From 0b0a176058845189bb14bd49ebf8d46cb9402205 Mon Sep 17 00:00:00 2001 From: Brayan Pereyra Date: Tue, 7 Oct 2025 02:22:03 +0000 Subject: [PATCH] TASK-290 Add new new command for Auth Sources Cron --- processmaker | 11 +- workflow/engine/bin/tasks/cliAuthSources.php | 881 ++++++++++++++++++ workflow/engine/classes/CLI.php | 7 +- workflow/engine/classes/LdapSource.php | 724 +++++++++++++- .../src/ProcessMaker/Model/Department.php | 8 +- .../src/ProcessMaker/Model/GroupUser.php | 79 ++ .../engine/src/ProcessMaker/Model/Groupwf.php | 8 +- .../Model/RbacAuthenticationSource.php | 8 +- .../src/ProcessMaker/Model/RbacUsers.php | 19 +- .../engine/src/ProcessMaker/Model/User.php | 100 ++ 10 files changed, 1789 insertions(+), 56 deletions(-) create mode 100644 workflow/engine/bin/tasks/cliAuthSources.php diff --git a/processmaker b/processmaker index 8d5144b45..82afd9d45 100755 --- a/processmaker +++ b/processmaker @@ -9,10 +9,9 @@ require_once __DIR__ . '/bootstrap/app.php'; $scriptDir = dirname(__FILE__).'/'; - define("PROCESSMAKER_PATH", $scriptDir); - define("WORKFLOW_PATH", $scriptDir . 'workflow/'); - define("WORKFLOW_BIN_PATH", $scriptDir . 'workflow/engine/bin/'); - error_reporting(error_reporting() & ~E_DEPRECATED & ~E_STRICT); - - include WORKFLOW_BIN_PATH . '/cli.php'; +define("PROCESSMAKER_PATH", $scriptDir); +define("WORKFLOW_PATH", $scriptDir . 'workflow/'); +define("WORKFLOW_BIN_PATH", $scriptDir . 'workflow/engine/bin/'); +error_reporting(error_reporting() & ~E_DEPRECATED & ~E_STRICT); +include WORKFLOW_BIN_PATH . '/cli.php'; diff --git a/workflow/engine/bin/tasks/cliAuthSources.php b/workflow/engine/bin/tasks/cliAuthSources.php new file mode 100644 index 000000000..cd1f5e1e4 --- /dev/null +++ b/workflow/engine/bin/tasks/cliAuthSources.php @@ -0,0 +1,881 @@ += 1) { + $workspace = $command[0]; + CLI::logging("Check workspace $workspace ...\n", null, 'blue'); + + if (!is_dir(PATH_DB . $workspace) || !file_exists(PATH_DB . $workspace . PATH_SEP . 'db.php')) { + CLI::logging("Workspace not found ❌\n",null, 'red'); + CLI::logging("Syncronization canceled 🚫\n",null, 'red'); + return; + } + CLI::logging("Workspace \"$workspace\" found.......... ✅\n",null, 'green'); + initWorkspace($workspace); + + executeLdapCron(); + /* + $language = new Language(); + $language->createLanguagePlugin($command[0], $command[1]); + */ + CLI::logging("Syncronization completed 🎉🎉🎉\n", null, 'green'); + } else { + CLI::logging("The command requires the workspace name\n"); + } +} + +function executeLdapCron() +{ + $plugin = new LdapSource(); + $rbac = RBAC::getSingleton(); + + if (is_null($rbac->authSourcesObj)) { + $rbac->authSourcesObj = new AuthenticationSource(); + } + + unset($GLOBALS['translation']); + + $plugin->setFrontEnd(true); + $plugin->setDebug(true); + + //Get all authsource for this plugin ( ldapAdvanced plugin, because other authsources are not needed ) + //$arrayAuthenticationSource = $plugin->getAuthSources(); + + $filters = ['orderBy' => ['AUTH_SOURCE_NAME', 'ASC']]; + $rbacAuthenticationSource = new RbacAuthenticationSource(); + $arrayAuthenticationSource = $rbacAuthenticationSource->show($filters); + + $filters = array( + 'conditions' => ['DEP_STATUS' => 'ACTIVE'], + 'orderBy' => ['DEP_TITLE', 'ASC'] + ); + $department = new Department(); + $aDepartments = $department->show($filters); + + $filters = array( + 'conditions' => ['GRP_STATUS' => 'ACTIVE'], + 'orderBy' => ['GRP_TITLE', 'ASC'] + ); + $groupwf = new Groupwf(); + $aGroups = $groupwf->show($filters); + + + $plugin->frontEndShow('START'); + $plugin->debugLog('START'); + $plugin->stdLog(null, 'cron execution started'); + + foreach ($arrayAuthenticationSource['data'] ?? [] as $value) { + $arrayAuthenticationSourceData = $value; + try { + $plugin->debugLog("ldapadvanced.php > function executeCron() > foreach > \$arrayAuthenticationSourceData ---->\n" . print_r($arrayAuthenticationSourceData, true)); + $plugin->stdLog(null, 'AuthenticationSourceData', ['result' => $arrayAuthenticationSourceData]); + + $plugin->authSourceUid = $arrayAuthenticationSourceData['AUTH_SOURCE_UID']; + $plugin->ldapcnn = null; + + $plugin->setArrayDepartmentUserSynchronizedChecked([]); + $plugin->setArrayUserUpdateChecked([]); + + // Get all User (USR_UID, USR_USERNAME, USR_AUTH_USER_DN) registered in RBAC with this Authentication Source + $plugin->setArrayAuthenticationSourceUsers($arrayAuthenticationSourceData['AUTH_SOURCE_UID']); //INITIALIZE DATA + // Set some logs to show + $plugin->frontEndShow('TEXT', 'Authentication Source: ' . $arrayAuthenticationSourceData['AUTH_SOURCE_NAME']); + $plugin->log(null, 'Executing cron for Authentication Source: ' . $arrayAuthenticationSourceData['AUTH_SOURCE_NAME']); + $plugin->stdLog(null, 'authentication source', ['AUTH_SOURCE_NAME' => $arrayAuthenticationSourceData['AUTH_SOURCE_NAME']]); + + // Get all departments from Ldap/ActiveDirectory and build a hierarchy using dn (ou->ou parent) + $aLdapDepts = $plugin->searchDepartments(); + + // Obtain all departments from PM with a valid department in LDAP/ActiveDirectory + $aRegisteredDepts = $plugin->getRegisteredDepartments($aLdapDepts, $aDepartments['data'] ?? []); + + // Set some logs to show + $plugin->debugLog("ldapadvanced.php > function executeCron() > foreach > \$aRegisteredDepts ---->\n" . print_r($aRegisteredDepts, true)); + $plugin->stdLog(null, 'RegisteredDepartments', ['result' => $aRegisteredDepts]); + // Get all group from Ldap/ActiveDirectory + $aLdapGroups = $plugin->searchGroups(); + // Obtain all groups from PM with a valid group in LDAP/ActiveDirectory + $aRegisteredGroups = $plugin->getRegisteredGroups($aLdapGroups, $aGroups['data'] ?? []); + // Set some logs to show + $plugin->debugLog("ldapadvanced.php > function executeCron() > foreach > \$aRegisteredGroups ---->\n" . print_r($aRegisteredGroups, true)); + $plugin->stdLog(null, 'RegisteredGroups', ['result' => $aRegisteredGroups]); + + // Get all users from Removed OU + $GLOBALS['usersRemovedOu'] = $plugin->getUsersFromRemovedOu($arrayAuthenticationSourceData); + $GLOBALS['deletedRemoved'] = count($GLOBALS['usersRemovedOu']); + + //Department - Synchronize Users + $numDepartments = count($aRegisteredDepts); + $count = 0; + + $plugin->debugLog("ldapadvanced.php > function executeCron() > foreach > \$numDepartments ----> $numDepartments"); + $plugin->stdLog(null, 'NumberDepartments', ['result' => $numDepartments]); + + foreach ($aRegisteredDepts as $registeredDept) { + $count++; + departmentSynchronizeUsers($plugin, $numDepartments, $count, $registeredDept); + } + + //Department - Print log + $logResults = sprintf( + "- Departments -> Existing users: %d, moved: %d, impossible: %d, created: %d, removed: %d", + $GLOBALS['dAlready'], + $GLOBALS['dMoved'], + $GLOBALS['dImpossible'], + $GLOBALS['dCreated'], + $GLOBALS['dRemoved'] + ); + + $plugin->frontEndShow('TEXT', $logResults); + $plugin->log(null, $logResults); + $context = [ + 'existingUsers' => $GLOBALS['dAlready'], + 'moved' => $GLOBALS['dMoved'], + 'impossible' => $GLOBALS['dImpossible'], + 'created' => $GLOBALS['dCreated'], + 'removed' => $GLOBALS['dRemoved'] + ]; + $plugin->stdLog(null, 'departments', $context); + // Group - Synchronize Users + $numGroups = count($aRegisteredGroups); + $count = 0; + + $plugin->debugLog("ldapadvanced.php > function executeCron() > foreach > \$numGroups ----> $numGroups"); + $plugin->stdLog(null, 'NumberGroups', ['result' => $numGroups]); + + foreach ($aRegisteredGroups as $registeredGroup) { + $count++; + $arrayAux = groupSynchronizeUsers($plugin, $numGroups, $count, $registeredGroup); + } + + // Group - Print log + $logResults = sprintf( + "- Groups -> Existing users: %d, moved: %d, impossible: %d, created: %d, removed: %d", + $GLOBALS['gAlready'], + $GLOBALS['gMoved'], + $GLOBALS['gImpossible'], + $GLOBALS['gCreated'], + $GLOBALS['gRemoved'] + ); + + $plugin->frontEndShow('TEXT', $logResults); + + $plugin->log(null, $logResults); + $context = [ + 'existingUsers' => $GLOBALS['gAlready'], + 'moved' => $GLOBALS['gMoved'], + 'impossible' => $GLOBALS['gImpossible'], + 'created' => $GLOBALS['gCreated'], + 'removed' => $GLOBALS['gRemoved'] + ]; + $plugin->stdLog(null, 'groups', $context); + + // Manager + $plugin->clearManager($GLOBALS['managersToClear']); + + + if (isset($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['DEPARTMENTS_TO_UNASSIGN'])) { + if (is_array($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['DEPARTMENTS_TO_UNASSIGN'])) { + foreach ($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['DEPARTMENTS_TO_UNASSIGN'] as $departmentUID) { + // Delete manager assignments + $user = new User(); + $GLOBALS['deletedManager'] = $user->updateData( + ['USR_REPORTS_TO' => ''], + ['DEP_UID' => $departmentUID, ['USR_REPORTS_TO', '!=', '']] + ); + + $rbacUsers = new RbacUsers(); + $totalRbacUsers = $rbacUsers->show(['conditions' => ['DEP_UID' => $departmentUID]]); + $GLOBALS['dMoved'] += (int)$totalRbacUsers['total']; + $rbacUsers->updateData( + ['DEP_UID' => ''], + ['DEP_UID' => $departmentUID] + ); + } + } + + unset($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['DEPARTMENTS_TO_UNASSIGN']); + + $rbac = RBAC::getSingleton(); + $rbac->authSourcesObj->update($arrayAuthenticationSourceData); + } + + if (isset($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['GROUPS_TO_UNASSIGN'])) { + if (is_array($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['GROUPS_TO_UNASSIGN'])) { + foreach ($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['GROUPS_TO_UNASSIGN'] as $groupUID) { + $groupUser = new GroupUser(); + $dataGroupUser = $groupUser->show([ + 'fields' => ['USR_UID'], + 'limit' => 1000, + 'conditions' => ['GRP_UID' => $groupUID] + ]); + + $users = []; + foreach ($dataGroupUser['data'] ?? [] as $user) { + $users[] = $user['USR_UID']; + } + + $user = new User(); + $GLOBALS['deletedManager'] = $user->updateDataFromListUsersUids( + ['USR_REPORTS_TO' => ''], + $users, + [['USR_REPORTS_TO', '!=', '']] + ); + + $GLOBALS['gMoved'] += $dataGroupUser['total']; + + // Delete group assignments + $groupUser = new GroupUser(); + $groupUser->removeGroupUser(['GRP_UID' => $groupUID]); + } + } + + unset($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['GROUPS_TO_UNASSIGN']); + + $rbac = RBAC::getSingleton(); + $rbac->authSourcesObj->update($arrayAuthenticationSourceData); + } + + + $rbacUsers = new RbacUsers(); + $rbacUsersData = $rbacUsers->show([ + 'fields' => ['USR_AUTH_USER_DN'], + 'conditions' => [['USR_AUTH_USER_DN', '!=', '']] + ]); + + $existingUsers = []; + foreach ($rbacUsersData['data'] ?? [] as $usersData) { + $existingUsers[] = $usersData['USR_AUTH_USER_DN']; + } + + foreach ($GLOBALS['managersHierarchy'] as $managerDN => $subordinates) { + if (!in_array($managerDN, $existingUsers)) { + unset($GLOBALS['managersHierarchy'][$managerDN]); + } + } + + // Get the managers assigments counters + $plugin->synchronizeManagers($GLOBALS['managersHierarchy']); + + $deletedManagersAssignments = array_diff_assoc_recursive($GLOBALS['oldManagersHierarchy'], $GLOBALS['managersHierarchy']); + $newManagersAssignments = array_diff_assoc_recursive($GLOBALS['managersHierarchy'], $GLOBALS['oldManagersHierarchy']); + $deletedManagers = []; + $newManagers = []; + $movedManagers = []; + + if (is_array($deletedManagersAssignments)) { + foreach ($deletedManagersAssignments as $dn1 => $subordinates1) { + foreach ($subordinates1 as $subordinate) { + if (!in_array($subordinate, $deletedManagers)) { + $deletedManagers[] = $subordinate; + } + + foreach ($newManagersAssignments as $dn2 => $subordinates2) { + if (isset($subordinates2[$subordinate])) { + $movedManagers[] = $subordinate; + } + } + } + } + } + + if (is_array($newManagersAssignments)) { + foreach ($newManagersAssignments as $dn1 => $subordinates1) { + foreach ($subordinates1 as $subordinate) { + if (!in_array($subordinate, $newManagers)) { + $newManagers[] = $subordinate; + } + + foreach ($deletedManagersAssignments as $dn2 => $subordinates2) { + if (isset($subordinates2[$subordinate])) { + if (!in_array($subordinate, $movedManagers)) { + $movedManagers[] = $subordinate; + } + } + } + } + } + } + //Print and log the users's information + //Retired/Deactivated Users + $logResults = sprintf("- Retired/Deactivated Users: %d", $GLOBALS['deletedRemoved']); + + $plugin->frontEndShow('TEXT', $logResults); + + $plugin->log(null, $logResults); + $context = [ + 'deletedRemoved' => $GLOBALS['deletedRemoved'] + ]; + $plugin->stdLog(null, 'retired/deactivated users', $context); + + if ($GLOBALS['deletedRemoved'] > 0) { + $plugin->log(null, 'Retired/Deactivated Users: '); + $plugin->log(null, $GLOBALS['deletedRemovedUsers']); + $context = [ + 'deletedRemovedUsers' => $GLOBALS['deletedRemovedUsers'] + ]; + $plugin->stdLog(null, 'retired/deactivated users', $context); + } + + if ($GLOBALS['dAlready'] + $GLOBALS['gAlready'] > 0) { + $plugin->log(null, 'Existing Users: '); + $plugin->log(null, $GLOBALS['dAlreadyUsers'] . ' ' . $GLOBALS['gAlreadyUsers']); + $context = [ + 'dAlreadyUsers' => $GLOBALS['dAlreadyUsers'], + 'gAlreadyUsers' => $GLOBALS['gAlreadyUsers'] + ]; + $plugin->stdLog(null, 'existing users', $context); + } + + if ($GLOBALS['dMoved'] + $GLOBALS['gMoved'] > 0) { + $plugin->log(null, 'Moved Users: '); + $plugin->log(null, $GLOBALS['dMovedUsers'] . ' ' . $GLOBALS['gMovedUsers']); + $context = [ + 'dMovedUsers' => $GLOBALS['dMovedUsers'], + 'gMovedUsers' => $GLOBALS['gMovedUsers'] + ]; + $plugin->stdLog(null, 'moved users', $context); + } + + if ($GLOBALS['dImpossible'] + $GLOBALS['gImpossible'] > 0) { + $plugin->log(null, 'Impossible Users: '); + $plugin->log(null, $GLOBALS['dImpossibleUsers'] . ' ' . $GLOBALS['gImpossibleUsers']); + $context = [ + 'dImpossibleUsers' => $GLOBALS['dImpossibleUsers'], + 'gImpossibleUsers' => $GLOBALS['gImpossibleUsers'] + ]; + $plugin->stdLog(null, 'impossible users', $context); + } + + if ($GLOBALS['dCreated'] + $GLOBALS['gCreated'] > 0) { + $plugin->log(null, 'Created Users: '); + $plugin->log(null, $GLOBALS['dCreatedUsers'] . ' ' . $GLOBALS['gCreatedUsers']); + $context = [ + 'dCreatedUsers' => $GLOBALS['dCreatedUsers'], + 'gCreatedUsers' => $GLOBALS['gCreatedUsers'] + ]; + $plugin->stdLog(null, 'created users', $context); + } + + if ($GLOBALS['dRemoved'] + $GLOBALS['gRemoved'] > 0) { + $plugin->log(null, 'Removed Users: '); + $plugin->log(null, $GLOBALS['dRemovedUsers'] . ' ' . $GLOBALS['gRemovedUsers']); + $context = [ + 'dRemovedUsers' => $GLOBALS['dRemovedUsers'], + 'gRemovedUsers' => $GLOBALS['gRemovedUsers'] + ]; + $plugin->stdLog(null, 'removed users', $context); + } + + //Print and log the managers assignments's information + $logResults = sprintf( + "- Managers assignments: created %d, moved %d, removed %d", + count($newManagers) - count($movedManagers), + count($movedManagers), + count($deletedManagers) - count($movedManagers) + $GLOBALS['deletedManager'] + ); + + $plugin->frontEndShow('TEXT', $logResults); + + $plugin->log(null, $logResults); + $context = [ + 'created' => count($newManagers) - count($movedManagers), + 'moved' => count($movedManagers), + 'removed' => count($deletedManagers) - count($movedManagers) + $GLOBALS['deletedManager'] + ]; + $plugin->stdLog(null, 'managers assignments', $context); + + // Update Users data based on the LDAP Server + $plugin->stdLog(null, 'usersUpdateData', [$arrayAuthenticationSourceData['AUTH_SOURCE_UID']]); + $result = $plugin->usersUpdateData($arrayAuthenticationSourceData['AUTH_SOURCE_UID']); + $logResults = sprintf("- Deleted/Removed Users: %d", $result['countUserDeleted']); + $plugin->frontEndShow('TEXT', $logResults); + $plugin->log(null, $logResults); + // Deactive Users + $plugin->stdLog(null, 'deactiveArrayOfUsers', [$GLOBALS['usersRemovedOu']]); + $plugin->deactiveArrayOfUsers($GLOBALS['usersRemovedOu']); + } catch (Exception $e) { + $plugin = new LdapSource(); + $message = $e->getMessage(); + $context = [ + 'action' => 'ldapSynchronize', + 'authSource' => $arrayAuthenticationSourceData + ]; + $plugin->stdLog(null, $message, $context, 'error'); + Log::channel(':ldapSynchronize')->error($message, Bootstrap::context($context)); + } + } + + $plugin->frontEndShow('END'); + $plugin->debugLog('END'); + $plugin->stdLog(null, 'cron execution finalized'); +} + + + +function departmentSynchronizeUsers($ldapAdvanced, $numDepartments, $count, array $arrayDepartmentData) +{ + $plugin = new LdapSource(); + try { + $ldapAdvanced->debugLog("ldapadvanced.php > function departmentSynchronizeUsers() > START"); + $ldapAdvanced->debugLog("ldapadvanced.php > function departmentSynchronizeUsers() > \$arrayDepartmentData ---->\n" . print_r($arrayDepartmentData, true)); + $plugin->stdLog(null, 'department synchronize users started', ['result' => $arrayDepartmentData]); + + //Get users from ProcessMaker tables (for this Department) + $ldapAdvanced->setArrayDepartmentUsers($arrayDepartmentData['DEP_UID']); //INITIALIZE DATA + + //Clear the manager assignments + $arrayUserUid = []; + + foreach ($ldapAdvanced->arrayDepartmentUsersByUid as $user) { + $arrayUserUid[] = $user['USR_UID']; + + if (isset($user['USR_REPORTS_TO']) && $user['USR_REPORTS_TO'] != '') { + $dn = (isset($ldapAdvanced->arrayAuthenticationSourceUsersByUid[$user['USR_REPORTS_TO']]['USR_AUTH_USER_DN']))? $ldapAdvanced->arrayAuthenticationSourceUsersByUid[$user['USR_REPORTS_TO']]['USR_AUTH_USER_DN'] : ''; + + if ($dn != '') { + if (!isset($GLOBALS['oldManagersHierarchy'][$dn])) { + $GLOBALS['oldManagersHierarchy'][$dn] = []; + } + $GLOBALS['oldManagersHierarchy'][$dn][$user['USR_UID']] = $user['USR_UID']; + } + } + } + + $GLOBALS['managersToClear'] = $arrayUserUid; + + //Synchronize Users from Department + //Now we need to go over ldapusers and check if the user exists in ldap but not in PM, then we need to create it + $arrayData = array( + 'already' => $GLOBALS['dAlready'], + 'moved' => $GLOBALS['dMoved'], + 'impossible' => $GLOBALS['dImpossible'], + 'created' => $GLOBALS['dCreated'], + 'alreadyUsers' => $GLOBALS['dAlreadyUsers'], + 'movedUsers' => $GLOBALS['dMovedUsers'], + 'impossibleUsers' => $GLOBALS['dImpossibleUsers'], + 'createdUsers' => $GLOBALS['dCreatedUsers'], + + 'managersHierarchy' => $GLOBALS['managersHierarchy'], + 'arrayUserUid' => [], + + 'n' => $numDepartments, + 'i' => $count + ); + + //Get Users from LDAP (for this Department) + $arrayData = $ldapAdvanced->ldapGetUsersFromDepartment('SYNCHRONIZE', $arrayDepartmentData['DEP_LDAP_DN'], $arrayData); + + $GLOBALS['dAlready'] = $arrayData['already']; + $GLOBALS['dMoved'] = $arrayData['moved']; + $GLOBALS['dImpossible'] = $arrayData['impossible']; + $GLOBALS['dCreated'] = $arrayData['created']; + $GLOBALS['dAlreadyUsers'] = $arrayData['alreadyUsers']; + $GLOBALS['dMovedUsers'] = $arrayData['movedUsers']; + $GLOBALS['dImpossibleUsers'] = $arrayData['impossibleUsers']; + $GLOBALS['dCreatedUsers'] = $arrayData['createdUsers']; + + $GLOBALS['managersHierarchy'] = $arrayData['managersHierarchy']; + $arrayUserUid = $arrayData['arrayUserUid']; + + //(D) Update Users + $arrayAux = array_diff(array_keys($ldapAdvanced->arrayDepartmentUsersByUid), $arrayUserUid); + + departmentRemoveUsers($arrayDepartmentData['DEP_UID'], $arrayAux); + + $GLOBALS['dRemoved'] += count($arrayAux); + $GLOBALS['dRemovedUsers'] = ''; + + $ldapAdvanced->debugLog("ldapadvanced.php > function departmentSynchronizeUsers() > END"); + $plugin->stdLog(null, 'department synchronize users finalized'); + + //Return all UID of Users synchronized in the Department (Return all UID of Users of this Department) + return $arrayUserUid; + } catch (Exception $e) { + $plugin = new LdapSource(); + $message = $e->getMessage(); + $context = [ + 'trace' => $e->getTrace() + ]; + $plugin->stdLog(null, $message, $context, 'error'); + throw $e; + } +} + + + +function groupSynchronizeUsers($ldapAdvanced, $numGroups, $count, array $arrayGroupData) +{ + $plugin = new LdapSource(); + try { + $ldapAdvanced->debugLog("ldapadvanced.php > function groupSynchronizeUsers() > START"); + $ldapAdvanced->debugLog("ldapadvanced.php > function groupSynchronizeUsers() > \$arrayGroupData ---->\n" . print_r($arrayGroupData, true)); + $plugin->stdLog(null, 'group synchronize users started', ['result' => $arrayGroupData]); + + //Get users from ProcessMaker tables (for this Group) + $ldapAdvanced->setArrayGroupUsers($arrayGroupData['GRP_UID']); //INITIALIZE DATA + + //Clear the manager assignments + $arrayUserUid = []; + + foreach ($ldapAdvanced->arrayGroupUsersByUid as $key => $user) { + $arrayUserUid[] = $user['USR_UID']; + + if (isset($user['USR_REPORTS_TO']) && $user['USR_REPORTS_TO'] != '') { + $dn = (isset($ldapAdvanced->arrayAuthenticationSourceUsersByUid[$user['USR_REPORTS_TO']]['USR_AUTH_USER_DN']))? $ldapAdvanced->arrayAuthenticationSourceUsersByUid[$user['USR_REPORTS_TO']]['USR_AUTH_USER_DN'] : ''; + + if ($dn != '') { + if (!isset($GLOBALS['oldManagersHierarchy'][$dn])) { + $GLOBALS['oldManagersHierarchy'][$dn] = []; + } + + $GLOBALS['oldManagersHierarchy'][$dn][$user['USR_UID']] = $user['USR_UID']; + } + } + } + + $GLOBALS['managersToClear'] = array_merge($GLOBALS['managersToClear'], $arrayUserUid); + + //Synchronize Users from Group + //Now we need to go over ldapusers and check if the user exists in ldap but not in PM, then we need to create it + $arrayData = array( + 'already' => $GLOBALS['gAlready'], + 'moved' => $GLOBALS['gMoved'], + 'impossible' => $GLOBALS['gImpossible'], + 'created' => $GLOBALS['gCreated'], + 'alreadyUsers' => $GLOBALS['gAlreadyUsers'], + 'movedUsers' => $GLOBALS['gMovedUsers'], + 'impossibleUsers' => $GLOBALS['gImpossibleUsers'], + 'createdUsers' => $GLOBALS['gCreatedUsers'], + + 'managersHierarchy' => $GLOBALS['managersHierarchy'], + 'arrayUserUid' => [], + + 'n' => $numGroups, + 'i' => $count + ); + + //Get Users from LDAP (for this Group) + $arrayData = $ldapAdvanced->ldapGetUsersFromGroup('SYNCHRONIZE', $arrayGroupData, $arrayData); + + $GLOBALS['gAlready'] = $arrayData['already']; + $GLOBALS['gMoved'] = $arrayData['moved']; + $GLOBALS['gImpossible'] = $arrayData['impossible']; + $GLOBALS['gCreated'] = $arrayData['created']; + $GLOBALS['gAlreadyUsers'] = $arrayData['alreadyUsers']; + $GLOBALS['gMovedUsers'] = $arrayData['movedUsers']; + $GLOBALS['gImpossibleUsers'] = $arrayData['impossibleUsers']; + $GLOBALS['gCreatedUsers'] = $arrayData['createdUsers']; + + $GLOBALS['managersHierarchy'] = $arrayData['managersHierarchy']; + $arrayUserUid = $arrayData['arrayUserUid']; + + //(G) Update Users + $arrayAux = array_diff(array_keys($ldapAdvanced->arrayGroupUsersByUid), $arrayUserUid); + + groupRemoveUsers($arrayGroupData['GRP_UID'], $arrayAux); + + $GLOBALS['gRemoved'] += count($arrayAux); + $GLOBALS['gRemovedUsers'] = ''; + + $ldapAdvanced->debugLog("ldapadvanced.php > function groupSynchronizeUsers() > END"); + $plugin->stdLog(null, 'group synchronize users finalized'); + + //Return all UID of Users synchronized in the Group (Return all UID of Users of this Group) + return $arrayUserUid; + } catch (Exception $e) { + $plugin = new LdapSource(); + $message = $e->getMessage(); + $context = [ + 'trace' => $e->getTrace() + ]; + $plugin->stdLog(null, $message, $context, 'error'); + throw $e; + } +} + +function departmentRemoveUsers($departmentUid, array $arrayUserUid) +{ + try { + $department = new DepartmentModel(); + $department->Load($departmentUid); + + $departmentManagerUid = $department->getDepManager(); + + foreach ($arrayUserUid as $value) { + $userUid = $value; + + $department->removeUserFromDepartment($departmentUid, $userUid); + + if ($userUid == $departmentManagerUid) { + $department->update(array('DEP_UID' => $departmentUid, 'DEP_MANAGER' => '')); + + $department->updateDepartmentManager($departmentUid); + } + } + } catch (Exception $e) { + $plugin = new LdapSource(); + $message = $e->getMessage(); + $context = [ + 'trace' => $e->getTrace() + ]; + $plugin->stdLog(null, $message, $context, 'error'); + throw $e; + } +} + +function groupRemoveUsers($groupUid, array $arrayUserUid) +{ + try { + $group = new Groups(); + + foreach ($arrayUserUid as $value) { + $userUid = $value; + + $group->removeUserOfGroup($groupUid, $userUid); + } + } catch (Exception $e) { + $plugin = new LdapSource(); + $message = $e->getMessage(); + $context = [ + 'trace' => $e->getTrace() + ]; + $plugin->stdLog(null, $message, $context, 'error'); + throw $e; + } +} + + + +function array_diff_assoc_recursive($array1, $array2) +{ + foreach ($array1 as $key => $value) { + if (is_array($value)) { + if (!isset($array2[$key])) { + $difference[$key] = $value; + } else { + if (!is_array($array2[$key])) { + $difference[$key] = $value; + } else { + $new_diff = array_diff_assoc_recursive($value, $array2[$key]); + + if ($new_diff != false) { + $difference[$key] = $new_diff; + } + } + } + } else { + if (!isset($array2[$key]) || $array2[$key] != $value) { + $difference[$key] = $value; + } + } + } + + return (!isset($difference))? [] : $difference; +} + + +function initWorkspace($workspace) { + define('SYS_SYS', $workspace); + config(["system.workspace" => $workspace]); + define('URL_KEY', config('app.key')); + //PM Paths DATA + define('PATH_DATA_SITE', PATH_DATA . 'sites/' . config("system.workspace") . '/'); + define('PATH_DOCUMENT', PATH_DATA_SITE . 'files/'); + define('PATH_DATA_MAILTEMPLATES', PATH_DATA_SITE . 'mailTemplates/'); + define('PATH_DATA_PUBLIC', PATH_DATA_SITE . 'public/'); + define('PATH_DATA_REPORTS', PATH_DATA_SITE . 'reports/'); + define('PATH_DYNAFORM', PATH_DATA_SITE . 'xmlForms/'); + define('PATH_IMAGES_ENVIRONMENT_FILES', PATH_DATA_SITE . 'usersFiles' . PATH_SEP); + define('PATH_IMAGES_ENVIRONMENT_USERS', PATH_DATA_SITE . 'usersPhotographies' . PATH_SEP); + + if (is_file(PATH_DATA_SITE . PATH_SEP . '.server_info')) { + $SERVER_INFO = file_get_contents(PATH_DATA_SITE . PATH_SEP . '.server_info'); + $SERVER_INFO = unserialize($SERVER_INFO); + + define('SERVER_NAME', $SERVER_INFO['SERVER_NAME']); + define('SERVER_PORT', $SERVER_INFO['SERVER_PORT']); + //to do improvement G::is_https() + if ((isset($SERVER_INFO['HTTPS']) && $SERVER_INFO['HTTPS'] == 'on') || + (isset($SERVER_INFO['HTTP_X_FORWARDED_PROTO']) && $SERVER_INFO['HTTP_X_FORWARDED_PROTO'] == 'https')) { + define('REQUEST_SCHEME', 'https'); + } else { + define('REQUEST_SCHEME', $SERVER_INFO['REQUEST_SCHEME']); + } + } else { + CLI::logging('WARNING! No server info found!', 'red'); + } + //load Processmaker translations + Bootstrap::LoadTranslationObject(SYS_LANG); + + + //DB + $phpCode = ''; + + $fileDb = fopen(PATH_DB . $workspace . PATH_SEP . 'db.php', 'r'); + + if ($fileDb) { + while (!feof($fileDb)) { + $buffer = fgets($fileDb, 4096); //Read a line + + $phpCode .= preg_replace('/define\s*\(\s*[\x22\x27](.*)[\x22\x27]\s*,\s*(\x22.*\x22|\x27.*\x27)\s*\)\s*;/i', '$$1 = $2;', $buffer); + } + + fclose($fileDb); + } + + $phpCode = str_replace([''], ['', '', ''], $phpCode); + + eval($phpCode); + + $dsn = $DB_ADAPTER . '://' . $DB_USER . ':' . $DB_PASS . '@' . $DB_HOST . '/' . $DB_NAME; + $dsnRbac = $DB_ADAPTER . '://' . $DB_RBAC_USER . ':' . $DB_RBAC_PASS . '@' . $DB_RBAC_HOST . '/' . $DB_RBAC_NAME; + $dsnRp = $DB_ADAPTER . '://' . $DB_REPORT_USER . ':' . $DB_REPORT_PASS . '@' . $DB_REPORT_HOST . '/' . $DB_REPORT_NAME; + + switch ($DB_ADAPTER) { + case 'mysql': + $dsn .= '?encoding=utf8'; + $dsnRbac .= '?encoding=utf8'; + break; + case 'mssql': + break; + default: + break; + } + + $pro = []; + $pro['datasources']['workflow']['connection'] = $dsn; + $pro['datasources']['workflow']['adapter'] = $DB_ADAPTER; + $pro['datasources']['rbac']['connection'] = $dsnRbac; + $pro['datasources']['rbac']['adapter'] = $DB_ADAPTER; + $pro['datasources']['rp']['connection'] = $dsnRp; + $pro['datasources']['rp']['adapter'] = $DB_ADAPTER; + + Propel::initConfiguration($pro); + + /** + * Load Laravel database connection + */ + $dbHost = explode(':', $DB_HOST); + config(['database.connections.workflow.host' => $dbHost[0]]); + config(['database.connections.workflow.database' => $DB_NAME]); + config(['database.connections.workflow.username' => $DB_USER]); + config(['database.connections.workflow.password' => $DB_PASS]); + if (count($dbHost) > 1) { + config(['database.connections.workflow.port' => $dbHost[1]]); + } + + //Enable RBAC, We need to keep both variables in upper and lower case. + $rbac = $RBAC = RBAC::getSingleton(PATH_DATA, session_id()); + $rbac->sSystem = 'PROCESSMAKER'; + + if (!defined('DB_ADAPTER')) { + define('DB_ADAPTER', $DB_ADAPTER); + } + if (!defined('DB_HOST')) { + define('DB_HOST', $DB_HOST); + } + if (!defined('DB_NAME')) { + define('DB_NAME', $DB_NAME); + } + if (!defined('DB_USER')) { + define('DB_USER', $DB_USER); + } + if (!defined('DB_PASS')) { + define('DB_PASS', $DB_PASS); + } + if (!defined('DB_RBAC_HOST')) { + define('DB_RBAC_HOST', $DB_RBAC_HOST); + } + if (!defined('DB_RBAC_NAME')) { + define('DB_RBAC_NAME', $DB_RBAC_NAME); + } + if (!defined('DB_RBAC_USER')) { + define('DB_RBAC_USER', $DB_RBAC_USER); + } + if (!defined('DB_RBAC_PASS')) { + define('DB_RBAC_PASS', $DB_RBAC_PASS); + } + if (!defined('DB_REPORT_HOST')) { + define('DB_REPORT_HOST', $DB_REPORT_HOST); + } + if (!defined('DB_REPORT_NAME')) { + define('DB_REPORT_NAME', $DB_REPORT_NAME); + } + if (!defined('DB_REPORT_USER')) { + define('DB_REPORT_USER', $DB_REPORT_USER); + } + if (!defined('DB_REPORT_PASS')) { + define('DB_REPORT_PASS', $DB_REPORT_PASS); + } + if (!defined('SYS_SKIN')) { + define('SYS_SKIN', $arraySystemConfiguration['default_skin']); + } + + $dateSystem = date('Y-m-d H:i:s'); + if (empty($now)) { + $now = $dateSystem; + } + + //Processing + CLI::logging('Processing workspace: ' . $workspace, null, 'green'); + + /** + * JobsManager + */ + JobsManager::getSingleton()->init(); +} diff --git a/workflow/engine/classes/CLI.php b/workflow/engine/classes/CLI.php index 9963ce5fc..8140b1335 100644 --- a/workflow/engine/classes/CLI.php +++ b/workflow/engine/classes/CLI.php @@ -103,6 +103,7 @@ class CLI public static function help ($args, $opts = null) { global $argv; + $scriptName = $argv[0]; if (is_array($args) && count($args) > 0 ) { $taskName = $args[0]; @@ -202,10 +203,12 @@ EOT; CLI::taskName( "help" ); CLI::taskRun( array ('self','help' ) ); + global $argv; $args = $argv; $cliname = array_shift( $args ); $taskName = array_shift( $args ); + if (isset($taskName[0])) { while ($taskName[0] == '-') { $taskName = array_shift( $args ); @@ -345,7 +348,7 @@ EOT; * @param string $message the message to display * @param string $filename the log file to write messages */ - public static function logging ($message, $filename = null) + public static function logging($message, $filename = null, $color = null) { static $log_file = null; if (isset( $filename )) { @@ -355,7 +358,7 @@ EOT; if (isset( $log_file )) { fwrite( $log_file, $message ); } - echo $message; + eprintln($message, $color); } } } diff --git a/workflow/engine/classes/LdapSource.php b/workflow/engine/classes/LdapSource.php index d666bdee7..a83a03038 100644 --- a/workflow/engine/classes/LdapSource.php +++ b/workflow/engine/classes/LdapSource.php @@ -2,19 +2,34 @@ use ProcessMaker\Model\RbacAuthenticationSource; use ProcessMaker\Model\RbacUsers; +use ProcessMaker\Model\User; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; -use ProcessMaker\BusinessModel\User; use ProcessMaker\Model\Department; use ProcessMaker\Model\Groupwf; +use ProcessMaker\BusinessModel\User as BusinessUser; +use \RbacUsers as RbacUsersModel; +use \Roles as RolesModel; +use \UsersRoles as UsersRolesModel; class LdapSource { public $authSourceUid; + public $sTerminatedOu = ''; public $ldapcnn = null; + public $debug = false; + private $frontEnd = false; public $terminatedOu; + public $allListOfUsers = []; private $arrayDepartmentUserSynchronizedChecked = []; + public $arrayAuthenticationSourceUsersByUid = []; + public $arrayAuthenticationSourceUsersByUsername = []; + public $arrayDepartmentUsersByUid = []; + public $arrayDepartmentUsersByUsername = []; + public $arrayGroupUsersByUid = []; + public $arrayGroupUsersByUsername = []; + private $arrayUserUpdateChecked = []; private $arrayObjectClassFilter = [ "user" => "|(objectclass=inetorgperson)(objectclass=organizationalperson)(objectclass=person)(objectclass=user)", @@ -42,7 +57,6 @@ class LdapSource $ldapcnn = ldap_connect($authSourceData['AUTH_SOURCE_SERVER_NAME'], $authSourceData['AUTH_SOURCE_PORT']); $this->stdLog($ldapcnn, 'ldap_connect', $loggableAuthSource); - $ldapServer = $authSourceData['AUTH_SOURCE_SERVER_NAME'] . ':' . $authSourceData['AUTH_SOURCE_PORT']; ldap_set_option($ldapcnn, LDAP_OPT_PROTOCOL_VERSION, 3); @@ -65,7 +79,9 @@ class LdapSource $bBind = ldap_bind($ldapcnn, $authSourceData['AUTH_SOURCE_SEARCH_USER'], $authSourceData['AUTH_SOURCE_PASSWORD']); $this->log($ldapcnn, 'bind ' . $ldapServer . ' with user ' . $loggableAuthSource['AUTH_SOURCE_SEARCH_USER']); } + $this->stdLog($ldapcnn, 'ldap_bind', $loggableAuthSource); + $this->getDiagnosticMessage($ldapcnn); if (!$bBind) { $message = 'Unable to bind to server: ' . $ldapServer . 'LDAP-Errno: ' . ldap_errno($ldapcnn) . ' : ' . ldap_error($ldapcnn) . " \n"; @@ -182,6 +198,7 @@ class LdapSource $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); @@ -189,6 +206,7 @@ class LdapSource $ldapcnn = $this->ldapConnection($authenticationSourceData); $this->ldapcnn = $ldapcnn['connection']; } + $this->terminatedOu = $attributes['AUTH_SOURCE_RETIRED_OU'] ?? ''; $ldapcnn = $this->ldapcnn; @@ -380,7 +398,7 @@ class LdapSource $this->log($linkIdentifier, $messageError); } - private function log($link, $text) + public function log($link, $text) { $logFile = PATH_DATA . 'logs/ldap.log'; @@ -412,7 +430,7 @@ class LdapSource fclose($fpt); } - private function stdLog($link, $message = "", $context = [], $level = "info") + public function stdLog($link, $message = "", $context = [], $level = "info") { try { if (empty($link)) { @@ -482,7 +500,6 @@ class LdapSource $filter = ($filterUsers != '') ? $filterUsers : '(' . $this->arrayObjectClassFilter['user'] . ')'; $filtersDefault = "(|(dn=$keyword)(uid=$keyword)(samaccountname=$keyword)(givenname=$keyword)(sn=$keyword)(cn=$keyword)(mail=$keyword)(userprincipalname=$keyword))"; $filter = '(&' . $filter . $filtersDefault . ')'; - $oSearch = @ldap_search($ldapcnn, $arrayAuthenticationSourceData['AUTH_SOURCE_BASE_DN'], $filter, array_merge($this->arrayAttributesForUser, $attributeSetAdd)); $context = [ 'baseDN' => $arrayAuthenticationSourceData['AUTH_SOURCE_BASE_DN'], @@ -921,12 +938,11 @@ class LdapSource return -1; } - /* if ($verifiedUser["sDN"] != $strUser || $setAttributes == 1) { $userDn = $verifiedUser['sDN']; // Update data - $user = new User(); + $user = new BusinessUser(); $arrayUserData = $user->getUserRecordByPk($usrUid, [], false); $result = $this->ldapUserUpdateByDnAndData( @@ -936,19 +952,12 @@ class LdapSource [$arrayUserData['USR_USERNAME'] => $arrayUserData] ); - //Update DN - $con = Propel::getConnection(RbacUsersPeer::DATABASE_NAME); - // select set - $c1 = new Criteria("rbac"); - $c1->add(RbacUsersPeer::UID_AUTH_SOURCE, $authenticationSourceData["AUTH_SOURCE_UID"]); - $c1->add(RbacUsersPeer::USR_AUTH_USER_DN, $strUser); - // update set - $c2 = new Criteria("rbac"); - $c2->add(RbacUsersPeer::USR_AUTH_USER_DN, $userDn); - - BasePeer::doUpdate($c1, $c2, $con); + $rbacUsers = new RbacUsers(); + $rbacUsers->updateData( + ['USR_AUTH_USER_DN' => $userDn], + ['UID_AUTH_SOURCE' => $authenticationSourceData["AUTH_SOURCE_UID"], 'USR_AUTH_USER_DN' => $strUser] + ); } - */ //Check ldap connection for user $authenticationSourceData["AUTH_ANONYMOUS"] = "0"; @@ -1147,26 +1156,30 @@ class LdapSource //Set variables $dn = trim($dn); - $rbac = RBAC::getSingleton(); - if (is_null($rbac->authSourcesObj)) { - $rbac->authSourcesObj = new AuthenticationSource(); + $rbacAuthenticationSource = new RbacAuthenticationSource(); + $filters = ['conditions' => ['AUTH_SOURCE_UID'=> $this->authSourceUid]]; + $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']; } - - $arrayAuthenticationSourceData = $rbac->authSourcesObj->load($this->sAuthSource); - $this->ldapcnn = $this->ldapConnection($arrayAuthenticationSourceData); $ldapcnn = $this->ldapcnn; //Get Users - $limit = $this->getPageSizeLimitByData($arrayAuthenticationSourceData); + $limit = $this->getPageSizeLimitByData($authenticationSourceData); $flagError = false; - if (!isset($arrayAuthenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_USERS_FILTER"])) { - $arrayAuthenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_USERS_FILTER"] = ""; + if (!isset($authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_USERS_FILTER"])) { + $authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_USERS_FILTER"] = ""; } - $uidUserIdentifier = (isset($arrayAuthenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_IDENTIFIER_FOR_USER"])) ? $arrayAuthenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_IDENTIFIER_FOR_USER"] : "uid"; - $filterUsers = trim($arrayAuthenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_USERS_FILTER"]); + $uidUserIdentifier = (isset($authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_IDENTIFIER_FOR_USER"])) ? $authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_IDENTIFIER_FOR_USER"] : "uid"; + $filterUsers = trim($authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_USERS_FILTER"]); $filter = ($filterUsers != "") ? $filterUsers : "(" . $this->arrayObjectClassFilter["user"] . ")"; $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartment() > \$filter ----> $filter"); $cookie = ''; @@ -1219,7 +1232,8 @@ class LdapSource foreach ($this->characters() as $value) { $char = $value; - $ldapcnn = $this->ldapConnection($arrayAuthenticationSourceData); + $ldapcnn = $this->ldapConnection($authenticationSourceData); + $ldapcnn = $ldapcnn['connection']; $filter = ($filterUsers != "") ? $filterUsers : "(" . $this->arrayObjectClassFilter["user"] . ")"; $filter = "(&$filter($uidUserIdentifier=$char*))"; $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartment() > \$filter ----> $filter"); @@ -1337,7 +1351,7 @@ class LdapSource if ($option == "SYNCHRONIZE") { // Progress bar - //$this->frontEndShow("BAR", "Departments: " . $arrayData["i"] . "/" . $arrayData["n"] . " " . $this->progressBar($totalUser, $countUser)); + $this->frontEndShow("BAR", "Departments: " . $arrayData["i"] . "/" . $arrayData["n"] . " " . $this->progressBar($totalUser, $countUser)); } } while ($entry = ldap_next_entry($ldapcnn, $entry)); } @@ -1351,6 +1365,307 @@ class LdapSource } } + public function usersUpdateData($authenticationSourceUid) + { + try { + $totalUser = count($this->arrayAuthenticationSourceUsersByUid); + $countUserUpdate = 0; + $countUserDelete = 0; + + // Set variables + $rbac = RBAC::getSingleton(); + if (is_null($rbac->authSourcesObj)) { + $rbac->authSourcesObj = new AuthenticationSource(); + } + + + $filters = ['conditions' => ['AUTH_SOURCE_UID'=> $authenticationSourceUid]]; + $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); + + $ldapcnn = $this->ldapConnection($authenticationSourceData); + $this->ldapcnn = $ldapcnn['connection']; + $ldapcnn = $this->ldapcnn; + + // Update Users + $limit = $this->getPageSizeLimitByData($authenticationSourceData); + $count = 0; + + $uidUserIdentifier = (isset($authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_IDENTIFIER_FOR_USER"])) ? $authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_IDENTIFIER_FOR_USER"] : "uid"; + + $filterUsers = ""; + $arrayUserUid = []; + foreach ($this->arrayAuthenticationSourceUsersByUid as $arrayUserData) { + $count++; + $filterUsers .= "($uidUserIdentifier=" . $arrayUserData["USR_USERNAME"] . ")"; + $arrayUserUid[] = $arrayUserData["USR_UID"]; + + if ($count == $limit) { + list($totalUser, $countUserUpdate, $countUserDelete) = $this->ldapUsersUpdateData( + $ldapcnn, + $authenticationSourceData, + $filterUsers, + $arrayUserUid, + ['totalUser' => $totalUser, 'countUserUpdated' => $countUserUpdate, 'countUserDeleted' => $countUserDelete] + ); + + $count = 0; + $filterUsers = ""; + $arrayUserUid = []; + } + } + + if ($count > 0) { + list($totalUser, $countUserUpdate, $countUserDelete) = $this->ldapUsersUpdateData( + $ldapcnn, + $authenticationSourceData, + $filterUsers, + $arrayUserUid, + ['totalUser' => $totalUser, 'countUserUpdated' => $countUserUpdate, 'countUserDeleted' => $countUserDelete] + ); + } + + return ['totalUser' => $totalUser, 'countUserUpdated' => $countUserUpdate, 'countUserDeleted' => $countUserDelete]; + } catch (Exception $e) { + throw $e; + } + } + + private function ldapUsersUpdateData($ldapcnn, array $arrayAuthSourceData, $filterUsers, array $listUids, array $countResult) + { + try { + $totalUser = $countResult['totalUser']; + $countUserUpdated = $countResult['countUserUpdated']; + $countUserDeleted = $countResult['countUserDeleted']; + + // Define the filter to search all users + $filter = '(&(' . $this->arrayObjectClassFilter['user'] . ')(|' . $filterUsers . '))'; + // Search all the users + $searchResult = @ldap_search($ldapcnn, $arrayAuthSourceData['AUTH_SOURCE_BASE_DN'], $filter, $this->arrayAttributesForUser); + $context = [ + "baseDN" => $arrayAuthSourceData['AUTH_SOURCE_BASE_DN'], + "filter" => $filter, + "attributes" => $this->arrayAttributesForUser + ]; + $this->stdLog($ldapcnn, "ldap_search", $context); + + if ($error = ldap_errno($ldapcnn)) { + // + } elseif ($searchResult && ldap_count_entries($ldapcnn, $searchResult) > 0) { // Check if at least one user was found + $this->stdLog($ldapcnn, "ldap_count_entries"); + // Get Users from DB + $arrayUser = []; + + $user = new User(); + $filters = [ + 'limit' => 10000, + 'conditions' => [['USR_STATUS', '!=', 'CLOSED']]]; + $userQueryData = $user->getByListUids($listUids, $filters); + foreach ($userQueryData['data'] ?? [] as $userData) { + $arrayUser[$userData['USR_USERNAME']] = $userData; + } + + // Get Users from LDAP Server + $entry = ldap_first_entry($ldapcnn, $searchResult); + $this->stdLog($ldapcnn, "ldap_first_entry"); + // Save all the list of users + $this->allListOfUsers = $arrayUser; + // Check all the ldap entry found + do { + if ($this->ldapUserUpdateByDnAndData($ldapcnn, $arrayAuthSourceData, ldap_get_dn($ldapcnn, $entry), $arrayUser)) { + $countUserUpdated++; + // Progress bar + $this->frontEndShow( + 'BAR', + 'Update Users data: ' . $countUserUpdated . '/' . $totalUser . ' ' . $this->progressBar($totalUser, $countUserUpdated) + ); + } + } while ($entry = ldap_next_entry($ldapcnn, $entry)); + $countUserDeleted = count($this->allListOfUsers); + // List of users to delete + foreach ($this->allListOfUsers as $index => $usr) { + $user = new BusinessUser(); + $user->deleteGdpr($usr['USR_UID']); + } + // Register the users deleted + $this->stdLog($ldapcnn, "deleteUsersGdpr", $this->allListOfUsers); + } else { // If no user found, we supposed that all are deleted + foreach ($listUids as $usr) { + $user = new BusinessUser(); + $user->deleteGdpr($usr); + } + // Register the users deleted + $this->stdLog($ldapcnn, "deleteAllUsersGdpr", $listUids); + } + + return [$totalUser, $countUserUpdated, $countUserDeleted]; + } catch (Exception $e) { + throw $e; + } + } + + private function ldapUserUpdateByDnAndData($ldapcnn, array $arrayAuthSourceData, $userDn, array $arrayUser) + { + try { + // Set variables + $rbac = RBAC::getSingleton(); + if (is_null($rbac->userObj)) { + $rbac->userObj = new RbacUsers(); + } + // Set variables + $flagUser = false; + $arrayAttributesToSync = [ + //Default attributes to sync + 'USR_FIRSTNAME' => 'givenname', + 'USR_LASTNAME' => 'sn', + 'USR_EMAIL' => 'mail', + 'USR_STATUS' => 'useraccountcontrol' + ]; + + if (!empty($arrayAuthSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE'])) { + foreach ($arrayAuthSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE'] as $value) { + $arrayAttributesToSync[$value['attributeUser']] = $value['attributeLdap']; + } + } + + // Search User from LDAP Server + $uidUserIdentifier = (isset($arrayAuthSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_IDENTIFIER_FOR_USER'])) ? + $arrayAuthSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_IDENTIFIER_FOR_USER'] : 'uid'; + + $arrayAttribute = array_merge($this->arrayAttributesForUser, array_values($arrayAttributesToSync)); + $searchResult = @ldap_search($ldapcnn, $userDn, '(objectclass=*)', $arrayAttribute); + $context = [ + "baseDN" => $userDn, + "filter" => "(objectclass=*)", + "attributes" => $arrayAttribute + ]; + $this->stdLog($ldapcnn, "ldap_search", $context); + + if ($error = ldap_errno($ldapcnn)) { + // + } elseif ($searchResult && ldap_count_entries($ldapcnn, $searchResult) > 0) { + $this->stdLog($ldapcnn, "ldap_count_entries"); + $entry = ldap_first_entry($ldapcnn, $searchResult); + $this->stdLog($ldapcnn, "ldap_first_entry", $context); + $arrayUserLdap = $this->ldapGetAttributes($ldapcnn, $entry); + $username = (isset($arrayUserLdap[$uidUserIdentifier])) ? $arrayUserLdap[$uidUserIdentifier] : ''; + + if ((is_array($username) && !empty($username)) || trim($username) != '') { + $username = trim((is_array($username)) ? $username[0] : $username); + + if (isset($arrayUser[$username])) { + if (!isset($this->arrayUserUpdateChecked[$username])) { + $this->arrayUserUpdateChecked[$username] = 1; + $arrayUserDataUpdate = []; + $extendedData = []; + + foreach ($arrayAttributesToSync as $key => $value) { + $fieldName = $key; + $attributeName = strtolower($value); + + if (isset($arrayUserLdap[$attributeName])) { + $ldapAttributeValue = trim((is_array($arrayUserLdap[$attributeName])) ? $arrayUserLdap[$attributeName][0] : $arrayUserLdap[$attributeName]); + + switch ($fieldName) { + case 'USR_STATUS': + if ($attributeName == 'useraccountcontrol') { + $ldapAttributeValue = (preg_match('/^(?:' . '512|544|66048|66080' . ')$/', $ldapAttributeValue)) ? (($arrayUser[$username][$fieldName] == 'VACATION') ? 'VACATION' : 'ACTIVE') : 'INACTIVE'; + } + break; + case 'USR_DUE_DATE': + if ($attributeName == 'accountexpires') { + $ldapAttributeValue = $this->convertDateADtoPM($ldapAttributeValue); + } + break; + } + + if (isset($arrayUser[$username][$fieldName])) { + if ($ldapAttributeValue != $arrayUser[$username][$fieldName]) { + $arrayUserDataUpdate[$fieldName] = $ldapAttributeValue; + } + } else { + $extendedData[$fieldName] = $ldapAttributeValue; + } + } + } + + // Update the extended data + if (!empty($extendedData)) { + $json = $arrayUser[$username]['USR_EXTENDED_ATTRIBUTES_DATA']; + $oldExtendedData = empty($json) ? [] : json_decode($json, true); + $extendedData = array_merge($oldExtendedData, $extendedData); + $arrayUserDataUpdate['USR_EXTENDED_ATTRIBUTES_DATA'] = json_encode($extendedData); + } + // Update the user information + if (!empty($arrayUserDataUpdate)) { + $arrayUserDataUpdate['USR_UID'] = $arrayUser[$username]['USR_UID']; + // Update User data + $rbac->updateUser($arrayUserDataUpdate); + $user = new Users(); + $result = $user->update($arrayUserDataUpdate); + } + // Remove the user from the array + unset($this->allListOfUsers[$username]); + } else { + $this->log( + $ldapcnn, + 'User is repeated: Username "' . $username . '", DN "' . $arrayUserLdap['dn'] . '"' + ); + } + + $flagUser = true; + } + } + } + + // Return + return $flagUser; + } catch (Exception $e) { + throw $e; + } + } + + public function setArrayDepartmentUsers($departmentUid) + { + try { + $this->arrayDepartmentUsersByUid = []; + $this->arrayDepartmentUsersByUsername = []; + // Set data + $user = new User(); + $filters = [ + 'fields' => ['USR_UID', 'USR_USERNAME', 'USR_REPORTS_TO'], + 'limit' => 10000, + 'conditions' => [['USR_STATUS', '!=', 'CLOSED'], ['DEP_UID', '=', $departmentUid]] + ]; + $usersDepartment = $user->show($filters); + foreach ($usersDepartment['data'] ?? [] as $userData) { + $this->arrayDepartmentUsersByUid[$userData['USR_UID']] = $userData; + $this->arrayDepartmentUsersByUsername[$userData['USR_USERNAME']] = $userData; + } + } catch (Exception $e) { + throw $e; + } + } + + public function deactiveArrayOfUsers($aUsers) + { + $aUsrUid = []; + foreach ($aUsers as $key => $val) { + $aUsrUid[] = $val['sUsername']; + } + + $rbacUsers = new RbacUsers(); + $rbacUsers->updateDataFromListUsersUids(['USR_STATUS' => '0'], $aUsrUid); + + $user = new User(); + $user->updateDataFromListUsersUids(['USR_STATUS' => 'INACTIVE', 'DEP_UID' => ''], $aUsrUid); + + return true; + } + public function departmentSynchronizeUser($departmentUid, array $arrayUserLdap, array $arrayData) { try { @@ -1444,6 +1759,165 @@ class LdapSource } } + public function createUserAndActivate($user, $depUid) + { + $rbac = RBAC::getSingleton(); + + if ($rbac->userObj == null) { + $rbac->userObj = new RbacUsersModel(); + } + + if ($rbac->rolesObj == null) { + $rbac->rolesObj = new RolesModel(); + } + + if ($rbac->usersRolesObj == null) { + $rbac->usersRolesObj = new UsersRolesModel(); + } + + $sUsername = $user['sUsername']; + $sFullname = $user['sFullname']; + $sFirstname = $user['sFirstname']; + $sLastname = $user['sLastname']; + $sEmail = $user['sEmail']; + $sDn = $user['sDN']; + $usrRole = empty($user['usrRole']) ? 'LURANA_OPERATOR' : $user['usrRole']; + + $data = []; + $data['USR_USERNAME'] = $sUsername; + $data["USR_PASSWORD"] = "00000000000000000000000000000000"; + $data['USR_FIRSTNAME'] = $sFirstname; + $data['USR_LASTNAME'] = $sLastname; + $data['USR_EMAIL'] = $sEmail; + $data['USR_DUE_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 2)); + $data['USR_CREATE_DATE'] = date('Y-m-d H:i:s'); + $data['USR_UPDATE_DATE'] = date('Y-m-d H:i:s'); + $data['USR_BIRTHDAY'] = date('Y-m-d'); + $data['USR_STATUS'] = 1; + $data['USR_AUTH_TYPE'] = 'ldapadvanced'; + $data['UID_AUTH_SOURCE'] = $this->authSourceUid; + $data['USR_AUTH_USER_DN'] = $sDn; + + $userUid = $rbac->createUser($data, $usrRole); + + $data['USR_STATUS'] = 'ACTIVE'; + $data['USR_UID'] = $userUid; + $data['DEP_UID'] = $depUid; + $data['USR_ROLE'] = $usrRole; + + $users = new Users(); + $users->create($data); + + return $userUid; + } + + public function getDepUidIfExistsDN($currentDN) + { + try { + $department = new Department(); + $filters = [ + 'fields' => ['DEP_UID', 'DEP_LDAP_DN'], + 'conditions' => [['DEP_STATUS', '=', 'ACTIVE'], ['DEP_LDAP_DN', '=', $currentDN]], + 'limit' => 1 + ]; + $departmentsData = $department->show($filters); + if (!empty($departmentsData['data']) && isset($departmentsData['data'][0]['DEP_UID'])) { + return $departmentsData['data'][0]['DEP_UID']; + } + return ''; + } catch (Exception $e) { + return false; + } + } + + public function activateUser($userUid, $userDn = null, $depUid = null) + { + $rbacUsers = new RbacUsers(); + $setData = [ + 'USR_STATUS' => '1' + ]; + if ($userDn != null) { + $setData['USR_AUTH_USER_DN'] = $userDn; + $setData['USR_AUTH_SUPERVISOR_DN'] = ''; + } + $rbacUsers->updateData( + $setData, + ['USR_UID' => $userUid] + ); + + $user = new User(); + $setData = [ + 'USR_STATUS' => 'ACTIVE' + ]; + if ($depUid != null) { + $setData['DEP_UID'] = $depUid; + } + $user->updateData( + $setData, + ['USR_UID' => $userUid] + ); + } + + public function getUserFromPM($username) + { + try { + $user = new User(); + $dataUser = $user->show([ + 'fields' => ['USR_UID', 'USR_USERNAME', 'DEP_UID'], + 'conditions' => [['USR_USERNAME', '=', $username], ['USR_STATUS', '!=', 'CLOSED']], + 'limit' => 1 + ]); + if (!empty($dataUser) && isset($dataUser['data'][0])) { + return $dataUser['data'][0]; + } + return []; + } catch (Exception $e) { + throw $e; + } + } + + public function authenticationSourceGetUserDataIfUsernameExists($username) + { + try { + if (isset($this->arrayAuthenticationSourceUsersByUsername[$username])) { + return $this->arrayAuthenticationSourceUsersByUsername[$username]; + } + // Return + return []; + } catch (Exception $e) { + throw $e; + } + } + + public function departmentGetUserDataIfUsernameExists($username) + { + try { + if (isset($this->arrayDepartmentUsersByUsername[$username])) { + return $this->arrayDepartmentUsersByUsername[$username]; + } + // Return + return []; + } catch (Exception $e) { + throw $e; + } + } + + public function setArrayAuthenticationSourceUser($userUid, array $arrayUserLdap) + { + try { + $arrayUserData = [ + "USR_UID" => $userUid, + "USR_USERNAME" => $arrayUserLdap["sUsername"], + "USR_AUTH_USER_DN" => $arrayUserLdap["sDN"] + ]; + // Set data + $this->arrayAuthenticationSourceUsersByUid[$arrayUserData["USR_UID"]] = $arrayUserData; + $this->arrayAuthenticationSourceUsersByUsername[$arrayUserData["USR_USERNAME"]] = $arrayUserData; + } catch (Exception $e) { + throw $e; + } + } + public function debugLog($text) { try { @@ -1468,4 +1942,190 @@ class LdapSource } return $datePM; } + + public function setDebug($debug) + { + try { + $this->debug = $debug; + } catch (Exception $e) { + throw $e; + } + } + + public function setFrontEnd($flag) + { + try { + $this->frontEnd = $flag; + } catch (Exception $e) { + throw $e; + } + } + + public function frontEndShow($option, $data = "") + { + try { + if (!$this->frontEnd) { + return; + } + + $numc = 100; + + switch ($option) { + case "BAR": + echo "\r" . "| " . $data . str_repeat(" ", $numc - 2 - strlen($data)); + break; + case "TEXT": + echo "\r" . "| " . $data . str_repeat(" ", $numc - 2 - strlen($data)) . "\n"; + break; + default: //START, END + echo "\r" . "+" . str_repeat("-", $numc - 2) . "+" . "\n"; + break; + } + } catch (Exception $e) { + throw $e; + } + } + + + public function setArrayAuthenticationSourceUsers($authSourceUid = '') + { + try { + if (empty($authSourceUid)) { + $authSourceUid = $this->authSourceUid; + } + + $this->arrayAuthenticationSourceUsersByUid = []; + $this->arrayAuthenticationSourceUsersByUsername = []; + + $filters = [ + 'select' => ['USR_USERNAME', 'USR_UID', 'USR_AUTH_USER_DN'], + 'fields' => ['USR_USERNAME', 'USR_UID'], + 'conditions' => [ + 'UID_AUTH_SOURCE' => $authSourceUid, + 'USR_AUTH_TYPE' => 'ldapadvanced', + 'USR_STATUS' => 1 + ] + ]; + $rbacUsers = new RbacUsers(); + $usersByAuthSource = $rbacUsers->show($filters); + + foreach ($usersByAuthSource['data'] ?? [] as $row) { + $this->arrayAuthenticationSourceUsersByUid[$row["USR_UID"]] = $row; + $this->arrayAuthenticationSourceUsersByUsername[$row["USR_USERNAME"]] = $row; + } + } catch (Exception $e) { + throw $e; + } + } + + public function clearManager($usersUIDs) + { + try { + $criteriaSet = new Criteria('workflow'); + $criteriaSet->add(UsersPeer::USR_REPORTS_TO, ''); + $criteriaWhere = new Criteria('workflow'); + $criteriaWhere->add(UsersPeer::USR_UID, $usersUIDs, Criteria::IN); + BasePeer::doUpdate($criteriaWhere, $criteriaSet, Propel::getConnection('workflow')); + } catch (Exception $error) { + $this->log($this->ldapcnn, $error->getMessage()); + } + } + + public function getUsersFromRemovedOu($aAuthSource) + { + $aUsers = []; //empty array is the default result + $attributes = $aAuthSource["AUTH_SOURCE_DATA"]; + $this->sTerminatedOu = isset($attributes['AUTH_SOURCE_RETIRED_OU']) ? trim($attributes['AUTH_SOURCE_RETIRED_OU']) : ''; + + if ($this->sTerminatedOu == '') { + return $aUsers; + } + + return $this->getUsersFromDepartmentByName($this->sTerminatedOu); + } + + public function synchronizeManagers($managersHierarchy) + { + try { + foreach ($managersHierarchy as $managerDN => $subordinates) { + $rbacUser = new RbacUsers(); + $rbacUsersData = $rbacUser->show(['conditions' => ['USR_AUTH_USER_DN' => $managerDN]]); + + if (!empty($rbacUsersData['data'])) { + $user = new User(); + $userData['USR_REPORTS_TO'] = $rbacUsersData['data'][0]['USR_UID']; + $user->updateDataFromListUsersUids($userData, $subordinates); + } + } + } catch (Exception $error) { + $this->log($this->ldapcnn, $error->getMessage()); + } + } + + public function progressBar($total, $count) + { + try { + $p = (int) (($count * 100) / $total); + $n = (int) ($p / 2); + + return "[" . str_repeat("|", $n) . str_repeat(" ", 50 - $n) . "] $p%"; + } catch (Exception $e) { + throw $e; + } + } + + public function getRegisteredDepartments(array $arrayLdapDepartment, array $arrayDbDepartment) + { + $aResult = []; + + if (!empty($arrayLdapDepartment)) { + $arrayLdapDepartment[0]["ou"] = $arrayLdapDepartment[0]["ou"] . " " . $arrayLdapDepartment[0]["dn"]; //Discard ROOT + + foreach ($arrayLdapDepartment as $ldapDept) { + foreach ($arrayDbDepartment as $department) { + if ($department["DEP_TITLE"] == $ldapDept["ou"] && $department["DEP_LDAP_DN"] == $ldapDept["dn"]) { + $aResult[] = $department; + break; + } + } + } + } + + return $aResult; + } + + public function getRegisteredGroups(array $arrayLdapGroup, array $arrayDbGroup) + { + $aResult = []; + + if (!empty($arrayLdapGroup)) { + foreach ($arrayLdapGroup as $ldapGroup) { + foreach ($arrayDbGroup as $group) { + if ($group["GRP_TITLE"] == $ldapGroup["cn"] && $group["GRP_LDAP_DN"] == $ldapGroup["dn"]) { + $aResult[] = $group; + } + } + } + } + + return $aResult; + } + + public function setArrayDepartmentUserSynchronizedChecked(array $arrayData) + { + try { + $this->arrayDepartmentUserSynchronizedChecked = $arrayData; + } catch (Exception $e) { + throw $e; + } + } + + public function setArrayUserUpdateChecked(array $arrayData) + { + try { + $this->arrayUserUpdateChecked = $arrayData; + } catch (Exception $e) { + throw $e; + } + } } \ No newline at end of file diff --git a/workflow/engine/src/ProcessMaker/Model/Department.php b/workflow/engine/src/ProcessMaker/Model/Department.php index 931023f9e..bafe8fe70 100644 --- a/workflow/engine/src/ProcessMaker/Model/Department.php +++ b/workflow/engine/src/ProcessMaker/Model/Department.php @@ -35,11 +35,11 @@ class Department extends Model try { $query = static::query(); - if (is_array($filters['fields'])) { + if (!empty($filters['fields']) && is_array($filters['fields'])) { $query->select($filters['fields']); } - if (is_array($filters['conditions'])) { + if (!empty($filters['conditions']) && is_array($filters['conditions'])) { if (!empty($filters['conditions']['text'])) { $query->where('DEP_TITLE', 'like', '%' . $filters['conditions']['text'] . '%'); unset($filters['conditions']['text']); @@ -49,13 +49,13 @@ class Department extends Model $total = $query->count(); - if (is_array($filters['start']) || is_array($filters['limit'])) { + if ((!empty($filters['start']) && is_array($filters['start'])) || (!empty($filters['limit']) && is_array($filters['limit']))) { $start = $filters['start'] ?? 0; $limit = $filters['limit'] ?? 25; $query->offset($start)->limit($limit); } - if (is_array($filters['orderBy'])) { + if (!empty($filters['orderBy']) && is_array($filters['orderBy'])) { $query->orderBy($filters['orderBy'][0], $filters['orderBy'][1] ?? 'asc'); } diff --git a/workflow/engine/src/ProcessMaker/Model/GroupUser.php b/workflow/engine/src/ProcessMaker/Model/GroupUser.php index 83c2d668b..74d70d49f 100644 --- a/workflow/engine/src/ProcessMaker/Model/GroupUser.php +++ b/workflow/engine/src/ProcessMaker/Model/GroupUser.php @@ -133,4 +133,83 @@ class GroupUser extends Model ]; return $result; } + + public function show($filters = array()) + { + try { + $query = static::query(); + + if (!empty($filters['fields']) && is_array($filters['fields'])) { + $query->select($filters['fields']); + } + + if (!empty($filters['conditions']) && is_array($filters['conditions'])) { + $query->where($filters['conditions']); + } + + $total = $query->count(); + + if ((!empty($filters['start']) && is_array($filters['start'])) || (!empty($filters['limit']) && is_array($filters['limit']))) { + $start = $filters['start'] ?? 0; + $limit = $filters['limit'] ?? 25; + $query->offset($start)->limit($limit); + } + + if (!empty($filters['orderBy']) && is_array($filters['orderBy'])) { + $query->orderBy($filters['orderBy'][0], $filters['orderBy'][1] ?? 'asc'); + } + + $data =$query->get()->toArray(); + $result = [ + 'total' => $total, + 'data' => $data + ]; + return $result; + } catch (Exception $exception) { + return $exception->getMessage(); + } + } + + public static function getUsersByGroupId($groupUid, $filters = []) + { + $query = static::query(); + + if (!empty($filters['fields']) && is_array($filters['fields'])) { + $query->select($filters['fields']); + } + + $query->where('GROUP_USER.GRP_UID', $groupUid); + $query->innerJoin('GROUP_USER.USR_UID', '=', 'USERS.USR_UID'); + + $total = $query->count(); + + if ((!empty($filters['start']) && is_array($filters['start'])) || (!empty($filters['limit']) && is_array($filters['limit']))) { + $start = $filters['start'] ?? 0; + $limit = $filters['limit'] ?? 25; + $query->offset($start)->limit($limit); + } + + if (!empty($filters['orderBy']) && is_array($filters['orderBy'])) { + $query->orderBy($filters['orderBy'][0], $filters['orderBy'][1] ?? 'asc'); + } + + $data =$query->get()->toArray(); + $result = [ + 'total' => $total, + 'data' => $data + ]; + return $result; + } + + public static function removeGroupUser($conditions) + { + try { + $responseSave = GroupUser::where($conditions) + ->delete(); + + return $responseSave; + } catch (Exception $exception) { + return $exception->getMessage(); + } + } } diff --git a/workflow/engine/src/ProcessMaker/Model/Groupwf.php b/workflow/engine/src/ProcessMaker/Model/Groupwf.php index a2df2b4df..871be9388 100644 --- a/workflow/engine/src/ProcessMaker/Model/Groupwf.php +++ b/workflow/engine/src/ProcessMaker/Model/Groupwf.php @@ -30,11 +30,11 @@ class Groupwf extends Model try { $query = static::query(); - if (is_array($filters['fields'])) { + if (!empty($filters['fields']) && is_array($filters['fields'])) { $query->select($filters['fields']); } - if (is_array($filters['conditions'])) { + if (!empty($filters['conditions']) && is_array($filters['conditions'])) { if (!empty($filters['conditions']['text'])) { $query->where('GRP_TITLE', 'like', '%' . $filters['conditions']['text'] . '%'); unset($filters['conditions']['text']); @@ -44,13 +44,13 @@ class Groupwf extends Model $total = $query->count(); - if (is_array($filters['start']) || is_array($filters['limit'])) { + if ((!empty($filters['start']) && is_array($filters['start'])) || (!empty($filters['limit']) && is_array($filters['limit']))) { $start = $filters['start'] ?? 0; $limit = $filters['limit'] ?? 25; $query->offset($start)->limit($limit); } - if (is_array($filters['orderBy'])) { + if (!empty($filters['orderBy']) && is_array($filters['orderBy'])) { $query->orderBy($filters['orderBy'][0], $filters['orderBy'][1] ?? 'asc'); } diff --git a/workflow/engine/src/ProcessMaker/Model/RbacAuthenticationSource.php b/workflow/engine/src/ProcessMaker/Model/RbacAuthenticationSource.php index 568150186..f95b9c3d3 100644 --- a/workflow/engine/src/ProcessMaker/Model/RbacAuthenticationSource.php +++ b/workflow/engine/src/ProcessMaker/Model/RbacAuthenticationSource.php @@ -34,11 +34,11 @@ class RbacAuthenticationSource extends Model try { $query = static::query(); - if (is_array($filters['fields'])) { + if (!empty($filters['fields']) && is_array($filters['fields'])) { $query->select($filters['fields']); } - if (is_array($filters['conditions'])) { + if (!empty($filters['conditions']) && is_array($filters['conditions'])) { if (!empty($filters['conditions']['text'])) { $query->where('AUTH_SOURCE_NAME', 'like', '%' . $filters['conditions']['text'] . '%'); unset($filters['conditions']['text']); @@ -48,13 +48,13 @@ class RbacAuthenticationSource extends Model $total = $query->count(); - if (is_array($filters['start']) || is_array($filters['limit'])) { + if ((!empty($filters['start']) && is_array($filters['start'])) || (!empty($filters['limit']) && is_array($filters['limit']))) { $start = $filters['start'] ?? 0; $limit = $filters['limit'] ?? 25; $query->offset($start)->limit($limit); } - if (is_array($filters['orderBy'])) { + if (!empty($filters['orderBy']) && is_array($filters['orderBy'])) { $query->orderBy($filters['orderBy'][0], $filters['orderBy'][1] ?? 'asc'); } diff --git a/workflow/engine/src/ProcessMaker/Model/RbacUsers.php b/workflow/engine/src/ProcessMaker/Model/RbacUsers.php index a9743e754..1fd36eee1 100644 --- a/workflow/engine/src/ProcessMaker/Model/RbacUsers.php +++ b/workflow/engine/src/ProcessMaker/Model/RbacUsers.php @@ -20,23 +20,23 @@ class RbacUsers extends Model try { $query = static::query(); - if (is_array($filters['fields'])) { + if (!empty($filters['fields']) && is_array($filters['fields'])) { $query->select($filters['fields']); } - if (is_array($filters['conditions'])) { + if (!empty($filters['conditions']) && is_array($filters['conditions'])) { $query->where($filters['conditions']); } $total = $query->count(); - if (is_array($filters['start']) || is_array($filters['limit'])) { + if ((!empty($filters['start']) && is_array($filters['start'])) || (!empty($filters['limit']) && is_array($filters['limit']))) { $start = $filters['start'] ?? 0; $limit = $filters['limit'] ?? 25; $query->offset($start)->limit($limit); } - if (is_array($filters['orderBy'])) { + if (!empty($filters['orderBy']) && is_array($filters['orderBy'])) { $query->orderBy($filters['orderBy'][0], $filters['orderBy'][1] ?? 'asc'); } @@ -96,6 +96,17 @@ class RbacUsers extends Model } } + public static function updateDataFromListUsersUids($userData, $usersUids = []) + { + try { + $responseSave = self::whereIn('USR_UID', $usersUids) + ->update($userData); + return $responseSave; + } catch (Exception $exception) { + return $exception->getMessage(); + } + } + /** * Verify if username exists * diff --git a/workflow/engine/src/ProcessMaker/Model/User.php b/workflow/engine/src/ProcessMaker/Model/User.php index 122038d6e..d1a3a0920 100644 --- a/workflow/engine/src/ProcessMaker/Model/User.php +++ b/workflow/engine/src/ProcessMaker/Model/User.php @@ -18,6 +18,79 @@ class User extends Model // Our custom timestamp columns const CREATED_AT = 'USR_CREATE_DATE'; const UPDATED_AT = 'USR_UPDATE_DATE'; + public function show($filters = array()) + { + try { + $query = static::query(); + + if (!empty($filters['fields']) && is_array($filters['fields'])) { + $query->select($filters['fields']); + } + + if (!empty($filters['conditions']) && is_array($filters['conditions'])) { + $query->where($filters['conditions']); + } + + $total = $query->count(); + + if ((!empty($filters['start']) && is_array($filters['start'])) || (!empty($filters['limit']) && is_array($filters['limit']))) { + $start = $filters['start'] ?? 0; + $limit = $filters['limit'] ?? 25; + $query->offset($start)->limit($limit); + } + + if (!empty($filters['orderBy']) && is_array($filters['orderBy'])) { + $query->orderBy($filters['orderBy'][0], $filters['orderBy'][1] ?? 'asc'); + } + + $data =$query->get()->toArray(); + $result = [ + 'total' => $total, + 'data' => $data + ]; + return $result; + } catch (Exception $exception) { + return $exception->getMessage(); + } + } + + public function getByListUids($listUids, $filters = array()) + { + try { + $query = static::query(); + + if (!empty($filters['fields']) && is_array($filters['fields'])) { + $query->select($filters['fields']); + } + + if (!empty($filters['conditions']) && is_array($filters['conditions'])) { + $query->where($filters['conditions']); + } + + $query->whereIn('USR_UID', $listUids); + + $total = $query->count(); + + if ((!empty($filters['start']) && is_array($filters['start'])) || (!empty($filters['limit']) && is_array($filters['limit']))) { + $start = $filters['start'] ?? 0; + $limit = $filters['limit'] ?? 25; + $query->offset($start)->limit($limit); + } + + if (!empty($filters['orderBy']) && is_array($filters['orderBy'])) { + $query->orderBy($filters['orderBy'][0], $filters['orderBy'][1] ?? 'asc'); + } + + $data =$query->get()->toArray(); + $result = [ + 'total' => $total, + 'data' => $data + ]; + return $result; + } catch (Exception $exception) { + return $exception->getMessage(); + } + } /** * Returns the delegations this user has (all of them) @@ -317,4 +390,31 @@ class User extends Model ]; return $result; } + + public static function updateData($userData, $conditions = []) + { + try { + $responseSave = self::where($conditions) + ->update($userData); + return $responseSave; + } catch (Exception $exception) { + return $exception->getMessage(); + } + } + + public static function updateDataFromListUsersUids($userData, $usersUids = [], $extraConditions = []) + { + try { + $query = self::whereIn('USR_UID', $usersUids); + + if (!empty($extraConditions) && is_array($extraConditions)) { + $query->where($extraConditions); + } + + $responseSave = $query->update($userData); + return $responseSave; + } catch (Exception $exception) { + return $exception->getMessage(); + } + } }