diff --git a/workflow/engine/classes/LdapSource.php b/workflow/engine/classes/LdapSource.php index a83a03038..5cc787949 100644 --- a/workflow/engine/classes/LdapSource.php +++ b/workflow/engine/classes/LdapSource.php @@ -8,6 +8,7 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use ProcessMaker\Model\Department; use ProcessMaker\Model\Groupwf; +use ProcessMaker\Model\GroupUser; use ProcessMaker\BusinessModel\User as BusinessUser; use \RbacUsers as RbacUsersModel; use \Roles as RolesModel; @@ -1876,6 +1877,346 @@ class LdapSource } } + public function setArrayGroupUsers($groupUid) + { + try { + $this->arrayGroupUsersByUid = []; + $this->arrayGroupUsersByUsername = []; + + $groupUser = new GroupUser(); + $filters = [ + 'fields' => ['GROUP_USER.GRP_UID', 'GROUP_USER.USR_UID', 'USERS.USR_USERNAME', 'USERS.USR_REPORTS_TO'], + 'limit' => 10000, + 'orderBy' => ['USERS.USR_USERNAME', 'ASC'], + 'conditions' => [['GRP_UID', '=', $groupUid], ['USR_STATUS', '!=', 'CLOSED']] + ]; + $groupUserData = $groupUser->getUsersByGroupId($filters); + + foreach ($groupUserData['data'] ?? [] as $userData) { + $this->arrayGroupUsersByUid[$userData['USR_UID']] = $userData; + $this->arrayGroupUsersByUsername[$userData['USR_USERNAME']] = $userData; + } + } catch (Exception $e) { + throw $e; + } + } + + public function ldapGetUsersFromGroup($option, array $arrayGroupData, array $arrayData = []) + { + try { + $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromGroup() > START"); + $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromGroup() > \$arrayGroupData ---->\n" . print_r($arrayGroupData, true)); + + $totalUser = 0; + $countUser = 0; + + //Set variables + $dn = trim($arrayGroupData["GRP_LDAP_DN"]); + $rbac = RBAC::getSingleton(); + + if (is_null($rbac->authSourcesObj)) { + $rbac->authSourcesObj = new AuthenticationSource(); + } + + $filters = ['conditions' => ['AUTH_SOURCE_UID'=> $this->authSourceUid]]; + $rbacAuthenticationSource = new RbacAuthenticationSource(); + $authSourceReturn = $rbacAuthenticationSource->show($filters); + $authenticationSourceData = $authSourceReturn['data'][0]; + $authenticationSourceData['AUTH_SOURCE_DATA'] = json_decode($authenticationSourceData['AUTH_SOURCE_DATA'], true); + $authenticationSourceData['AUTH_SOURCE_PASSWORD'] = G::decrypt($authenticationSourceData['AUTH_SOURCE_PASSWORD'], URL_KEY); + + if (is_null($this->ldapcnn)) { + $ldapcnn = $this->ldapConnection($authenticationSourceData); + $this->ldapcnn = $ldapcnn['connection']; + } + $ldapcnn = $this->ldapcnn; + + //Get Group members + $memberAttribute = $this->arrayAttributes[$authenticationSourceData["AUTH_SOURCE_DATA"]["LDAP_TYPE"]]["member"]; + $filter = "(" . $this->arrayObjectClassFilter["group"] . ")"; + $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromGroup() > \$filter ----> $filter"); + $searchResult = @ldap_search($ldapcnn, $dn, $filter, array($memberAttribute)); + $context = [ + "baseDN" => $dn, + "filter" => $filter, + "attributes" => [$memberAttribute] + ]; + $this->stdLog($ldapcnn, "ldap_search", $context); + + if ($error = ldap_errno($ldapcnn)) { + $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromGroup() > ldap_search > ERROR > \$error ---->\n" . print_r($error, true)); + } else { + $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromGroup() > ldap_search > OK1"); + + if ($searchResult) { + $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromGroup() > ldap_search > OK2"); + $numEntries = ldap_count_entries($ldapcnn, $searchResult); + $this->stdLog($ldapcnn, "ldap_count_entries"); + $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromGroup() > ldap_search > OK2 > \$numEntries ----> $numEntries"); + + if ($numEntries > 0) { + $entry = ldap_first_entry($ldapcnn, $searchResult); + $this->stdLog($ldapcnn, "ldap_first_entry"); + $arrayGroupLdap = $this->ldapGetAttributes($ldapcnn, $entry); + // Syncronize members + $flagMemberRange = false; + $memberAttribute2 = $memberAttribute; + + if (isset($arrayGroupLdap[$memberAttribute]) && empty($arrayGroupLdap[$memberAttribute])) { + foreach ($arrayGroupLdap as $key => $value) { + if (preg_match('/^member;range=\d+\-\d+$/i', $key)) { + $memberAttribute2 = $key; + $flagMemberRange = true; + break; + } + } + } + + $arrayData = $this->ldapGroupSynchronizeMembers( + $ldapcnn, + $authenticationSourceData, + $arrayGroupData['GRP_UID'], + $arrayGroupLdap, + $memberAttribute2, + array_merge($arrayData, ['totalUser' => $totalUser, 'countUser' => $countUser]) + ); + + $totalUser = $arrayData['totalUser']; + $countUser = $arrayData['countUser']; + + $limitMemberRange = (isset($arrayData['countMembers'])) ? $arrayData['countMembers'] : 0; + + if ($flagMemberRange) { + for ($start = $limitMemberRange; true; $start += $limitMemberRange) { + $end = $start + $limitMemberRange - 1; + $memberAttribute2 = $memberAttribute . ';range=' . $start . '-' . $end; + $searchResult = @ldap_search($ldapcnn, $dn, $filter, [$memberAttribute2]); + $context = [ + "baseDN" => $dn, + "filter" => $filter, + "attributes" => [$memberAttribute2] + ]; + $this->stdLog($ldapcnn, "ldap_search", $context); + + if ($error = ldap_errno($ldapcnn)) { + break; + } else { + if ($searchResult) { + if (ldap_count_entries($ldapcnn, $searchResult) > 0) { + $this->stdLog($ldapcnn, "ldap_count_entries"); + $entry = ldap_first_entry($ldapcnn, $searchResult); + $this->stdLog($ldapcnn, "ldap_first_entry"); + $arrayGroupLdap = $this->ldapGetAttributes($ldapcnn, $entry); + + foreach ($arrayGroupLdap as $key => $value) { + if (preg_match('/^member;range=\d+\-\*$/i', $key)) { + $memberAttribute2 = $key; + break; + } + } + + $arrayData = $this->ldapGroupSynchronizeMembers( + $ldapcnn, + $authenticationSourceData, + $arrayGroupData['GRP_UID'], + $arrayGroupLdap, + $memberAttribute2, + array_merge($arrayData, ['totalUser' => $totalUser, 'countUser' => $countUser]) + ); + + $totalUser = $arrayData['totalUser']; + $countUser = $arrayData['countUser']; + } + } + } + } + } + } + } + } + + $this->log($ldapcnn, "Found $totalUser users in group $dn"); + $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromGroup() > END"); + + //Return + return $arrayData; + } catch (Exception $e) { + throw $e; + } + } + + private function ldapGroupSynchronizeMembers($ldapcnn, array $arrayAuthSourceData, $groupUid, array $arrayGroupLdap, $memberAttribute, array $arrayData = []) + { + try { + unset($arrayData['countMembers']); + + //Get members + if (!isset($arrayAuthSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_USERS_FILTER'])) { + $arrayAuthSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_USERS_FILTER'] = ''; + } + + $uidUserIdentifier = (isset($arrayAuthSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_IDENTIFIER_FOR_USER'])) ? + $arrayAuthSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_IDENTIFIER_FOR_USER'] : 'uid'; + + $filterUsers = trim($arrayAuthSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_USERS_FILTER']); + + $filter = ($filterUsers != '') ? $filterUsers : '(' . $this->arrayObjectClassFilter['user'] . ')'; + + if (isset($arrayGroupLdap[$memberAttribute])) { + if (!is_array($arrayGroupLdap[$memberAttribute])) { + $arrayGroupLdap[$memberAttribute] = [$arrayGroupLdap[$memberAttribute]]; + } + + $arrayData['countMembers'] = count($arrayGroupLdap[$memberAttribute]); + $arrayData['totalUser'] += $arrayData['countMembers']; + + //Synchronize members + foreach ($arrayGroupLdap[$memberAttribute] as $value) { + $member = $value; //User DN + + $searchResult = @ldap_search($ldapcnn, $member, $filter, $this->arrayAttributesForUser); + $context = [ + "baseDN" => $member, + "filter" => $filter, + "attributes" => $this->arrayAttributesForUser + ]; + $this->stdLog($ldapcnn, "ldap_search", $context); + + if ($error = ldap_errno($ldapcnn)) { + // + } else { + if ($searchResult) { + if (ldap_count_entries($ldapcnn, $searchResult) > 0) { + $this->stdLog($ldapcnn, "ldap_count_entries"); + $entry = ldap_first_entry($ldapcnn, $searchResult); + $this->stdLog($ldapcnn, "ldap_first_entry"); + $arrayUserLdap = $this->ldapGetAttributes($ldapcnn, $entry); + $username = (isset($arrayUserLdap[$uidUserIdentifier])) ? $arrayUserLdap[$uidUserIdentifier] : ''; + $arrayData['countUser']++; + + if ((is_array($username) && !empty($username)) || trim($username) != '') { + $dataUserLdap = $this->getUserDataFromAttribute($username, $arrayUserLdap); + $dataUserLdap["usrRole"] = ""; + if (!empty($arrayAuthSourceData['AUTH_SOURCE_DATA']['USR_ROLE'])) { + $dataUserLdap["usrRole"] = $arrayAuthSourceData['AUTH_SOURCE_DATA']['USR_ROLE']; + } + $arrayData = $this->groupSynchronizeUser( + $groupUid, + $dataUserLdap, + $arrayData + ); + } + + //Progress bar + $this->frontEndShow( + 'BAR', + 'Groups: ' . $arrayData['i'] . '/' . $arrayData['n'] . ' ' . + $this->progressBar($arrayData['totalUser'], $arrayData['countUser']) + ); + } + } + } + } + } + // Return + return $arrayData; + } catch (Exception $e) { + throw $e; + } + } + + public function groupSynchronizeUser($groupUid, array $arrayUserLdap, array $arrayData) + { + try { + $this->debugLog("class.ldapAdvanced.php > function groupSynchronizeUser() > START"); + $this->debugLog("class.ldapAdvanced.php > function groupSynchronizeUser() > \$arrayUserLdap[sUsername] ----> " . $arrayUserLdap["sUsername"]); + + $group = new Groups(); + + $userUid = ""; + $found = false; + + $arrayUserData = $this->groupGetUserDataIfUsernameExists($arrayUserLdap["sUsername"]); + + if (!empty($arrayUserData)) { + //User already exists in this group and there is nothing to do + //User already exists + $userUid = $arrayUserData["USR_UID"]; + $found = true; + + $arrayData["already"]++; + $arrayData["alreadyUsers"] .= $arrayUserData["USR_USERNAME"] . " "; + } + + if (!$found) { + //If user DO NOT exists in this group.. do: + //If exists with another AuthSource -> impossible + //If exists in another group, but in PM and for this authsource, we need to move it + //$arrayNewUserData = $this->searchUserByUid($arrayUserLdap["sUsername"]); + $arrayNewUserData = $arrayUserLdap; + + $arrayUserData = $this->authenticationSourceGetUserDataIfUsernameExists($arrayNewUserData["sUsername"]); + + if (!empty($arrayUserData)) { + //User exists in this Authentication Source + //Move User + $userUid = $arrayUserData["USR_UID"]; + + $this->activateUser($arrayUserData["USR_UID"], $arrayNewUserData["sDN"]); + + $group->addUserToGroup($groupUid, $userUid); + + $arrayData["moved"]++; + $arrayData["movedUsers"] .= $arrayUserData["USR_USERNAME"] . " "; + + $this->setArrayAuthenticationSourceUser($userUid, $arrayNewUserData); //INITIALIZE DATA //Update User + } else { + $arrayUserData = $this->getUserFromPM($arrayNewUserData["sUsername"]); + + if (!empty($arrayUserData)) { + //User exists in another Authentication Source and another Group + //Impossible + $userUid = $arrayUserData["USR_UID"]; + + $arrayData["impossible"]++; + $arrayData["impossibleUsers"] .= $arrayUserData["USR_USERNAME"] . " "; + } else { + //User not exists + //Create User + $userUid = $this->createUserAndActivate($arrayNewUserData, ""); + + $group->addUserToGroup($groupUid, $userUid); + + $arrayData["created"]++; + $arrayData["createdUsers"] .= $arrayNewUserData["sUsername"] . " "; + + $this->setArrayAuthenticationSourceUser($userUid, $arrayNewUserData); //INITIALIZE DATA //Add User + } + } + } + + if ($userUid != "") { + $arrayData["arrayUserUid"][] = $userUid; + + if (isset($arrayUserLdap["sManagerDN"]) && $arrayUserLdap["sManagerDN"] != "") { + if (!isset($arrayData["managersHierarchy"][$arrayUserLdap["sManagerDN"]])) { + $arrayData["managersHierarchy"][$arrayUserLdap["sManagerDN"]] = []; + } + + $arrayData["managersHierarchy"][$arrayUserLdap["sManagerDN"]][$userUid] = $userUid; + } + } + + $this->debugLog("class.ldapAdvanced.php > function groupSynchronizeUser() > \$userUid ----> $userUid"); + $this->debugLog("class.ldapAdvanced.php > function groupSynchronizeUser() > END"); + + //Return + return $arrayData; + } catch (Exception $e) { + throw $e; + } + } + public function authenticationSourceGetUserDataIfUsernameExists($username) { try { @@ -1986,6 +2327,18 @@ class LdapSource } } + public function groupGetUserDataIfUsernameExists($username) + { + try { + if (isset($this->arrayGroupUsersByUsername[$username])) { + return $this->arrayGroupUsersByUsername[$username]; + } + // Return + return []; + } catch (Exception $e) { + throw $e; + } + } public function setArrayAuthenticationSourceUsers($authSourceUid = '') { diff --git a/workflow/engine/methods/users/users_ViewPhotoGrid.php b/workflow/engine/methods/users/users_ViewPhotoGrid.php index 13e7459a5..0b8b9a6d6 100644 --- a/workflow/engine/methods/users/users_ViewPhotoGrid.php +++ b/workflow/engine/methods/users/users_ViewPhotoGrid.php @@ -1,26 +1,8 @@ . - * - * For more information, contact Colosa Inc, 2566 Le Jeune Rd., - * Coral Gables, FL, 33134, USA, or email info@colosa.com. - */ + +use ProcessMaker\Model\User; + + if (($RBAC_Response = $RBAC->userCanAccess( "PM_LOGIN" )) != 1) return $RBAC_Response; @@ -30,8 +12,23 @@ $direction = PATH_IMAGES_ENVIRONMENT_USERS . $_REQUEST['pUID'] . ".gif"; if (! file_exists( $direction )) { - $direction = PATH_HOME . 'public_html/images/user.gif'; + $user = new User(); + $filters = array( + 'limit' => 1, + 'fields' => ['USR_UID'], + 'conditions' => [['USR_ID', '=', $_REQUEST['pUID']]] + ); + $result = $user->show($filters); + if ($result['total'] == 1){ + $direction = PATH_IMAGES_ENVIRONMENT_USERS . $result['data'][0]['USR_UID'] . ".gif"; + if (! file_exists( $direction )) { + $direction = PATH_HOME . 'public_html/images/user.gif'; + } + } else { + $direction = PATH_HOME . 'public_html/images/user.gif'; + } } + G::sendHeaders( $direction ); DumpHeaders( $direction ); diff --git a/workflow/engine/src/ProcessMaker/Model/GroupUser.php b/workflow/engine/src/ProcessMaker/Model/GroupUser.php index 74d70d49f..6cf39825b 100644 --- a/workflow/engine/src/ProcessMaker/Model/GroupUser.php +++ b/workflow/engine/src/ProcessMaker/Model/GroupUser.php @@ -170,7 +170,7 @@ class GroupUser extends Model } } - public static function getUsersByGroupId($groupUid, $filters = []) + public static function getUsersByGroupId($filters = []) { $query = static::query(); @@ -178,8 +178,11 @@ class GroupUser extends Model $query->select($filters['fields']); } - $query->where('GROUP_USER.GRP_UID', $groupUid); - $query->innerJoin('GROUP_USER.USR_UID', '=', 'USERS.USR_UID'); + if (!empty($filters['conditions']) && is_array($filters['conditions'])) { + $query->where($filters['conditions']); + } + + $query->leftJoin('USERS', 'GROUP_USER.USR_UID', '=', 'USERS.USR_UID'); $total = $query->count();