From a7d8067341ee54ca3d594d0fd7aa8b11314ab53f Mon Sep 17 00:00:00 2001 From: Roly Rudy Gutierrez Pinto Date: Wed, 7 Oct 2020 22:59:04 -0400 Subject: [PATCH] PMCORE-1207 Generic message for wrong credentials and AD users --- .../engine/classes/LdapAdvancedTest.php | 45 +++++++++++++ workflow/engine/classes/LdapAdvanced.php | 63 ++++++++++++++++++- .../translations/english/processmaker.en.po | 48 ++++++++++++++ workflow/engine/data/mysql/insert.sql | 8 +++ .../engine/methods/login/authentication.php | 10 ++- 5 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 tests/unit/workflow/engine/classes/LdapAdvancedTest.php diff --git a/tests/unit/workflow/engine/classes/LdapAdvancedTest.php b/tests/unit/workflow/engine/classes/LdapAdvancedTest.php new file mode 100644 index 000000000..7919570de --- /dev/null +++ b/tests/unit/workflow/engine/classes/LdapAdvancedTest.php @@ -0,0 +1,45 @@ +ldapAdvanced = new LdapAdvanced(); + } + + /** + * This tests the getDiagnosticMessage method. + * Many paths cannot be covered because an active connection is required for + * Active Directory or LDAP. + * @test + * @covers LdapAdvanced::getDiagnosticMessage() + */ + public function it_should_test_getDiagnosticMessage_method() + { + $logDirectory = PATH_DATA . "log"; + if (!is_dir($logDirectory)) { + mkdir($logDirectory); + } + $linkIdentifier = ldap_connect('localhost'); + $this->ldapAdvanced->getDiagnosticMessage($linkIdentifier); + $message = Cache::get('ldapMessageError'); + $this->assertEquals('Success.', $message); + + @ldap_bind($linkIdentifier, 'uid=user1,ou=system', 'password'); + $this->ldapAdvanced->getDiagnosticMessage($linkIdentifier); + $message = Cache::get('ldapMessageError'); + $this->assertEquals("Can't contact LDAP server.", $message); + } +} diff --git a/workflow/engine/classes/LdapAdvanced.php b/workflow/engine/classes/LdapAdvanced.php index 18a73208e..7811ac3f8 100644 --- a/workflow/engine/classes/LdapAdvanced.php +++ b/workflow/engine/classes/LdapAdvanced.php @@ -1,5 +1,6 @@ log($ldapcnn, "bind $ldapServer with user " . $aAuthSource["AUTH_SOURCE_SEARCH_USER"]); } - + $this->getDiagnosticMessage($ldapcnn); if (!$bBind) { throw new Exception("Unable to bind to server: $ldapServer . " . "LDAP-Errno: " . ldap_errno($ldapcnn) . " : " . ldap_error($ldapcnn) . " \n"); } @@ -541,6 +542,64 @@ class LdapAdvanced return $ldapcnn; } + /** + * Get a diagnostic message of the ldap connection status. + * @param resource $linkIdentifier + */ + public function getDiagnosticMessage($linkIdentifier) + { + //specific message + $keysError = [ + [ + 'key' => 'USER_NOT_FOUND', + 'code' => 525, + 'message' => G::LoadTranslation('ID_LDAP_USER_NOT_FOUND_INVALID'), + ], [ + 'key' => 'NOT_PERMITTED_TO_LOGON_AT_THIS_TIME', + 'code' => 530, + 'message' => G::LoadTranslation('ID_LDAP_NOT_PERMITTED_TO_LOGON_AT_THIS_TIME'), + ], [ + 'key' => 'RESTRICTED_TO_SPECIFIC_MACHINES', + 'code' => 531, + 'message' => G::LoadTranslation('ID_LDAP_RESTRICTED_TO_SPECIFIC_MACHINES'), + ], [ + 'key' => 'PASSWORD_EXPIRED', + 'code' => 532, + 'message' => G::LoadTranslation('ID_LDAP_PASSWORD_EXPIRED'), + ], [ + 'key' => 'ACCOUNT_DISABLED', + 'code' => 533, + 'message' => G::LoadTranslation('ID_LDAP_ACCOUNT_DISABLED'), + ], [ + 'key' => 'ACCOUNT_EXPIRED', + 'code' => 701, + 'message' => G::LoadTranslation('ID_LDAP_ACCOUNT_EXPIRED'), + ], [ + 'key' => 'USER_MUST_RESET_PASSWORD', + 'code' => 773, + 'message' => G::LoadTranslation('ID_LDAP_USER_MUST_RESET_PASSWORD'), + ] + ]; + $message = ''; + ldap_get_option($linkIdentifier, LDAP_OPT_DIAGNOSTIC_MESSAGE, $messageError); + foreach ($keysError as $key => $value) { + if (strpos($messageError, (string) $value['code']) !== false) { + $message = $value['message']; + break; + } + } + //standard message + if (empty($message)) { + $errorNumber = ldap_errno($linkIdentifier); + $message = ldap_err2str($errorNumber) . "."; + } + if (empty($message)) { + $message = G::LoadTranslation('ID_LDAP_ERROR_CONNECTION'); + } + Cache::put('ldapMessageError', $message, 2); + $this->log($linkIdentifier, $messageError); + } + /** * This method obtains the attributes of a ldap Connection passed as parameter * @param Object $ldapcnn ldap connection @@ -1451,6 +1510,8 @@ class LdapAdvanced $searchResult = @ldap_search($ldapcnn, $arrayAuthenticationSourceData["AUTH_SOURCE_BASE_DN"], $filter, array_merge($this->arrayAttributesForUser, $attributeSetAdd)); if ($error = ldap_errno($ldapcnn)) { + $messageError = ldap_err2str($error); + Cache::put('ldapMessageError', $messageError, 2); // } else { if ($searchResult) { diff --git a/workflow/engine/content/translations/english/processmaker.en.po b/workflow/engine/content/translations/english/processmaker.en.po index 2f5b66cf1..a5d078f28 100755 --- a/workflow/engine/content/translations/english/processmaker.en.po +++ b/workflow/engine/content/translations/english/processmaker.en.po @@ -10661,24 +10661,72 @@ msgstr "Last Run Time" msgid "Latest version" msgstr "Latest version" +# TRANSLATION +# LABEL/ID_LDAP_ACCOUNT_DISABLED +#: LABEL/ID_LDAP_ACCOUNT_DISABLED +msgid "The account is currently disabled." +msgstr "The account is currently disabled." + +# TRANSLATION +# LABEL/ID_LDAP_ACCOUNT_EXPIRED +#: LABEL/ID_LDAP_ACCOUNT_EXPIRED +msgid "The user's account has expired." +msgstr "The user's account has expired." + +# TRANSLATION +# LABEL/ID_LDAP_ERROR_CONNECTION +#: LABEL/ID_LDAP_ERROR_CONNECTION +msgid "Error connection." +msgstr "Error connection." + # TRANSLATION # LABEL/ID_LDAP_FIELD #: LABEL/ID_LDAP_FIELD msgid "LDAP Field" msgstr "LDAP Field" +# TRANSLATION +# LABEL/ID_LDAP_NOT_PERMITTED_TO_LOGON_AT_THIS_TIME +#: LABEL/ID_LDAP_NOT_PERMITTED_TO_LOGON_AT_THIS_TIME +msgid "The user is not permitted to log on at this time." +msgstr "The user is not permitted to log on at this time." + # TRANSLATION # LABEL/ID_LDAP_OPTIONAL #: LABEL/ID_LDAP_OPTIONAL msgid "LDAP is optional." msgstr "LDAP is optional." +# TRANSLATION +# LABEL/ID_LDAP_PASSWORD_EXPIRED +#: LABEL/ID_LDAP_PASSWORD_EXPIRED +msgid "User's account has expired." +msgstr "User's account has expired." + +# TRANSLATION +# LABEL/ID_LDAP_RESTRICTED_TO_SPECIFIC_MACHINES +#: LABEL/ID_LDAP_RESTRICTED_TO_SPECIFIC_MACHINES +msgid "The user is not permitted to log on from this computer." +msgstr "The user is not permitted to log on from this computer." + # TRANSLATION # LABEL/ID_LDAP_USERS #: LABEL/ID_LDAP_USERS msgid "LDAP Users" msgstr "LDAP Users" +# TRANSLATION +# LABEL/ID_LDAP_USER_MUST_RESET_PASSWORD +#: LABEL/ID_LDAP_USER_MUST_RESET_PASSWORD +msgid "The user's password must be changed before logging on the first time." +msgstr "The user's password must be changed before logging on the first time." + +# TRANSLATION +# LABEL/ID_LDAP_USER_NOT_FOUND_INVALID +#: LABEL/ID_LDAP_USER_NOT_FOUND_INVALID +msgid "The username is invalid." +msgstr "The username is invalid." + # TRANSLATION # LABEL/ID_LECA #: LABEL/ID_LECA diff --git a/workflow/engine/data/mysql/insert.sql b/workflow/engine/data/mysql/insert.sql index 7871948a0..5fea6526a 100755 --- a/workflow/engine/data/mysql/insert.sql +++ b/workflow/engine/data/mysql/insert.sql @@ -58630,9 +58630,17 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE ) VALUES ( 'LABEL','ID_LATEST_VERSION','en','Latest version','2014-09-18') , +( 'LABEL','ID_LDAP_ACCOUNT_DISABLED','en','The account is currently disabled.','2020-10-02') , +( 'LABEL','ID_LDAP_ACCOUNT_EXPIRED','en','The user''s account has expired.','2020-10-02') , +( 'LABEL','ID_LDAP_ERROR_CONNECTION','en','Error connection.','2020-10-02') , ( 'LABEL','ID_LDAP_FIELD','en','LDAP Field','2015-09-15') , +( 'LABEL','ID_LDAP_NOT_PERMITTED_TO_LOGON_AT_THIS_TIME','en','The user is not permitted to log on at this time.','2020-10-02') , ( 'LABEL','ID_LDAP_OPTIONAL','en','LDAP is optional.','2014-01-15') , +( 'LABEL','ID_LDAP_PASSWORD_EXPIRED','en','User''s account has expired.','2020-10-02') , +( 'LABEL','ID_LDAP_RESTRICTED_TO_SPECIFIC_MACHINES','en','The user is not permitted to log on from this computer.','2020-10-02') , ( 'LABEL','ID_LDAP_USERS','en','LDAP Users','2015-09-15') , +( 'LABEL','ID_LDAP_USER_MUST_RESET_PASSWORD','en','The user''s password must be changed before logging on the first time.','2020-10-02') , +( 'LABEL','ID_LDAP_USER_NOT_FOUND_INVALID','en','The username is invalid.','2020-10-02') , ( 'LABEL','ID_LECA','en','Your license has expired. Please contact your administrator.','2016-07-28') , ( 'LABEL','ID_LEFT','en','left','2014-09-18') , ( 'LABEL','ID_LEFT_MARGIN','en','Left Margin','2014-01-15') , diff --git a/workflow/engine/methods/login/authentication.php b/workflow/engine/methods/login/authentication.php index bceee435f..1e74266b2 100644 --- a/workflow/engine/methods/login/authentication.php +++ b/workflow/engine/methods/login/authentication.php @@ -50,7 +50,9 @@ try { $enterprise->setup(); } /*----------------------------------********---------------------------------*/ - $uid = $RBAC->VerifyLogin($usr , $pwd); + Cache::put('ldapMessageError', '', 2); + $uid = $RBAC->VerifyLogin($usr, $pwd); + $ldapMessageError = Cache::pull('ldapMessageError'); $RBAC->cleanSessionFiles(72); //cleaning session files older than 72 hours switch ($uid) { @@ -148,7 +150,11 @@ try { $d = serialize(['u' => $usr, 'p' => $pwd, 'm' => G::LoadTranslation($errLabel)]); $urlLogin = $urlLogin . '?d=' . base64_encode($d); } else { - G::SendTemporalMessage($errLabel, "warning"); + if (empty($ldapMessageError)) { + G::SendTemporalMessage($errLabel, "warning"); + } else { + G::SendTemporalMessage($ldapMessageError, "warning", "string"); + } } $u = (array_key_exists('form', $_POST) && array_key_exists('URL', $_POST['form']))? 'u=' . urlencode(htmlspecialchars_decode($_POST['form']['URL'])) : '';