Page 1 of 1

Custom external authentication source via Plugin

Posted: Mon Nov 27, 2017 5:44 am
by mustapah
Can I add a custom authentication source(s) via a plugin?

I just checked out PM login procedure. As far as I understand:
1- VerifyWithOtherAuthenticationSource method within class.rbac.php has the responsible for authenticating with external source(s).
2- initRBAC method within class.rbac.php is the provider of available authentication source(s) to the above-mentioned method.

I'm not sure, but I think adding new class file inside the folder (/processmaker/rbac/engine/classes/plugins) could be a solution. However, it's, surely, not a clean one.

I need a brief instruction(s) about developing a plugin as an external authentication source, if it's even possible. amosbatto, I need your help :)

/processmaker/gulliver/system/class.rbac.php
Code: Select all
public function VerifyWithOtherAuthenticationSource ($sAuthType, $aUserFields, $strPass)
{
    if ($sAuthType == '' || $sAuthType == 'MYSQL') {
        //check if the user is active
        if ($aUserFields['USR_STATUS'] != 1) {
            return - 3; //inactive user
        }

        //check if the user's due date is valid
        if ($aUserFields['USR_DUE_DATE'] < date( 'Y-m-d' )) {
            return - 4; //due date
        }
    }

    foreach ($this->aRbacPlugins as $sClassName) {
        if (strtolower( $sClassName ) == strtolower( $sAuthType )) {
            $plugin = new $sClassName();
            $plugin->sAuthSource = $aUserFields["UID_AUTH_SOURCE"];
            $plugin->sSystem = $this->sSystem;

            $bValidUser = false;
            $bValidUser = $plugin->VerifyLogin( $aUserFields["USR_AUTH_USER_DN"], $strPass );
            if ($bValidUser === true) {
                return ($aUserFields['USR_UID']);
            } else {
                return - 2; //wrong password
            }
        }
    }
    return - 5; //invalid authentication source
}
/processmaker/gulliver/system/class.rbac.php
Code: Select all
public function initRBAC ()
{

    ...

    //hook for RBAC plugins
    $pathPlugins = PATH_RBAC . 'plugins';
    if (is_dir( $pathPlugins )) {
        if ($handle = opendir( $pathPlugins )) {
            while (false !== ($file = readdir( $handle ))) {
                if (strpos( $file, '.php', 1 ) && is_file( $pathPlugins . PATH_SEP . $file ) && substr( $file, 0, 6 ) == 'class.' && substr( $file, - 4 ) == '.php') {

                    $sClassName = substr( $file, 6, strlen( $file ) - 10 );
                    require_once ($pathPlugins . PATH_SEP . $file);
                    $this->aRbacPlugins[] = $sClassName;

                }
            }
        }
    }
    if (!in_array('ldapAdvanced', $this->aRbacPlugins)) {
        G::LoadClass('ldapAdvanced');
        if (class_exists('ldapAdvanced')) {
            $this->aRbacPlugins[] = 'ldapAdvanced';
        }
    }
}

Re: Custom external authentication source via Plugin

Posted: Mon Nov 27, 2017 8:33 pm
by amosbatto
I have never customized authentication, but you have found the right place to modify the source code. I have no idea how to customize authentication with a plugin. It is probably easier to change the source code.

Re: Custom external authentication source via Plugin

Posted: Fri Apr 19, 2019 12:09 am
by chieunh
1. Edit the authentication
- add class.custom_auth.php file to the /opt/processmaker/rbac/engine/classes/plugins directory
(refer to class.ldap.php file).
- edit file /opt/processmaker/gulliver/system/class.rbac.php -> VerifyWithOtherAuthenticationSource
Code: Select all
foreach ($this->aRbacPlugins as $sClassName) {
            if (strtoupper($sClassName) == strtoupper($sAuthType)){
                switch (strtoupper($sClassName)){
                    case 'CUSTOM_AUTH': 
                        $plugin = new $sClassName();
                        $plugin->sAuthSource = $aUserFields["UID_AUTH_SOURCE"];
                        $plugin->sSystem = $this->sSystem;
                        $bValidUser = false;
                        $result = $plugin->verifyLogin($aUserFields["USR_USERNAME"], $strPass );
                        
                        if ($result->status === true) {
                            return ($aUserFields['USR_UID']);
                        } else {
                            //neu ko nhan dc result
                            if(!is_object($result)){
                                return -500;
                            }
                            return -$result->code;
                        }
                        break;
                    default:
                        $plugin = new $sClassName();
                        $plugin->sAuthSource = $aUserFields["UID_AUTH_SOURCE"];
                        $plugin->sSystem = $this->sSystem;

                        $bValidUser = false;
                        $bValidUser = $plugin->VerifyLogin( $aUserFields["USR_AUTH_USER_DN"], $strPass );
                        if ($bValidUser === true) {
                            return ($aUserFields['USR_UID']);
                        } else {
                            return - 2; //wrong password
                        }
                }
            }
2. Edit the add Auth source section(in menu Admin -> User -> Authentication Sources -> New)
- edit file /opt/processmaker/workflow/engine/templates/authSources/authSourcesListNew.js -> function gotypesAuthSources:
Code: Select all
success: function(f,a){
                resp = Ext.util.JSON.decode(a.response.responseText);
                if (resp.success) {
                  //chieunh start comment
                  // if (resp.optionAuthS=='ldap') {
                  //     window.location = 'authSources_kindof?sprovider='+resp.optionAuthS;
                  // } else {
                  //     window.location = 'authSources_New?AUTH_SOURCE_PROVIDER='+resp.optionAuthS;
                  // }
                  //chieunh end comment

                  //chieunh start new code
                  switch(resp.optionAuthS.toUpperCase()){
                    case "LDAP":
                      window.location = 'authSources_kindof?sprovider='+resp.optionAuthS;
                      break;
                    case "CUSTOM_AUTH":
                      window.location = '../shbfCustom/authSources/custom_authSources_new?sprovider='+resp.optionAuthS;
                      break;
                    default:
                      window.location = 'authSources_New?AUTH_SOURCE_PROVIDER='+resp.optionAuthS;
                  }
                  //chieunh end new code
                }
            }

3. 2. Edit the add Auth source section(in menu Admin -> User -> Authentication Sources -> Edit)
- Edit file: /opt/processmaker/workflow/engine/methods/authSources/authSources_Edit.php

4. Write more custom/authSource sections
- custom/authSource/custom_authSources_new.php file to catch request and gene to html page
- add the file /opt/processmaker/workflow/engine/templates/custom/authSources/authSourceInformation.html as the html section showing the content.
- add file /opt/processmaker/workflow/public_html/assets/js/customAuthSource.js -> code js
- add custom/authSource/custom_authSources_save file -> handle insert / update auth source into DB.

This is a very difficult job, you need to understand the directory structure of the system.
good luck

Re: Custom external authentication source via Plugin

Posted: Mon Apr 22, 2019 9:49 pm
by amosbatto
Nice work chieunh!

If you have the time, please consider adding your plugin to the PMUsers wiki at: https://www.pmusers.com/index.php/Plugins
So that others can study your code