TASK-228 Encrypt the password for authentication sources
This commit is contained in:
@@ -7,11 +7,43 @@ use ProcessMaker\Model\GroupUser;
|
|||||||
use ProcessMaker\Model\Groupwf;
|
use ProcessMaker\Model\Groupwf;
|
||||||
use ProcessMaker\Model\User;
|
use ProcessMaker\Model\User;
|
||||||
use ProcessMaker\Model\Department;
|
use ProcessMaker\Model\Department;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AuthSources Class
|
||||||
|
*
|
||||||
|
* This class manages authentication sources for the Lurana workflow engine.
|
||||||
|
* It provides functionality to handle LDAP authentication sources including:
|
||||||
|
* - Listing and managing authentication sources
|
||||||
|
* - Testing LDAP connections
|
||||||
|
* - Importing users from LDAP
|
||||||
|
* - Managing groups and departments synchronization
|
||||||
|
*
|
||||||
|
* @package Lurana\Workflow\Engine\Classes
|
||||||
|
* @author Lurana Team
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
class AuthSources
|
class AuthSources
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of authentication sources
|
||||||
|
*
|
||||||
|
* This method fetches authentication sources with pagination support,
|
||||||
|
* filtering, and sorting capabilities. It also includes user count
|
||||||
|
* information for each authentication source.
|
||||||
|
*
|
||||||
|
* @param string $userUid The unique identifier of the requesting user
|
||||||
|
* @param int $start Starting position for pagination (default: 0)
|
||||||
|
* @param int $limit Maximum number of records to return (default: 25)
|
||||||
|
* @param string $orderBy Field name to sort by (optional)
|
||||||
|
* @param string $ascending Sort direction: 'asc' or 'desc' (default: 'asc', invalid values auto-convert to 'asc')
|
||||||
|
* @param string $filter Text filter to search authentication sources (optional)
|
||||||
|
*
|
||||||
|
* @return array Response array containing:
|
||||||
|
* - success: boolean indicating operation success
|
||||||
|
* - sources: array of authentication source data
|
||||||
|
* - total_sources: total count of authentication sources
|
||||||
|
* - message: error message if operation fails
|
||||||
|
*/
|
||||||
public function getListAuthSources($userUid, $start = 0, $limit = 25, $orderBy = '', $ascending = 'asc' , $filter = '') {
|
public function getListAuthSources($userUid, $start = 0, $limit = 25, $orderBy = '', $ascending = 'asc' , $filter = '') {
|
||||||
try {
|
try {
|
||||||
if ($limit == 0) {
|
if ($limit == 0) {
|
||||||
@@ -48,22 +80,21 @@ class AuthSources
|
|||||||
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
||||||
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
||||||
|
|
||||||
global $RBAC;
|
$rbacUsers = new RbacUsers();
|
||||||
$auth = $RBAC->getAllUsersByAuthSource();
|
$usersByAuthSource = $rbacUsers->getAllUsersByAuthSource();
|
||||||
|
$auth = [];
|
||||||
|
foreach (($usersByAuthSource['data'] ?? []) as $user) {
|
||||||
|
$auth[$user['UID_AUTH_SOURCE']] = $user['CNT'];
|
||||||
|
}
|
||||||
|
|
||||||
$sources = [];
|
$sources = [];
|
||||||
foreach ($authSourceReturn['data'] as $key => $authSourceRow) {
|
foreach (($authSourceReturn['data'] ?? []) as $authSourceRow) {
|
||||||
$values = explode('_', $authSourceRow['AUTH_SOURCE_PASSWORD']);
|
|
||||||
foreach ($values as $value) {
|
|
||||||
if ($value == '2NnV3ujj3w') {
|
|
||||||
$authSourceRow['AUTH_SOURCE_PASSWORD'] = G::decrypt($values[0], $authSourceRow['AUTH_SOURCE_SERVER_NAME']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$label = G::LoadTranslation('ID_DISABLE');
|
$label = G::LoadTranslation('ID_DISABLE');
|
||||||
if ($authSourceRow['AUTH_SOURCE_ENABLED_TLS'] === '1') {
|
if ($authSourceRow['AUTH_SOURCE_ENABLED_TLS'] === '1') {
|
||||||
$label = G::LoadTranslation('ID_ENABLE');
|
$label = G::LoadTranslation('ID_ENABLE');
|
||||||
}
|
}
|
||||||
$authSourceRow['AUTH_SOURCE_ENABLED_TLS_LABEL'] = $label;
|
$authSourceRow['AUTH_SOURCE_ENABLED_TLS_LABEL'] = $label;
|
||||||
|
$authSourceRow['AUTH_SOURCE_PASSWORD'] = '';
|
||||||
//additional information
|
//additional information
|
||||||
$authSourceData = json_decode($authSourceRow['AUTH_SOURCE_DATA'], true);
|
$authSourceData = json_decode($authSourceRow['AUTH_SOURCE_DATA'], true);
|
||||||
if (is_array($authSourceData)) {
|
if (is_array($authSourceData)) {
|
||||||
@@ -71,7 +102,7 @@ class AuthSources
|
|||||||
}
|
}
|
||||||
$authSourceRow['AUTH_ANONYMOUS'] = (string)$authSourceRow['AUTH_ANONYMOUS'];
|
$authSourceRow['AUTH_ANONYMOUS'] = (string)$authSourceRow['AUTH_ANONYMOUS'];
|
||||||
$sources[] = $authSourceRow;
|
$sources[] = $authSourceRow;
|
||||||
$index = sizeof($sources) - 1;
|
$index = array_key_last($sources);
|
||||||
$sources[$index]['CURRENT_USERS'] = isset($auth[$sources[$index]['AUTH_SOURCE_UID']]) ? $auth[$sources[$index]['AUTH_SOURCE_UID']] : 0;
|
$sources[$index]['CURRENT_USERS'] = isset($auth[$sources[$index]['AUTH_SOURCE_UID']]) ? $auth[$sources[$index]['AUTH_SOURCE_UID']] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,9 +117,29 @@ class AuthSources
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an authentication source from the system
|
||||||
|
*
|
||||||
|
* This method permanently deletes an authentication source
|
||||||
|
* identified by its unique identifier. It validates that the
|
||||||
|
* authentication source exists before attempting removal.
|
||||||
|
*
|
||||||
|
* @param string $authSourceUid The unique identifier of the authentication source to remove
|
||||||
|
*
|
||||||
|
* @return array Response array containing:
|
||||||
|
* - success: boolean indicating operation success
|
||||||
|
* - deleteRows: number of rows deleted (if successful)
|
||||||
|
* - message: error message if operation fails
|
||||||
|
*
|
||||||
|
* @throws Exception When authSourceUid is empty or authentication source not found
|
||||||
|
*/
|
||||||
public function removeAuthSource($authSourceUid) {
|
public function removeAuthSource($authSourceUid) {
|
||||||
try {
|
try {
|
||||||
$conditions = ['AUTH_SOURCE_UID'=> $authSourceUid];
|
if (empty($authSourceUid)) {
|
||||||
|
throw new Exception('Authentication source UID is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
$conditions = ['AUTH_SOURCE_UID' => $authSourceUid];
|
||||||
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
||||||
$removeResponse = $rbacAuthenticationSource->remove($conditions);
|
$removeResponse = $rbacAuthenticationSource->remove($conditions);
|
||||||
return ['success' => true, 'deleteRows' => $removeResponse['deleteRows'] ];
|
return ['success' => true, 'deleteRows' => $removeResponse['deleteRows'] ];
|
||||||
@@ -97,6 +148,21 @@ class AuthSources
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies if an authentication source name already exists and suggests alternatives
|
||||||
|
*
|
||||||
|
* This method checks if a given authentication source name is already in use.
|
||||||
|
* If the name exists, it generates a suggested alternative name by appending
|
||||||
|
* a number in parentheses (e.g., "Source Name (1)").
|
||||||
|
*
|
||||||
|
* @param string $authSourceName The authentication source name to verify
|
||||||
|
*
|
||||||
|
* @return array Response array containing:
|
||||||
|
* - success: boolean indicating operation success
|
||||||
|
* - row: existing authentication source data (false if not found)
|
||||||
|
* - suggestName: suggested alternative name if original exists
|
||||||
|
* - message: error message if operation fails
|
||||||
|
*/
|
||||||
public function verifyAuthSourceName($authSourceName) {
|
public function verifyAuthSourceName($authSourceName) {
|
||||||
try {
|
try {
|
||||||
$row = false;
|
$row = false;
|
||||||
@@ -108,6 +174,7 @@ class AuthSources
|
|||||||
|
|
||||||
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
||||||
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
||||||
|
$authSourceReturn['AUTH_SOURCE_DATA'] = json_decode($authSourceReturn['AUTH_SOURCE_DATA'], true);
|
||||||
|
|
||||||
if ($authSourceReturn['total'] > 0) {
|
if ($authSourceReturn['total'] > 0) {
|
||||||
$row = $authSourceReturn['data'][0];
|
$row = $authSourceReturn['data'][0];
|
||||||
@@ -135,10 +202,25 @@ class AuthSources
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the connection to an LDAP authentication source
|
||||||
|
*
|
||||||
|
* This method validates the connection parameters for an LDAP server
|
||||||
|
* and checks if TLS encryption is properly configured.
|
||||||
|
*
|
||||||
|
* @param array $authSourceData Array containing LDAP connection parameters:
|
||||||
|
* - server, port, username, password, base DN, etc.
|
||||||
|
*
|
||||||
|
* @return array Response array containing:
|
||||||
|
* - success: boolean indicating connection success
|
||||||
|
* - status: connection status ('OK' if successful)
|
||||||
|
* - message: warning/error message (e.g., TLS certificate issues)
|
||||||
|
*/
|
||||||
public function testConnection($authSourceData) {
|
public function testConnection($authSourceData) {
|
||||||
try {
|
try {
|
||||||
$ldapSource = new LdapSource();
|
$ldapSource = new LdapSource();
|
||||||
$authSourceConnectionData = $ldapSource->ldapConnection($authSourceData);
|
$authSourceConnectionData = $ldapSource->ldapConnection($authSourceData);
|
||||||
|
$connectionEstablished = isset($authSourceConnectionData['connection']) && $authSourceConnectionData['connection'];
|
||||||
|
|
||||||
$response = ['success' => true, 'status' => 'OK'];
|
$response = ['success' => true, 'status' => 'OK'];
|
||||||
if ($authSourceConnectionData['startTLS'] === false) {
|
if ($authSourceConnectionData['startTLS'] === false) {
|
||||||
@@ -150,33 +232,83 @@ class AuthSources
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves or updates an authentication source configuration
|
||||||
|
*
|
||||||
|
* This method creates a new authentication source or updates an existing one.
|
||||||
|
* It establishes an LDAP connection to validate the configuration and
|
||||||
|
* determines the LDAP page size limit for optimal performance.
|
||||||
|
*
|
||||||
|
* @param array $authSourceData Complete authentication source configuration including:
|
||||||
|
* - AUTH_SOURCE_UID: unique identifier (empty for new sources)
|
||||||
|
* - AUTH_SOURCE_DATA: LDAP connection parameters
|
||||||
|
* - AUTH_SOURCE_BASE_DN: base distinguished name
|
||||||
|
*
|
||||||
|
* @return array Response array containing:
|
||||||
|
* - success: boolean indicating operation success
|
||||||
|
* - saveData: saved authentication source data
|
||||||
|
* - message: error message if operation fails
|
||||||
|
*/
|
||||||
public function saveAuthSource($authSourceData) {
|
public function saveAuthSource($authSourceData) {
|
||||||
try {
|
try {
|
||||||
$authSourceData['AUTH_SOURCE_VERSION'] = 3;
|
|
||||||
$ldapSource = new LdapSource();
|
$ldapSource = new LdapSource();
|
||||||
|
$authSourceData['AUTH_SOURCE_VERSION'] = 3;
|
||||||
$ldapConnection = $ldapSource->ldapConnection($authSourceData);
|
$ldapConnection = $ldapSource->ldapConnection($authSourceData);
|
||||||
|
|
||||||
|
if (!isset($ldapConnection['connection']) || !$ldapConnection['connection']) {
|
||||||
|
throw new Exception('LDAP connection failed');
|
||||||
|
}
|
||||||
|
|
||||||
$authSourceData['AUTH_SOURCE_DATA']['LDAP_PAGE_SIZE_LIMIT'] = $ldapSource->getPageSizeLimit(
|
$authSourceData['AUTH_SOURCE_DATA']['LDAP_PAGE_SIZE_LIMIT'] = $ldapSource->getPageSizeLimit(
|
||||||
$ldapConnection['connection'],
|
$ldapConnection['connection'],
|
||||||
$authSourceData['AUTH_SOURCE_BASE_DN']
|
$authSourceData['AUTH_SOURCE_BASE_DN']
|
||||||
);
|
);
|
||||||
|
|
||||||
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
|
||||||
$authSourceData['AUTH_SOURCE_UID'] = $authSourceData['AUTH_SOURCE_UID'] ?? '';
|
$authSourceData['AUTH_SOURCE_UID'] = $authSourceData['AUTH_SOURCE_UID'] ?? '';
|
||||||
|
if (!empty($authSourceData['AUTH_SOURCE_UID']) && empty($authSourceData['AUTH_SOURCE_PASSWORD'])) {
|
||||||
|
unset($authSourceData['AUTH_SOURCE_PASSWORD']);
|
||||||
|
} else {
|
||||||
|
$authSourceData['AUTH_SOURCE_PASSWORD'] = G::encrypt($authSourceData['AUTH_SOURCE_PASSWORD'], URL_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
$authSourceData['AUTH_SOURCE_DATA'] = json_encode($authSourceData['AUTH_SOURCE_DATA']);
|
$authSourceData['AUTH_SOURCE_DATA'] = json_encode($authSourceData['AUTH_SOURCE_DATA']);
|
||||||
|
|
||||||
|
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
||||||
$saveDataResponse = $rbacAuthenticationSource->saveData($authSourceData);
|
$saveDataResponse = $rbacAuthenticationSource->saveData($authSourceData);
|
||||||
|
|
||||||
return ['success' => true, 'saveData' => $saveDataResponse];
|
return ['success' => true, 'saveData' => $saveDataResponse];
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
return ['success' => false, 'message' => $exception->getMessage()];
|
return ['success' => false, 'message' => $exception->getMessage()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for users in an LDAP authentication source
|
||||||
|
*
|
||||||
|
* This method queries an LDAP server to find users based on search criteria.
|
||||||
|
* It compares found users with existing system users to determine import status.
|
||||||
|
*
|
||||||
|
* @param string $authSourceUid The unique identifier of the authentication source
|
||||||
|
* @param array $filters Search parameters containing:
|
||||||
|
* - text: search term for user lookup
|
||||||
|
* - start: pagination start position
|
||||||
|
* - limit: maximum number of results
|
||||||
|
*
|
||||||
|
* @return array Response array containing:
|
||||||
|
* - success: boolean indicating operation success
|
||||||
|
* - status: operation status ('OK' if successful)
|
||||||
|
* - resultTotal: total number of users found
|
||||||
|
* - resultRoot: array of user data with import status
|
||||||
|
* - message: error message if operation fails
|
||||||
|
*/
|
||||||
public function searchUsers($authSourceUid, $filters) {
|
public function searchUsers($authSourceUid, $filters) {
|
||||||
try {
|
try {
|
||||||
$rbacUsers = new RbacUsers();
|
$rbacUsers = new RbacUsers();
|
||||||
$usersAuthSources = $rbacUsers->listUsersAuthSources();
|
$usersAuthSources = $rbacUsers->listUsersAuthSources();
|
||||||
|
|
||||||
foreach ($usersAuthSources['data'] as $row) {
|
$listUsers = [];
|
||||||
|
foreach (($usersAuthSources['data'] ?? []) as $row) {
|
||||||
$listUsers[strtolower($row['USR_USERNAME'])] = $row['UID_AUTH_SOURCE'];
|
$listUsers[strtolower($row['USR_USERNAME'])] = $row['UID_AUTH_SOURCE'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,14 +316,15 @@ class AuthSources
|
|||||||
$ldapSource->authSourceUid = $authSourceUid;
|
$ldapSource->authSourceUid = $authSourceUid;
|
||||||
$result = $ldapSource->searchUsersLdap($filters['text'], $filters['start'], $filters['limit']);
|
$result = $ldapSource->searchUsersLdap($filters['text'], $filters['start'], $filters['limit']);
|
||||||
|
|
||||||
$arrayData = array();
|
$arrayData = [];
|
||||||
foreach ($result['data'] as $value) {
|
foreach (($result['data'] ?? []) as $value) {
|
||||||
$listUsersData = $value;
|
$listUsersData = $value;
|
||||||
|
$usernameLower = strtolower($listUsersData['sUsername']);
|
||||||
|
|
||||||
if (!isset($listUsers[strtolower($listUsersData['sUsername'])])) {
|
if (!isset($listUsers[$usernameLower])) {
|
||||||
$listUsersData['STATUS'] = G::LoadTranslation('ID_NOT_IMPORTED');
|
$listUsersData['STATUS'] = G::LoadTranslation('ID_NOT_IMPORTED');
|
||||||
$listUsersData['IMPORT'] = 1;
|
$listUsersData['IMPORT'] = 1;
|
||||||
} elseif ($authSourceUid === $listUsers[strtolower($listUsersData['sUsername'])]) {
|
} elseif ($authSourceUid === $listUsers[$usernameLower]) {
|
||||||
$listUsersData['STATUS'] = G::LoadTranslation('ID_IMPORTED');
|
$listUsersData['STATUS'] = G::LoadTranslation('ID_IMPORTED');
|
||||||
$listUsersData['IMPORT'] = 0;
|
$listUsersData['IMPORT'] = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -208,20 +341,40 @@ class AuthSources
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports users from an LDAP authentication source into the system
|
||||||
|
*
|
||||||
|
* This method creates new user accounts in the system based on LDAP user data.
|
||||||
|
* It handles user attribute mapping, role assignment, and calendar assignment.
|
||||||
|
*
|
||||||
|
* @param string $authSourceUid The unique identifier of the authentication source
|
||||||
|
* @param array $usersImport Array of user objects to import, each containing:
|
||||||
|
* - sUsername: LDAP username
|
||||||
|
* - sFirstname: user's first name
|
||||||
|
* - sLastname: user's last name
|
||||||
|
* - sEmail: user's email address
|
||||||
|
* - sDN: user's distinguished name
|
||||||
|
* - USR_STATUS: user status (optional)
|
||||||
|
*
|
||||||
|
* @return array Response array containing:
|
||||||
|
* - success: boolean indicating operation success
|
||||||
|
* - message: error message if operation fails
|
||||||
|
*/
|
||||||
public function importUsers($authSourceUid, $usersImport) {
|
public function importUsers($authSourceUid, $usersImport) {
|
||||||
try {
|
try {
|
||||||
$filters = ['conditions' => ['AUTH_SOURCE_UID'=> $authSourceUid]];
|
$filters = ['conditions' => ['AUTH_SOURCE_UID'=> $authSourceUid]];
|
||||||
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
||||||
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
||||||
$authSourceReturn = $authSourceReturn['data'][0];
|
|
||||||
|
|
||||||
$aAttributes = array();
|
if (empty($authSourceReturn['data']) || !isset($authSourceReturn['data'][0])) {
|
||||||
if (isset($authSourceReturn['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE'])) {
|
throw new Exception('Authentication source not found');
|
||||||
$aAttributes = $authSourceReturn['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$usersCreated = '';
|
$authSourceReturn = $authSourceReturn['data'][0];
|
||||||
$countUsers = 0;
|
$authSourceReturn['AUTH_SOURCE_DATA'] = json_decode($authSourceReturn['AUTH_SOURCE_DATA'], true);
|
||||||
|
|
||||||
|
$aAttributes = $authSourceReturn['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE'] ?? [];
|
||||||
|
|
||||||
global $RBAC;
|
global $RBAC;
|
||||||
foreach ($usersImport as $sUser) {
|
foreach ($usersImport as $sUser) {
|
||||||
$aUser = (array) $sUser;
|
$aUser = (array) $sUser;
|
||||||
@@ -229,9 +382,6 @@ class AuthSources
|
|||||||
$aData = array();
|
$aData = array();
|
||||||
$aData['USR_USERNAME'] = str_replace('*', "'", $aUser['sUsername']);
|
$aData['USR_USERNAME'] = str_replace('*', "'", $aUser['sUsername']);
|
||||||
$aData['USR_PASSWORD'] = '00000000000000000000000000000000';
|
$aData['USR_PASSWORD'] = '00000000000000000000000000000000';
|
||||||
// note added by gustavo gustavo-at-colosa.com
|
|
||||||
// asign the FirstName and LastName variables
|
|
||||||
// add replace to change D*Souza to D'Souza by krlos
|
|
||||||
$aData['USR_FIRSTNAME'] = str_replace('*', "'", $aUser['sFirstname']);
|
$aData['USR_FIRSTNAME'] = str_replace('*', "'", $aUser['sFirstname']);
|
||||||
$aData['USR_FIRSTNAME'] = ($aData['USR_FIRSTNAME'] == '') ? $aData['USR_USERNAME'] : $aData['USR_FIRSTNAME'];
|
$aData['USR_FIRSTNAME'] = ($aData['USR_FIRSTNAME'] == '') ? $aData['USR_USERNAME'] : $aData['USR_FIRSTNAME'];
|
||||||
$aData['USR_LASTNAME'] = str_replace('*', "'", $aUser['sLastname']);
|
$aData['USR_LASTNAME'] = str_replace('*', "'", $aUser['sLastname']);
|
||||||
@@ -240,15 +390,14 @@ class AuthSources
|
|||||||
$aData['USR_CREATE_DATE'] = date('Y-m-d H:i:s');
|
$aData['USR_CREATE_DATE'] = date('Y-m-d H:i:s');
|
||||||
$aData['USR_UPDATE_DATE'] = date('Y-m-d H:i:s');
|
$aData['USR_UPDATE_DATE'] = date('Y-m-d H:i:s');
|
||||||
$aData['USR_BIRTHDAY'] = date('Y-m-d');
|
$aData['USR_BIRTHDAY'] = date('Y-m-d');
|
||||||
|
// Set USR_STATUS for RBAC (numeric format)
|
||||||
$aData['USR_STATUS'] = (isset($aUser['USR_STATUS'])) ? (($aUser['USR_STATUS'] == 'ACTIVE') ? 1 : 0) : 1;
|
$aData['USR_STATUS'] = (isset($aUser['USR_STATUS'])) ? (($aUser['USR_STATUS'] == 'ACTIVE') ? 1 : 0) : 1;
|
||||||
$aData['USR_AUTH_TYPE'] = strtolower($authSourceReturn['AUTH_SOURCE_PROVIDER']);
|
$aData['USR_AUTH_TYPE'] = strtolower($authSourceReturn['AUTH_SOURCE_PROVIDER']);
|
||||||
$aData['UID_AUTH_SOURCE'] = $authSourceReturn['AUTH_SOURCE_UID'];
|
$aData['UID_AUTH_SOURCE'] = $authSourceReturn['AUTH_SOURCE_UID'];
|
||||||
|
|
||||||
// validating with regexp if there are some missing * inside the DN string
|
|
||||||
// if it's so the is changed to the ' character
|
|
||||||
preg_match('/[a-zA-Z]\*[a-zA-Z]/', $aUser['sDN'], $matches);
|
preg_match('/[a-zA-Z]\*[a-zA-Z]/', $aUser['sDN'], $matches);
|
||||||
|
|
||||||
foreach ($matches as $key => $match) {
|
foreach ($matches as $match) {
|
||||||
$newMatch = str_replace('*', '\'', $match);
|
$newMatch = str_replace('*', '\'', $match);
|
||||||
$aUser['sDN'] = str_replace($match, $newMatch, $aUser['sDN']);
|
$aUser['sDN'] = str_replace($match, $newMatch, $aUser['sDN']);
|
||||||
}
|
}
|
||||||
@@ -260,9 +409,8 @@ class AuthSources
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sUserUID = $RBAC->createUser($aData, $usrRole, $authSourceReturn['AUTH_SOURCE_NAME']);
|
$sUserUID = $RBAC->createUser($aData, $usrRole, $authSourceReturn['AUTH_SOURCE_NAME']);
|
||||||
$usersCreated .= $aData['USR_USERNAME'] . ' ';
|
|
||||||
$countUsers++;
|
|
||||||
|
|
||||||
|
// Set USR_STATUS for User model (string format)
|
||||||
$aData['USR_STATUS'] = (isset($aUser['USR_STATUS'])) ? $aUser['USR_STATUS'] : 'ACTIVE';
|
$aData['USR_STATUS'] = (isset($aUser['USR_STATUS'])) ? $aUser['USR_STATUS'] : 'ACTIVE';
|
||||||
$aData['USR_UID'] = $sUserUID;
|
$aData['USR_UID'] = $sUserUID;
|
||||||
$aData['USR_ROLE'] = $usrRole;
|
$aData['USR_ROLE'] = $usrRole;
|
||||||
@@ -275,7 +423,6 @@ class AuthSources
|
|||||||
if (isset($aUser[$value['attributeUser']])) {
|
if (isset($aUser[$value['attributeUser']])) {
|
||||||
$aData[$value['attributeUser']] = str_replace('*', "'", $aUser[$value['attributeUser']]);
|
$aData[$value['attributeUser']] = str_replace('*', "'", $aUser[$value['attributeUser']]);
|
||||||
if ($value['attributeUser'] == 'USR_STATUS') {
|
if ($value['attributeUser'] == 'USR_STATUS') {
|
||||||
$evalValue = $aData[$value['attributeUser']];
|
|
||||||
$statusValue = $aData['USR_STATUS'];
|
$statusValue = $aData['USR_STATUS'];
|
||||||
$aData[$value['attributeUser']] = $statusValue;
|
$aData[$value['attributeUser']] = $statusValue;
|
||||||
}
|
}
|
||||||
@@ -291,6 +438,19 @@ class AuthSources
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for groups in an LDAP authentication source
|
||||||
|
*
|
||||||
|
* This method retrieves all available groups from an LDAP server
|
||||||
|
* and compares them with existing system groups to show synchronization status.
|
||||||
|
*
|
||||||
|
* @param string $authSourceUid The unique identifier of the authentication source
|
||||||
|
*
|
||||||
|
* @return array|TreeNodeAuthSource[] Array of TreeNodeAuthSource objects representing groups, or
|
||||||
|
* error array containing:
|
||||||
|
* - success: false
|
||||||
|
* - message: error description
|
||||||
|
*/
|
||||||
public function searchGroups($authSourceUid) {
|
public function searchGroups($authSourceUid) {
|
||||||
try {
|
try {
|
||||||
$ldapSource = new LdapSource();
|
$ldapSource = new LdapSource();
|
||||||
@@ -299,7 +459,7 @@ class AuthSources
|
|||||||
|
|
||||||
$allGroupsLdap = [];
|
$allGroupsLdap = [];
|
||||||
foreach ($groupsLdap as $group) {
|
foreach ($groupsLdap as $group) {
|
||||||
$node = array();
|
$node = [];
|
||||||
$node['GRP_UID'] = $group['cn'];
|
$node['GRP_UID'] = $group['cn'];
|
||||||
$node['GRP_TITLE'] = $group['cn'];
|
$node['GRP_TITLE'] = $group['cn'];
|
||||||
$node['GRP_USERS'] = $group['users'];
|
$node['GRP_USERS'] = $group['users'];
|
||||||
@@ -310,7 +470,7 @@ class AuthSources
|
|||||||
$groupUser = new GroupUser();
|
$groupUser = new GroupUser();
|
||||||
$groupsNumberUsers = $groupUser->getNumberOfUsersByGroups();
|
$groupsNumberUsers = $groupUser->getNumberOfUsersByGroups();
|
||||||
$listGroupsNumberUsers = [];
|
$listGroupsNumberUsers = [];
|
||||||
foreach ($groupsNumberUsers['data'] as $group) {
|
foreach (($groupsNumberUsers['data'] ?? []) as $group) {
|
||||||
$listGroupsNumberUsers[$group['GRP_UID']] = $group['NUM_REC'];
|
$listGroupsNumberUsers[$group['GRP_UID']] = $group['NUM_REC'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,9 +479,9 @@ class AuthSources
|
|||||||
foreach ($allGroupsLdap as $group) {
|
foreach ($allGroupsLdap as $group) {
|
||||||
$groupObject = new TreeNodeAuthSource();
|
$groupObject = new TreeNodeAuthSource();
|
||||||
$groupObject->text = htmlentities($group['GRP_TITLE'], ENT_QUOTES, 'UTF-8');
|
$groupObject->text = htmlentities($group['GRP_TITLE'], ENT_QUOTES, 'UTF-8');
|
||||||
$groupUid = $groupwf->getGroupWithDN($group['GRP_DN']);
|
$groupResult = $groupwf->getGroupWithDN($group['GRP_DN']);
|
||||||
if (!empty($groupUid[0]['GRP_UID'])) {
|
if (!empty($groupResult) && !empty($groupResult[0]['GRP_UID'])) {
|
||||||
$groupUid = $groupUid[0]['GRP_UID'];
|
$groupUid = $groupResult[0]['GRP_UID'];
|
||||||
$groupObject->text .= ' (' . ($listGroupsNumberUsers[$groupUid] ?? 0) . ')';
|
$groupObject->text .= ' (' . ($listGroupsNumberUsers[$groupUid] ?? 0) . ')';
|
||||||
$groupObject->checked = true;
|
$groupObject->checked = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -337,18 +497,30 @@ class AuthSources
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function searchDepartaments($authSourceUid) {
|
/**
|
||||||
|
* Searches for departments (organizational units) in an LDAP authentication source
|
||||||
|
*
|
||||||
|
* This method retrieves the organizational unit structure from an LDAP server
|
||||||
|
* and builds a hierarchical tree representation with user count information.
|
||||||
|
*
|
||||||
|
* @param string $authSourceUid The unique identifier of the authentication source
|
||||||
|
*
|
||||||
|
* @return array|TreeNodeAuthSource[] Hierarchical array of department objects, or
|
||||||
|
* error array containing:
|
||||||
|
* - success: false
|
||||||
|
* - message: error description
|
||||||
|
*/
|
||||||
|
public function searchDepartments($authSourceUid) {
|
||||||
try {
|
try {
|
||||||
$ldapSource = new LdapSource();
|
$ldapSource = new LdapSource();
|
||||||
$ldapSource->authSourceUid = $authSourceUid;
|
$ldapSource->authSourceUid = $authSourceUid;
|
||||||
$departments = $ldapSource->searchDepartments();
|
$departments = $ldapSource->searchDepartments();
|
||||||
|
|
||||||
$departmentsObjects = array();
|
|
||||||
$user = new User();
|
$user = new User();
|
||||||
$departmentsNumberUsers = $user->getNumberOfUsersByDepartments();
|
$departmentsNumberUsers = $user->getNumberOfUsersByDepartments();
|
||||||
$listDepartmentsNumberUsers = [];
|
$listDepartmentsNumberUsers = [];
|
||||||
foreach ($departmentsNumberUsers['data'] as $group) {
|
foreach (($departmentsNumberUsers['data'] ?? []) as $department) {
|
||||||
$listDepartmentsNumberUsers[$group['DEP_UID']] = $group['NUM_REC'];
|
$listDepartmentsNumberUsers[$department['DEP_UID']] = $department['NUM_REC'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$departmentsObject = $this->getChildrenDepartments($departments, '', $listDepartmentsNumberUsers, $ldapSource->terminatedOu);
|
$departmentsObject = $this->getChildrenDepartments($departments, '', $listDepartmentsNumberUsers, $ldapSource->terminatedOu);
|
||||||
@@ -358,7 +530,23 @@ class AuthSources
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves group synchronization settings for an authentication source
|
||||||
|
*
|
||||||
|
* This method processes a list of LDAP group distinguished names to synchronize
|
||||||
|
* with the system. It creates new groups or updates existing ones and handles
|
||||||
|
* unsynchronization of previously synchronized groups.
|
||||||
|
*
|
||||||
|
* @param string $groupsDN Pipe-separated list of URL-encoded group distinguished names
|
||||||
|
* @param string $authSourceUid The unique identifier of the authentication source
|
||||||
|
*
|
||||||
|
* @return array Response array containing:
|
||||||
|
* - success: boolean indicating operation success
|
||||||
|
* - status: operation status ('OK' if successful)
|
||||||
|
* - message: error message if operation fails
|
||||||
|
*/
|
||||||
public function saveGroups($groupsDN, $authSourceUid) {
|
public function saveGroups($groupsDN, $authSourceUid) {
|
||||||
|
try {
|
||||||
$groupsToCheck = explode('|', $groupsDN);
|
$groupsToCheck = explode('|', $groupsDN);
|
||||||
$groupsToCheck = array_map('urldecode', $groupsToCheck);
|
$groupsToCheck = array_map('urldecode', $groupsToCheck);
|
||||||
$groupsToUncheck = $this->getGroupsToUncheck($groupsToCheck);
|
$groupsToUncheck = $this->getGroupsToUncheck($groupsToCheck);
|
||||||
@@ -366,6 +554,11 @@ class AuthSources
|
|||||||
$filters = ['conditions' => ['AUTH_SOURCE_UID'=> $authSourceUid]];
|
$filters = ['conditions' => ['AUTH_SOURCE_UID'=> $authSourceUid]];
|
||||||
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
||||||
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
||||||
|
|
||||||
|
if (empty($authSourceReturn['data']) || !isset($authSourceReturn['data'][0])) {
|
||||||
|
throw new Exception('Authentication source not found');
|
||||||
|
}
|
||||||
|
|
||||||
$authenticationSourceData = $authSourceReturn['data'][0];
|
$authenticationSourceData = $authSourceReturn['data'][0];
|
||||||
$authenticationSourceData['AUTH_SOURCE_DATA'] = json_decode($authenticationSourceData['AUTH_SOURCE_DATA'], true);
|
$authenticationSourceData['AUTH_SOURCE_DATA'] = json_decode($authenticationSourceData['AUTH_SOURCE_DATA'], true);
|
||||||
|
|
||||||
@@ -388,7 +581,10 @@ class AuthSources
|
|||||||
'conditions' => ['GRP_TITLE' => $groupTitle, 'GRP_STATUS' => 'ACTIVE']
|
'conditions' => ['GRP_TITLE' => $groupTitle, 'GRP_STATUS' => 'ACTIVE']
|
||||||
);
|
);
|
||||||
$allGroups = $groupwf->show($filters);
|
$allGroups = $groupwf->show($filters);
|
||||||
$groupUid = $allGroups['data'][0]['GRP_UID'] ?? '';
|
$groupUid = '';
|
||||||
|
if (!empty($allGroups['data']) && isset($allGroups['data'][0]['GRP_UID'])) {
|
||||||
|
$groupUid = $allGroups['data'][0]['GRP_UID'];
|
||||||
|
}
|
||||||
|
|
||||||
if ($groupUid === '') {
|
if ($groupUid === '') {
|
||||||
$group = [
|
$group = [
|
||||||
@@ -419,9 +615,12 @@ class AuthSources
|
|||||||
'conditions' => ['GRP_TITLE' => $groupTitle, 'GRP_STATUS' => 'ACTIVE']
|
'conditions' => ['GRP_TITLE' => $groupTitle, 'GRP_STATUS' => 'ACTIVE']
|
||||||
);
|
);
|
||||||
$allGroups = $groupwf->show($filters);
|
$allGroups = $groupwf->show($filters);
|
||||||
$groupUid = $allGroups['data'][0]['GRP_UID'] ?? '';
|
$groupUid = '';
|
||||||
|
if (!empty($allGroups['data']) && isset($allGroups['data'][0]['GRP_UID'])) {
|
||||||
|
$groupUid = $allGroups['data'][0]['GRP_UID'];
|
||||||
|
}
|
||||||
|
|
||||||
if ($groupUid != '') {
|
if ($groupUid != '' && !empty($allGroups['data'])) {
|
||||||
$group = $allGroups['data'][0];
|
$group = $allGroups['data'][0];
|
||||||
$group['GRP_LDAP_DN'] = '';
|
$group['GRP_LDAP_DN'] = '';
|
||||||
$groupwf->saveData($group);
|
$groupwf->saveData($group);
|
||||||
@@ -437,18 +636,32 @@ class AuthSources
|
|||||||
$rbacAuthenticationSource->saveData($authenticationSourceData);
|
$rbacAuthenticationSource->saveData($authenticationSourceData);
|
||||||
}
|
}
|
||||||
|
|
||||||
$responseSaveGroups = [
|
return [
|
||||||
'status' => 'OK',
|
'status' => 'OK',
|
||||||
'success' => true
|
'success' => true
|
||||||
];
|
];
|
||||||
return $responseSaveGroups;
|
} catch (Exception $exception) {
|
||||||
|
return ['success' => false, 'message' => $exception->getMessage()];
|
||||||
if ($ldapSource->checkDuplicateTitles()) {
|
|
||||||
$response->warning = G::LoadTranslation('ID_IT_WAS_IDENTIFIED_DUPLICATED_GROUPS_PLEASE_REMOVE_THESE_GROUPS');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves department synchronization settings for an authentication source
|
||||||
|
*
|
||||||
|
* This method processes a list of LDAP organizational unit distinguished names
|
||||||
|
* to synchronize with the system. It creates new departments or updates existing
|
||||||
|
* ones while maintaining the hierarchical structure.
|
||||||
|
*
|
||||||
|
* @param string $departmentsDN Pipe-separated list of URL-encoded department distinguished names
|
||||||
|
* @param string $authSourceUid The unique identifier of the authentication source
|
||||||
|
*
|
||||||
|
* @return array Response array containing:
|
||||||
|
* - success: boolean indicating operation success
|
||||||
|
* - status: operation status ('OK' if successful)
|
||||||
|
* - message: error message if operation fails
|
||||||
|
*/
|
||||||
public function saveDepartments($departmentsDN, $authSourceUid) {
|
public function saveDepartments($departmentsDN, $authSourceUid) {
|
||||||
|
try {
|
||||||
$depsToCheck = ($departmentsDN != '') ? explode('|', $departmentsDN) : [];
|
$depsToCheck = ($departmentsDN != '') ? explode('|', $departmentsDN) : [];
|
||||||
$depsToCheck = array_map('urldecode', $depsToCheck);
|
$depsToCheck = array_map('urldecode', $depsToCheck);
|
||||||
|
|
||||||
@@ -457,6 +670,11 @@ class AuthSources
|
|||||||
$filters = ['conditions' => ['AUTH_SOURCE_UID'=> $authSourceUid]];
|
$filters = ['conditions' => ['AUTH_SOURCE_UID'=> $authSourceUid]];
|
||||||
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
||||||
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
||||||
|
|
||||||
|
if (empty($authSourceReturn['data']) || !isset($authSourceReturn['data'][0])) {
|
||||||
|
throw new Exception('Authentication source not found');
|
||||||
|
}
|
||||||
|
|
||||||
$authenticationSourceData = $authSourceReturn['data'][0];
|
$authenticationSourceData = $authSourceReturn['data'][0];
|
||||||
$authenticationSourceData['AUTH_SOURCE_DATA'] = json_decode($authenticationSourceData['AUTH_SOURCE_DATA'], true);
|
$authenticationSourceData['AUTH_SOURCE_DATA'] = json_decode($authenticationSourceData['AUTH_SOURCE_DATA'], true);
|
||||||
|
|
||||||
@@ -481,14 +699,11 @@ class AuthSources
|
|||||||
$parentUid = $department->getDepUidIfExistsDN($parentDn);
|
$parentUid = $department->getDepUidIfExistsDN($parentDn);
|
||||||
$parentUid = $parentUid['data'][0]['DEP_UID'] ?? '';
|
$parentUid = $parentUid['data'][0]['DEP_UID'] ?? '';
|
||||||
if (str_ireplace($authenticationSourceData['AUTH_SOURCE_BASE_DN'], '', $parentDn) != '' && $parentUid == '') {
|
if (str_ireplace($authenticationSourceData['AUTH_SOURCE_BASE_DN'], '', $parentDn) != '' && $parentUid == '') {
|
||||||
$response = new stdClass();
|
$errorMessage = G::LoadTranslation(
|
||||||
$response->status = 'ERROR';
|
|
||||||
$response->message = G::LoadTranslation(
|
|
||||||
'ID_DEPARTMENT_CHECK_PARENT_DEPARTMENT',
|
'ID_DEPARTMENT_CHECK_PARENT_DEPARTMENT',
|
||||||
[$parentDn, $departmentTitle]
|
[$parentDn, $departmentTitle]
|
||||||
);
|
);
|
||||||
echo json_encode($response);
|
throw new Exception($errorMessage);
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,7 +711,10 @@ class AuthSources
|
|||||||
'conditions' => ['DEP_STATUS' => 'ACTIVE', 'DEP_TITLE' => $departmentTitle]
|
'conditions' => ['DEP_STATUS' => 'ACTIVE', 'DEP_TITLE' => $departmentTitle]
|
||||||
);
|
);
|
||||||
$allDepartments = $department->show($filters);
|
$allDepartments = $department->show($filters);
|
||||||
$departmentUid = $allDepartments['data'][0]['DEP_UID'] ?? '';
|
$departmentUid = '';
|
||||||
|
if (!empty($allDepartments['data']) && isset($allDepartments['data'][0]['DEP_UID'])) {
|
||||||
|
$departmentUid = $allDepartments['data'][0]['DEP_UID'];
|
||||||
|
}
|
||||||
|
|
||||||
if (empty($departmentUid)) {
|
if (empty($departmentUid)) {
|
||||||
$data = [
|
$data = [
|
||||||
@@ -505,23 +723,20 @@ class AuthSources
|
|||||||
'DEP_LDAP_DN' => $departmentDn,
|
'DEP_LDAP_DN' => $departmentDn,
|
||||||
'DEP_REF_CODE' => ''
|
'DEP_REF_CODE' => ''
|
||||||
];
|
];
|
||||||
$saveDerpartment = $department->saveData($data);
|
$saveDepartment = $department->saveData($data);
|
||||||
|
|
||||||
if (empty($saveDerpartment)) {
|
if (empty($saveDepartment)) {
|
||||||
$response = new stdClass();
|
throw new Exception(G::LoadTranslation('ID_DEPARTMENT_ERROR_CREATE'));
|
||||||
$response->status = 'ERROR';
|
|
||||||
$response->message = G::LoadTranslation('ID_DEPARTMENT_ERROR_CREATE');
|
|
||||||
echo json_encode($response);
|
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (!empty($allDepartments['data'])) {
|
||||||
$data = $allDepartments['data'][0];
|
$data = $allDepartments['data'][0];
|
||||||
$data['DEP_LDAP_DN'] = $departmentDn;
|
$data['DEP_LDAP_DN'] = $departmentDn;
|
||||||
$department->saveData($data);
|
$department->saveData($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (count($depsToUncheck) > 0) {
|
if (count($depsToUncheck) > 0) {
|
||||||
$baseDnLength = strlen($authenticationSourceData['AUTH_SOURCE_BASE_DN']);
|
$baseDnLength = strlen($authenticationSourceData['AUTH_SOURCE_BASE_DN']);
|
||||||
@@ -553,24 +768,44 @@ class AuthSources
|
|||||||
$rbacAuthenticationSource->saveData($authenticationSourceData);
|
$rbacAuthenticationSource->saveData($authenticationSourceData);
|
||||||
}
|
}
|
||||||
|
|
||||||
$responseSaveGroups = [
|
return [
|
||||||
'status' => 'OK',
|
'status' => 'OK',
|
||||||
'success' => true
|
'success' => true
|
||||||
];
|
];
|
||||||
return $responseSaveGroups;
|
} catch (Exception $exception) {
|
||||||
|
return ['success' => false, 'message' => $exception->getMessage()];
|
||||||
if ($ldapAdvanced->checkDuplicateDepartmentTitles()) {
|
|
||||||
$response->warning = G::LoadTranslation('ID_IT_WAS_IDENTIFIED_DUPLICATED_DEPARTMENTS_PLEASE_REMOVE_THESE_DEPARTMENTS');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Filters and organizes departments based on parent-child relationships
|
||||||
|
*
|
||||||
|
* This private method processes a flat array of departments and returns
|
||||||
|
* only those that are direct children of the specified parent, excluding
|
||||||
|
* terminated organizational units. Returns empty array on error.
|
||||||
|
*
|
||||||
|
* @param array $departments Complete list of department data from LDAP
|
||||||
|
* @param string $parent Parent department distinguished name
|
||||||
|
* @param string $terminatedOu Name of the terminated organizational unit to exclude
|
||||||
|
*
|
||||||
|
* @return array Array of department objects that are children of the specified parent,
|
||||||
|
* empty array on error
|
||||||
|
*/
|
||||||
private function getDepartments($departments, $parent, $terminatedOu)
|
private function getDepartments($departments, $parent, $terminatedOu)
|
||||||
{
|
{
|
||||||
$parentDepartments = $departments;
|
try {
|
||||||
$childDepartments = $departments;
|
|
||||||
$currentDepartments = array();
|
$currentDepartments = array();
|
||||||
|
|
||||||
foreach ($parentDepartments as $key => $val) {
|
// Create hash map for O(1) parent-child lookups
|
||||||
|
$parentChildMap = [];
|
||||||
|
foreach ($departments as $dept) {
|
||||||
|
$parentKey = strtolower($dept['parent']);
|
||||||
|
if (!isset($parentChildMap[$parentKey])) {
|
||||||
|
$parentChildMap[$parentKey] = [];
|
||||||
|
}
|
||||||
|
$parentChildMap[$parentKey][] = $dept;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($departments as $key => $val) {
|
||||||
if (strtolower($val['dn']) != strtolower($parent)) {
|
if (strtolower($val['dn']) != strtolower($parent)) {
|
||||||
if ((strtolower($val['parent']) == strtolower($parent)) && (strtolower($val['ou']) != strtolower($terminatedOu))) {
|
if ((strtolower($val['parent']) == strtolower($parent)) && (strtolower($val['ou']) != strtolower($terminatedOu))) {
|
||||||
$node = array();
|
$node = array();
|
||||||
@@ -578,16 +813,10 @@ class AuthSources
|
|||||||
$node['DEP_TITLE'] = $val['ou'];
|
$node['DEP_TITLE'] = $val['ou'];
|
||||||
$node['DEP_USERS'] = $val['users'];
|
$node['DEP_USERS'] = $val['users'];
|
||||||
$node['DEP_DN'] = $val['dn'];
|
$node['DEP_DN'] = $val['dn'];
|
||||||
$node['HAS_CHILDREN'] = false;
|
|
||||||
$departments[$key]['hasChildren'] = false;
|
|
||||||
|
|
||||||
foreach ($childDepartments as $key2 => $val2) {
|
// Use hash map for O(1) lookup instead of nested loop
|
||||||
if (strtolower($val2['parent']) == strtolower($val['dn'])) {
|
$valDnKey = strtolower($val['dn']);
|
||||||
$node['HAS_CHILDREN'] = true;
|
$node['HAS_CHILDREN'] = isset($parentChildMap[$valDnKey]);
|
||||||
$departments[$key]['hasChildren'] = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$node['DEP_LAST'] = false;
|
$node['DEP_LAST'] = false;
|
||||||
$currentDepartments[] = $node;
|
$currentDepartments[] = $node;
|
||||||
@@ -595,17 +824,43 @@ class AuthSources
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($currentDepartments[count($currentDepartments) - 1])) {
|
$lastIndex = count($currentDepartments) - 1;
|
||||||
$currentDepartments[count($currentDepartments) - 1]['DEP_LAST'] = true;
|
if (isset($currentDepartments[$lastIndex])) {
|
||||||
|
$currentDepartments[$lastIndex]['DEP_LAST'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $currentDepartments;
|
return $currentDepartments;
|
||||||
|
} catch (Exception $exception) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively builds a hierarchical tree structure of departments
|
||||||
|
*
|
||||||
|
* This private method creates a tree representation of departments with
|
||||||
|
* user count information and synchronization status. It includes recursion
|
||||||
|
* depth protection to prevent infinite loops. Returns empty array on error.
|
||||||
|
*
|
||||||
|
* @param array $departments Complete list of department data from LDAP
|
||||||
|
* @param string $parent Parent department distinguished name (empty for root level)
|
||||||
|
* @param array $listDepartmentsNumberUsers Associative array of department UIDs and user counts
|
||||||
|
* @param string $terminatedOu Name of the terminated organizational unit to exclude
|
||||||
|
* @param int $depth Current recursion depth (default: 0, max: 50)
|
||||||
|
*
|
||||||
|
* @return TreeNodeAuthSource[] Array of TreeNodeAuthSource objects representing the department hierarchy,
|
||||||
|
* empty array on error or max depth reached
|
||||||
|
*/
|
||||||
|
private function getChildrenDepartments($departments, $parent, $listDepartmentsNumberUsers, $terminatedOu, $depth = 0) {
|
||||||
|
try {
|
||||||
|
if ($depth >= 50) {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getChildrenDepartments($departments, $parent, $listDepartmentsNumberUsers, $terminatedOu) {
|
|
||||||
$allDepartments = $this->getDepartments($departments, $parent, $terminatedOu);
|
$allDepartments = $this->getDepartments($departments, $parent, $terminatedOu);
|
||||||
|
|
||||||
$department = new Department();
|
$department = new Department();
|
||||||
|
$departmentsObjects = [];
|
||||||
foreach ($allDepartments as $departmentData) {
|
foreach ($allDepartments as $departmentData) {
|
||||||
$departmentObject = new TreeNodeAuthSource();
|
$departmentObject = new TreeNodeAuthSource();
|
||||||
$departmentObject->text = htmlentities($departmentData['DEP_TITLE'], ENT_QUOTES, 'UTF-8');
|
$departmentObject->text = htmlentities($departmentData['DEP_TITLE'], ENT_QUOTES, 'UTF-8');
|
||||||
@@ -614,116 +869,143 @@ class AuthSources
|
|||||||
$departmentUid = $departmentDNData['data'][0]['DEP_UID'] ?? '';
|
$departmentUid = $departmentDNData['data'][0]['DEP_UID'] ?? '';
|
||||||
|
|
||||||
if ($departmentUid != '') {
|
if ($departmentUid != '') {
|
||||||
$departmentObject->text .= ' (' . ($listDepartmentsNumberUsers[$departmentUid] ?? '') . ')';
|
$departmentObject->text .= ' (' . ($listDepartmentsNumberUsers[$departmentUid] ?? '0') . ')';
|
||||||
$departmentObject->checked = true;
|
$departmentObject->checked = true;
|
||||||
} else {
|
} else {
|
||||||
$departmentObject->checked = false;
|
$departmentObject->checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($departmentData['HAS_CHILDREN'] == 1) {
|
if ((int)$departmentData['HAS_CHILDREN'] == 1) {
|
||||||
$departmentObject->children = $this->getChildrenDepartments($departments, $departmentData['DEP_DN'], $listDepartmentsNumberUsers, $terminatedOu);
|
$departmentObject->children = $this->getChildrenDepartments($departments, $departmentData['DEP_DN'], $listDepartmentsNumberUsers, $terminatedOu, $depth + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$departmentObject->id = urlencode($departmentData['DEP_DN']);
|
$departmentObject->id = urlencode($departmentData['DEP_DN']);
|
||||||
$departmentsObjects[] = $departmentObject;
|
$departmentsObjects[] = $departmentObject;
|
||||||
}
|
}
|
||||||
return $departmentsObjects;
|
return $departmentsObjects;
|
||||||
|
} catch (Exception $exception) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifies departments that should be unsynchronized
|
||||||
|
*
|
||||||
|
* This private method compares currently synchronized departments with
|
||||||
|
* the new list of departments to synchronize, returning those that should
|
||||||
|
* be removed from synchronization. Returns empty array on error.
|
||||||
|
*
|
||||||
|
* @param array $depsToCheck Array of department distinguished names to keep synchronized
|
||||||
|
*
|
||||||
|
* @return array Array of department distinguished names to unsynchronize,
|
||||||
|
* empty array on error
|
||||||
|
*/
|
||||||
private function getDepartmentsToUncheck($depsToCheck)
|
private function getDepartmentsToUncheck($depsToCheck)
|
||||||
{
|
{
|
||||||
$departament = new Department();
|
try {
|
||||||
$departmentsWithDN = $departament->getDepartmentsWithDN();
|
$department = new Department();
|
||||||
$departmentsWithDN = $departmentsWithDN['data'];
|
$departmentsWithDN = $department->getDepartmentsWithDN();
|
||||||
|
$departmentsWithDN = $departmentsWithDN['data'] ?? [];
|
||||||
|
|
||||||
$depsToUncheck = [];
|
$depsToUncheck = [];
|
||||||
foreach ($departmentsWithDN as $departmentWithDN) {
|
foreach ($departmentsWithDN as $departmentWithDN) {
|
||||||
$found = false;
|
if (!in_array($departmentWithDN['DEP_LDAP_DN'], $depsToCheck)) {
|
||||||
|
|
||||||
foreach ($depsToCheck as $depToCheck) {
|
|
||||||
if ($departmentWithDN['DEP_LDAP_DN'] == $depToCheck) {
|
|
||||||
$found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$found) {
|
|
||||||
$depsToUncheck[] = $departmentWithDN['DEP_LDAP_DN'];
|
$depsToUncheck[] = $departmentWithDN['DEP_LDAP_DN'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $depsToUncheck;
|
return $depsToUncheck;
|
||||||
|
} catch (Exception $exception) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifies groups that should be unsynchronized
|
||||||
|
*
|
||||||
|
* This private method compares currently synchronized groups with
|
||||||
|
* the new list of groups to synchronize, returning those that should
|
||||||
|
* be removed from synchronization. Returns empty array on error.
|
||||||
|
*
|
||||||
|
* @param array $groupsToCheck Array of group distinguished names to keep synchronized
|
||||||
|
*
|
||||||
|
* @return array Array of group distinguished names to unsynchronize,
|
||||||
|
* empty array on error
|
||||||
|
*/
|
||||||
private function getGroupsToUncheck($groupsToCheck)
|
private function getGroupsToUncheck($groupsToCheck)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
$groupsWithDN = $this->getGroupsWithDN();
|
$groupsWithDN = $this->getGroupsWithDN();
|
||||||
$groupsToUncheck = array();
|
if (!is_array($groupsWithDN)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$groupsToUncheck = [];
|
||||||
foreach ($groupsWithDN as $groupWithDN) {
|
foreach ($groupsWithDN as $groupWithDN) {
|
||||||
$found = false;
|
if (!in_array($groupWithDN['GRP_LDAP_DN'], $groupsToCheck)) {
|
||||||
|
|
||||||
foreach ($groupsToCheck as $groupToCheck) {
|
|
||||||
if ($groupWithDN['GRP_LDAP_DN'] == $groupToCheck) {
|
|
||||||
$found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$found) {
|
|
||||||
$groupsToUncheck[] = $groupWithDN['GRP_LDAP_DN'];
|
$groupsToUncheck[] = $groupWithDN['GRP_LDAP_DN'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $groupsToUncheck;
|
return $groupsToUncheck;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all groups that have LDAP distinguished names
|
||||||
|
*
|
||||||
|
* This private method fetches all system groups that are currently
|
||||||
|
* synchronized with LDAP (have non-empty LDAP DN values).
|
||||||
|
* Uses a high limit (100,000) which may cause performance issues with large datasets.
|
||||||
|
*
|
||||||
|
* @return array Array of group data with LDAP distinguished names,
|
||||||
|
* empty array on error
|
||||||
|
*
|
||||||
|
* @warning High limit of 100,000 records may cause memory issues
|
||||||
|
*/
|
||||||
private function getGroupsWithDN()
|
private function getGroupsWithDN()
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
$groupwf = new Groupwf();
|
$groupwf = new Groupwf();
|
||||||
$filters = array('start' => 0, 'limit' => 1000);
|
$filters = [
|
||||||
|
'start' => 0, 'limit' => 100000,
|
||||||
|
'conditions' => ['GRP_LDAP_DN' => ['!=', '']]
|
||||||
|
];
|
||||||
$allGroups = $groupwf->show($filters);
|
$allGroups = $groupwf->show($filters);
|
||||||
$allGroups = $allGroups['data'];
|
return $allGroups['data'] ?? [];
|
||||||
$groupsWithDN = array();
|
} catch (Exception $exception) {
|
||||||
|
return [];
|
||||||
foreach ($allGroups as $group) {
|
|
||||||
if ($group['GRP_LDAP_DN'] != '') {
|
|
||||||
$groupsWithDN[] = $group;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $groupsWithDN;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function encrypt($plaintext, $key) {
|
|
||||||
$cipher = 'AES-256-CBC';
|
|
||||||
$ivlen = openssl_cipher_iv_length($cipher);
|
|
||||||
$iv = openssl_random_pseudo_bytes($ivlen);
|
|
||||||
|
|
||||||
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
|
|
||||||
|
|
||||||
$ciphertext = base64_encode($iv . $ciphertext_raw);
|
|
||||||
return $ciphertext;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function decrypt($ciphertext_b64, $key) {
|
|
||||||
$cipher = 'AES-256-CBC';
|
|
||||||
$ivlen = openssl_cipher_iv_length($cipher);
|
|
||||||
|
|
||||||
$ciphertext = base64_decode($ciphertext_b64);
|
|
||||||
$iv = substr($ciphertext, 0, $ivlen);
|
|
||||||
$ciphertext_raw = substr($ciphertext, $ivlen);
|
|
||||||
|
|
||||||
$plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, OPENSSL_RAW_DATA, $iv);
|
|
||||||
return $plaintext;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class TreeNodeAuthSource extends stdclass
|
/**
|
||||||
|
* TreeNodeAuthSource Class
|
||||||
|
*
|
||||||
|
* This class represents a node in a tree structure used for displaying
|
||||||
|
* authentication source hierarchical data (groups and departments).
|
||||||
|
* It extends stdClass to provide a flexible object structure for tree rendering.
|
||||||
|
*
|
||||||
|
* @package Lurana\Workflow\Engine\Classes
|
||||||
|
*/
|
||||||
|
class TreeNodeAuthSource extends stdClass
|
||||||
{
|
{
|
||||||
|
/** @var string Display text for the tree node */
|
||||||
public $text = '';
|
public $text = '';
|
||||||
|
|
||||||
|
/** @var string CSS class for styling the tree node */
|
||||||
public $cls = '';
|
public $cls = '';
|
||||||
|
|
||||||
|
/** @var bool Indicates if this is a leaf node (no children) */
|
||||||
public $leaf = false;
|
public $leaf = false;
|
||||||
|
|
||||||
|
/** @var bool Indicates if this node is selected/checked */
|
||||||
public $checked = false;
|
public $checked = false;
|
||||||
|
|
||||||
|
/** @var array Array of child TreeNodeAuthSource objects */
|
||||||
public $children = array();
|
public $children = array();
|
||||||
|
|
||||||
|
/** @var string Unique identifier for the tree node */
|
||||||
public $id = '';
|
public $id = '';
|
||||||
}
|
}
|
||||||
@@ -8,10 +8,6 @@ use ProcessMaker\BusinessModel\User;
|
|||||||
use ProcessMaker\Model\Department;
|
use ProcessMaker\Model\Department;
|
||||||
use ProcessMaker\Model\Groupwf;
|
use ProcessMaker\Model\Groupwf;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class LdapAdvanced
|
|
||||||
*/
|
|
||||||
class LdapSource
|
class LdapSource
|
||||||
{
|
{
|
||||||
public $authSourceUid;
|
public $authSourceUid;
|
||||||
@@ -31,19 +27,17 @@ class LdapSource
|
|||||||
|
|
||||||
private $arrayAttributesForUser = ["dn", "uid", "samaccountname", "givenname", "sn", "cn", "mail", "userprincipalname", "useraccountcontrol", "accountexpires", "manager"];
|
private $arrayAttributesForUser = ["dn", "uid", "samaccountname", "givenname", "sn", "cn", "mail", "userprincipalname", "useraccountcontrol", "accountexpires", "manager"];
|
||||||
|
|
||||||
public function ldapConnection($authSourceData) {
|
public function __destruct() {
|
||||||
$pass = explode('_', $authSourceData['AUTH_SOURCE_PASSWORD']);
|
if ($this->ldapcnn) {
|
||||||
|
@ldap_close($this->ldapcnn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ldapConnection($authSourceData) {
|
||||||
// Removing sensitive data
|
// Removing sensitive data
|
||||||
$loggableAuthSource = $authSourceData;
|
$loggableAuthSource = $authSourceData;
|
||||||
unset($loggableAuthSource['AUTH_SOURCE_PASSWORD']);
|
unset($loggableAuthSource['AUTH_SOURCE_PASSWORD']);
|
||||||
|
|
||||||
foreach ($pass as $index => $value) {
|
|
||||||
if ($value == '2NnV3ujj3w') {
|
|
||||||
$authSourceData['AUTH_SOURCE_PASSWORD'] = G::decrypt($pass[0], $authSourceData['AUTH_SOURCE_SERVER_NAME']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$ldapcnn = ldap_connect($authSourceData['AUTH_SOURCE_SERVER_NAME'], $authSourceData['AUTH_SOURCE_PORT']);
|
$ldapcnn = ldap_connect($authSourceData['AUTH_SOURCE_SERVER_NAME'], $authSourceData['AUTH_SOURCE_PORT']);
|
||||||
$this->stdLog($ldapcnn, 'ldap_connect', $loggableAuthSource);
|
$this->stdLog($ldapcnn, 'ldap_connect', $loggableAuthSource);
|
||||||
|
|
||||||
@@ -74,7 +68,7 @@ class LdapSource
|
|||||||
$message = 'Unable to bind to server: ' . $ldapServer . 'LDAP-Errno: ' . ldap_errno($ldapcnn) . ' : ' . ldap_error($ldapcnn) . " \n";
|
$message = 'Unable to bind to server: ' . $ldapServer . 'LDAP-Errno: ' . ldap_errno($ldapcnn) . ' : ' . ldap_error($ldapcnn) . " \n";
|
||||||
throw new Exception($message);
|
throw new Exception($message);
|
||||||
}
|
}
|
||||||
|
$this->ldapcnn = $ldapcnn;
|
||||||
return ['connection' =>$ldapcnn, 'startTLS' => $resultLDAPStartTLS];
|
return ['connection' =>$ldapcnn, 'startTLS' => $resultLDAPStartTLS];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,22 +76,21 @@ class LdapSource
|
|||||||
try {
|
try {
|
||||||
$arrayGroup = [];
|
$arrayGroup = [];
|
||||||
|
|
||||||
$rbac = RBAC::getSingleton();
|
$filters = ['conditions' => ['AUTH_SOURCE_UID'=> $this->authSourceUid]];
|
||||||
|
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
||||||
if (is_null($rbac->authSourcesObj)) {
|
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
||||||
$rbac->authSourcesObj = new AuthenticationSource();
|
$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);
|
||||||
$arrayAuthenticationSourceData = $rbac->authSourcesObj->load($this->authSourceUid);
|
|
||||||
|
|
||||||
if (is_null($this->ldapcnn)) {
|
if (is_null($this->ldapcnn)) {
|
||||||
$ldapcnn = $this->ldapConnection($arrayAuthenticationSourceData);
|
$ldapcnn = $this->ldapConnection($authenticationSourceData);
|
||||||
$this->ldapcnn = $ldapcnn['connection'];
|
$this->ldapcnn = $ldapcnn['connection'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$ldapcnn = $this->ldapcnn;
|
$ldapcnn = $this->ldapcnn;
|
||||||
// Get Groups
|
// Get Groups
|
||||||
$limit = $this->getPageSizeLimitByData($arrayAuthenticationSourceData);
|
$limit = $this->getPageSizeLimitByData($authenticationSourceData);
|
||||||
$flagError = false;
|
$flagError = false;
|
||||||
$filter = '(' . $this->arrayObjectClassFilter['group'] . ')';
|
$filter = '(' . $this->arrayObjectClassFilter['group'] . ')';
|
||||||
$this->log($ldapcnn, 'search groups with Filter: ' . $filter);
|
$this->log($ldapcnn, 'search groups with Filter: ' . $filter);
|
||||||
@@ -106,7 +99,7 @@ class LdapSource
|
|||||||
do {
|
do {
|
||||||
$searchResult = @ldap_search(
|
$searchResult = @ldap_search(
|
||||||
$ldapcnn,
|
$ldapcnn,
|
||||||
$arrayAuthenticationSourceData['AUTH_SOURCE_BASE_DN'],
|
$authenticationSourceData['AUTH_SOURCE_BASE_DN'],
|
||||||
$filter,
|
$filter,
|
||||||
['dn', 'cn'],
|
['dn', 'cn'],
|
||||||
0,
|
0,
|
||||||
@@ -119,7 +112,7 @@ class LdapSource
|
|||||||
$this->stdLog($ldapcnn, "ldap_search", ["filter" => $filter, "attributes" => ['dn', 'cn']]);
|
$this->stdLog($ldapcnn, "ldap_search", ["filter" => $filter, "attributes" => ['dn', 'cn']]);
|
||||||
|
|
||||||
$context = [
|
$context = [
|
||||||
"baseDN" => $arrayAuthenticationSourceData['AUTH_SOURCE_BASE_DN'],
|
"baseDN" => $authenticationSourceData['AUTH_SOURCE_BASE_DN'],
|
||||||
"filter" => $filter,
|
"filter" => $filter,
|
||||||
"attributes" => ['dn', 'cn']
|
"attributes" => ['dn', 'cn']
|
||||||
];
|
];
|
||||||
@@ -172,7 +165,6 @@ class LdapSource
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->log($ldapcnn, 'found ' . count($arrayGroup) . ' groups: ' . $str);
|
$this->log($ldapcnn, 'found ' . count($arrayGroup) . ' groups: ' . $str);
|
||||||
|
|
||||||
return $arrayGroup;
|
return $arrayGroup;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
throw $e;
|
throw $e;
|
||||||
@@ -187,6 +179,8 @@ class LdapSource
|
|||||||
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
||||||
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
||||||
$authenticationSourceData = $authSourceReturn['data'][0];
|
$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)) {
|
if (is_null($this->ldapcnn)) {
|
||||||
$ldapcnn = $this->ldapConnection($authenticationSourceData);
|
$ldapcnn = $this->ldapConnection($authenticationSourceData);
|
||||||
@@ -290,7 +284,6 @@ class LdapSource
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->log($ldapcnn, 'found ' . count($arrayDepartment) . ' departments: ' . $str);
|
$this->log($ldapcnn, 'found ' . count($arrayDepartment) . ' departments: ' . $str);
|
||||||
|
|
||||||
return $arrayDepartment;
|
return $arrayDepartment;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
throw $e;
|
throw $e;
|
||||||
@@ -459,6 +452,7 @@ class LdapSource
|
|||||||
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
||||||
$arrayAuthenticationSourceData = $authSourceReturn['data'][0];
|
$arrayAuthenticationSourceData = $authSourceReturn['data'][0];
|
||||||
$arrayAuthenticationSourceData['AUTH_SOURCE_DATA'] = json_decode($arrayAuthenticationSourceData['AUTH_SOURCE_DATA'], true);
|
$arrayAuthenticationSourceData['AUTH_SOURCE_DATA'] = json_decode($arrayAuthenticationSourceData['AUTH_SOURCE_DATA'], true);
|
||||||
|
$arrayAuthenticationSourceData['AUTH_SOURCE_PASSWORD'] = G::decrypt($arrayAuthenticationSourceData['AUTH_SOURCE_PASSWORD'], URL_KEY);
|
||||||
|
|
||||||
$attributeUserSet = [];
|
$attributeUserSet = [];
|
||||||
$attributeSetAdd = [];
|
$attributeSetAdd = [];
|
||||||
@@ -512,39 +506,6 @@ class LdapSource
|
|||||||
|
|
||||||
if ((is_array($sUsername) && !empty($sUsername)) || trim($sUsername) != '') {
|
if ((is_array($sUsername) && !empty($sUsername)) || trim($sUsername) != '') {
|
||||||
$countUser++;
|
$countUser++;
|
||||||
|
|
||||||
/* Active Directory userAccountControl Values
|
|
||||||
Normal Day to Day Values:
|
|
||||||
512 - Enable Account
|
|
||||||
514 - Disable account
|
|
||||||
544 - Account Enabled - Require user to change password at first logon
|
|
||||||
4096 - Workstation/server
|
|
||||||
66048 - Enabled, password never expires
|
|
||||||
66050 - Disabled, password never expires
|
|
||||||
262656 - Smart Card Logon Required
|
|
||||||
532480 - Domain controller
|
|
||||||
1 - script
|
|
||||||
2 - accountdisable
|
|
||||||
8 - homedir_required
|
|
||||||
16 - lockout
|
|
||||||
32 - passwd_notreqd
|
|
||||||
64 - passwd_cant_change
|
|
||||||
128 - encrypted_text_pwd_allowed
|
|
||||||
256 - temp_duplicate_account
|
|
||||||
512 - normal_account
|
|
||||||
2048 - interdomain_trust_account
|
|
||||||
4096 - workstation_trust_account
|
|
||||||
8192 - server_trust_account
|
|
||||||
65536 - dont_expire_password
|
|
||||||
131072 - mns_logon_account
|
|
||||||
262144 - smartcard_required
|
|
||||||
524288 - trusted_for_delegation
|
|
||||||
1048576 - not_delegated
|
|
||||||
2097152 - use_des_key_only
|
|
||||||
4194304 - dont_req_preauth
|
|
||||||
8388608 - password_expired
|
|
||||||
16777216 - trusted_to_auth_for_delegation
|
|
||||||
*/
|
|
||||||
$userCountControl = '';
|
$userCountControl = '';
|
||||||
//Active Directory, openLdap
|
//Active Directory, openLdap
|
||||||
if (isset($aAttr['useraccountcontrol'])) {
|
if (isset($aAttr['useraccountcontrol'])) {
|
||||||
@@ -598,7 +559,6 @@ class LdapSource
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ($paged) ? ['numRecTotal' => $totalUser, 'data' => $arrayUser] : $arrayUser;
|
return ($paged) ? ['numRecTotal' => $totalUser, 'data' => $arrayUser] : $arrayUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,41 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentication Sources Proxy
|
||||||
|
*
|
||||||
|
* This script serves as a proxy handler for authentication source operations.
|
||||||
|
* It processes various AJAX requests related to LDAP/Active Directory authentication
|
||||||
|
* sources management including listing, creating, updating, deleting, testing
|
||||||
|
* connections, and importing users/groups/departments.
|
||||||
|
*
|
||||||
|
* @author Lurana System
|
||||||
|
* @version 1.0
|
||||||
|
* @package Workflow Engine
|
||||||
|
* @subpackage Authentication Sources
|
||||||
|
*/
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Validate that an action parameter was provided in the request
|
||||||
if (isset($_REQUEST['action']) === false) {
|
if (isset($_REQUEST['action']) === false) {
|
||||||
throw new Exception('No action was sent');
|
throw new Exception('No action was sent');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure user is authenticated before processing any requests
|
||||||
if (isset($_SESSION['USER_LOGGED']) === false) {
|
if (isset($_SESSION['USER_LOGGED']) === false) {
|
||||||
throw new Exception('There is no logged in user');
|
throw new Exception('There is no logged in user');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extract request parameters and initialize response structure
|
||||||
$action = $_REQUEST['action'];
|
$action = $_REQUEST['action'];
|
||||||
$userUid = $_SESSION['USER_LOGGED'];
|
$userUid = $_SESSION['USER_LOGGED'];
|
||||||
$responseProxy = ['success' => true];
|
$responseProxy = ['success' => true];
|
||||||
|
|
||||||
|
// Process the requested action using a switch statement
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
|
/**
|
||||||
|
* Retrieve a paginated list of authentication sources
|
||||||
|
* Parameters: start, limit, textFilter, orderBy, ascending
|
||||||
|
*/
|
||||||
case 'authSourcesList':
|
case 'authSourcesList':
|
||||||
$start = $_REQUEST['start'] ?? 0;
|
$start = $_REQUEST['start'] ?? 0;
|
||||||
$limit = $_REQUEST['limit'] ?? 25;
|
$limit = $_REQUEST['limit'] ?? 25;
|
||||||
@@ -24,6 +46,10 @@ try {
|
|||||||
$authSources = new AuthSources();
|
$authSources = new AuthSources();
|
||||||
$responseProxy = $authSources->getListAuthSources($userUid, $start, $limit, $orderBy, $ascending, $filter);
|
$responseProxy = $authSources->getListAuthSources($userUid, $start, $limit, $orderBy, $ascending, $filter);
|
||||||
break;
|
break;
|
||||||
|
/**
|
||||||
|
* Delete an authentication source by its UID
|
||||||
|
* Required parameter: auth_uid
|
||||||
|
*/
|
||||||
case 'authSourcesDelete':
|
case 'authSourcesDelete':
|
||||||
if (!isset($_REQUEST['auth_uid'])) {
|
if (!isset($_REQUEST['auth_uid'])) {
|
||||||
throw new Exception('No auth source UID was sent');
|
throw new Exception('No auth source UID was sent');
|
||||||
@@ -32,16 +58,30 @@ try {
|
|||||||
$authSources = new AuthSources();
|
$authSources = new AuthSources();
|
||||||
$responseProxy = $authSources->removeAuthSource($authSourceUid);
|
$responseProxy = $authSources->removeAuthSource($authSourceUid);
|
||||||
break;
|
break;
|
||||||
|
/**
|
||||||
|
* Verify if an authentication source name is unique/available
|
||||||
|
* Required parameter: AUTH_SOURCE_NAME
|
||||||
|
*/
|
||||||
case 'authSourcesVerifyName':
|
case 'authSourcesVerifyName':
|
||||||
if (empty($_REQUEST['AUTH_SOURCE_NAME'])) {
|
if (empty($_REQUEST['AUTH_SOURCE_NAME'])) {
|
||||||
throw new Exception('No auth source UID was sent');
|
throw new Exception('No auth source name was sent');
|
||||||
}
|
}
|
||||||
|
|
||||||
$authSourceName = $_REQUEST['AUTH_SOURCE_NAME'];
|
$authSourceName = $_REQUEST['AUTH_SOURCE_NAME'];
|
||||||
$authSources = new AuthSources();
|
$authSources = new AuthSources();
|
||||||
$responseProxy = $authSources->verifyAuthSourceName($authSourceName);
|
$responseProxy = $authSources->verifyAuthSourceName($authSourceName);
|
||||||
break;
|
break;
|
||||||
|
/**
|
||||||
|
* Test connection to an authentication source (LDAP/AD)
|
||||||
|
* Required parameter: AUTH_ANONYMOUS
|
||||||
|
* If anonymous auth is enabled, clears username and password
|
||||||
|
*/
|
||||||
case 'authSourcesTestConnection':
|
case 'authSourcesTestConnection':
|
||||||
|
if (isset($_REQUEST['AUTH_ANONYMOUS']) === false) {
|
||||||
|
throw new Exception('No auth anonymous was sent');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear credentials if anonymous authentication is enabled
|
||||||
if ($_REQUEST['AUTH_ANONYMOUS'] == '1') {
|
if ($_REQUEST['AUTH_ANONYMOUS'] == '1') {
|
||||||
$_REQUEST['AUTH_SOURCE_SEARCH_USER'] = '';
|
$_REQUEST['AUTH_SOURCE_SEARCH_USER'] = '';
|
||||||
$_REQUEST['AUTH_SOURCE_PASSWORD'] = '';
|
$_REQUEST['AUTH_SOURCE_PASSWORD'] = '';
|
||||||
@@ -53,12 +93,19 @@ try {
|
|||||||
$authSources = new AuthSources();
|
$authSources = new AuthSources();
|
||||||
$responseProxy = $authSources->testConnection($authSourceData);
|
$responseProxy = $authSources->testConnection($authSourceData);
|
||||||
break;
|
break;
|
||||||
|
/**
|
||||||
|
* Save (create or update) an authentication source configuration
|
||||||
|
* Processes form data, separates common fields from extra data,
|
||||||
|
* and handles grid attributes if enabled
|
||||||
|
*/
|
||||||
case 'authSourcesSave':
|
case 'authSourcesSave':
|
||||||
$temporalData = $_REQUEST;
|
$temporalData = $_REQUEST;
|
||||||
|
|
||||||
|
// Process grid attributes if the show grid checkbox is enabled
|
||||||
if (isset($temporalData['AUTH_SOURCE_SHOWGRID-checkbox'])) {
|
if (isset($temporalData['AUTH_SOURCE_SHOWGRID-checkbox'])) {
|
||||||
if ($temporalData['AUTH_SOURCE_SHOWGRID-checkbox'] == 'on') {
|
if ($temporalData['AUTH_SOURCE_SHOWGRID-checkbox'] == 'on') {
|
||||||
$temporalData['AUTH_SOURCE_SHOWGRID'] = 'on';
|
$temporalData['AUTH_SOURCE_SHOWGRID'] = 'on';
|
||||||
|
// Parse JSON grid attributes and convert to array format
|
||||||
$attributes = G::json_decode($temporalData['AUTH_SOURCE_GRID_TEXT']);
|
$attributes = G::json_decode($temporalData['AUTH_SOURCE_GRID_TEXT']);
|
||||||
$con = 1;
|
$con = 1;
|
||||||
foreach ($attributes as $value) {
|
foreach ($attributes as $value) {
|
||||||
@@ -69,20 +116,19 @@ try {
|
|||||||
unset($temporalData['AUTH_SOURCE_SHOWGRID-checkbox']);
|
unset($temporalData['AUTH_SOURCE_SHOWGRID-checkbox']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear credentials for anonymous authentication
|
||||||
if ($temporalData['AUTH_ANONYMOUS'] == '1') {
|
if ($temporalData['AUTH_ANONYMOUS'] == '1') {
|
||||||
$temporalData['AUTH_SOURCE_SEARCH_USER'] = '';
|
$temporalData['AUTH_SOURCE_SEARCH_USER'] = '';
|
||||||
$temporalData['AUTH_SOURCE_PASSWORD'] = '';
|
$temporalData['AUTH_SOURCE_PASSWORD'] = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($temporalData['AUTH_SOURCE_GRID_TEXT']);
|
unset($temporalData['AUTH_SOURCE_GRID_TEXT']);
|
||||||
unset($temporalData['DELETE1']);
|
|
||||||
unset($temporalData['DELETE2']);
|
|
||||||
unset($temporalData['AUTH_SOURCE_ATTRIBUTE_IDS']);
|
unset($temporalData['AUTH_SOURCE_ATTRIBUTE_IDS']);
|
||||||
unset($temporalData['AUTH_SOURCE_SHOWGRID_FLAG']);
|
|
||||||
unset($temporalData['AUTH_SOURCE_GRID_TEXT']);
|
|
||||||
|
|
||||||
|
// Define core authentication source fields
|
||||||
$commonFields = array('AUTH_SOURCE_UID', 'AUTH_SOURCE_NAME', 'AUTH_SOURCE_PROVIDER', 'AUTH_SOURCE_SERVER_NAME', 'AUTH_SOURCE_PORT', 'AUTH_SOURCE_ENABLED_TLS', 'AUTH_ANONYMOUS', 'AUTH_SOURCE_SEARCH_USER', 'AUTH_SOURCE_PASSWORD', 'AUTH_SOURCE_VERSION', 'AUTH_SOURCE_BASE_DN', 'AUTH_SOURCE_OBJECT_CLASSES', 'AUTH_SOURCE_ATTRIBUTES');
|
$commonFields = array('AUTH_SOURCE_UID', 'AUTH_SOURCE_NAME', 'AUTH_SOURCE_PROVIDER', 'AUTH_SOURCE_SERVER_NAME', 'AUTH_SOURCE_PORT', 'AUTH_SOURCE_ENABLED_TLS', 'AUTH_ANONYMOUS', 'AUTH_SOURCE_SEARCH_USER', 'AUTH_SOURCE_PASSWORD', 'AUTH_SOURCE_VERSION', 'AUTH_SOURCE_BASE_DN', 'AUTH_SOURCE_OBJECT_CLASSES', 'AUTH_SOURCE_ATTRIBUTES');
|
||||||
|
|
||||||
|
// Separate common fields from extra configuration data
|
||||||
$authSourceData = $authSourceExtraData = array();
|
$authSourceData = $authSourceExtraData = array();
|
||||||
foreach ($temporalData as $sField => $sValue) {
|
foreach ($temporalData as $sField => $sValue) {
|
||||||
if (in_array($sField, $commonFields)) {
|
if (in_array($sField, $commonFields)) {
|
||||||
@@ -92,6 +138,7 @@ try {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove grid attributes if grid display is disabled
|
||||||
if (!isset($authSourceExtraData['AUTH_SOURCE_SHOWGRID']) || $authSourceExtraData['AUTH_SOURCE_SHOWGRID'] == 'off') {
|
if (!isset($authSourceExtraData['AUTH_SOURCE_SHOWGRID']) || $authSourceExtraData['AUTH_SOURCE_SHOWGRID'] == 'off') {
|
||||||
unset($authSourceExtraData['AUTH_SOURCE_GRID_ATTRIBUTE']);
|
unset($authSourceExtraData['AUTH_SOURCE_GRID_ATTRIBUTE']);
|
||||||
unset($authSourceExtraData['AUTH_SOURCE_SHOWGRID']);
|
unset($authSourceExtraData['AUTH_SOURCE_SHOWGRID']);
|
||||||
@@ -102,12 +149,18 @@ try {
|
|||||||
$authSources = new AuthSources();
|
$authSources = new AuthSources();
|
||||||
$responseProxy = $authSources->saveAuthSource($authSourceData);
|
$responseProxy = $authSources->saveAuthSource($authSourceData);
|
||||||
break;
|
break;
|
||||||
|
/**
|
||||||
|
* Search for users in an authentication source for import
|
||||||
|
* Required parameter: sUID (auth source UID)
|
||||||
|
* Optional parameters: start, limit/pageSize, sKeyword
|
||||||
|
*/
|
||||||
case 'authSourcesImportSearchUsers':
|
case 'authSourcesImportSearchUsers':
|
||||||
if (!isset($_REQUEST['sUID'])) {
|
if (!isset($_POST['sUID'])) {
|
||||||
throw new Exception('No auth source UID was sent');
|
throw new Exception('No auth source UID was sent');
|
||||||
}
|
}
|
||||||
|
|
||||||
$authSourceUid = $_POST['sUID'];
|
$authSourceUid = $_POST['sUID'];
|
||||||
|
// Set up search filters with default values
|
||||||
$filters = [
|
$filters = [
|
||||||
'start'=> $_POST['start'] ?? 0,
|
'start'=> $_POST['start'] ?? 0,
|
||||||
'limit'=> $_POST['limit'] ?? ($_POST['pageSize'] ?? 10),
|
'limit'=> $_POST['limit'] ?? ($_POST['pageSize'] ?? 10),
|
||||||
@@ -117,6 +170,10 @@ try {
|
|||||||
$authSources = new AuthSources();
|
$authSources = new AuthSources();
|
||||||
$responseProxy = $authSources->searchUsers($authSourceUid, $filters);
|
$responseProxy = $authSources->searchUsers($authSourceUid, $filters);
|
||||||
break;
|
break;
|
||||||
|
/**
|
||||||
|
* Import selected users from an authentication source
|
||||||
|
* Required parameters: UsersImport (JSON), AUTH_SOURCE_UID
|
||||||
|
*/
|
||||||
case 'authSourcesImportUsers':
|
case 'authSourcesImportUsers':
|
||||||
if (!isset($_REQUEST['UsersImport'])) {
|
if (!isset($_REQUEST['UsersImport'])) {
|
||||||
throw new Exception('There are no users to import');
|
throw new Exception('There are no users to import');
|
||||||
@@ -128,11 +185,16 @@ try {
|
|||||||
|
|
||||||
$authSourceUid = $_REQUEST['AUTH_SOURCE_UID'];
|
$authSourceUid = $_REQUEST['AUTH_SOURCE_UID'];
|
||||||
$usersImport = $_REQUEST['UsersImport'];
|
$usersImport = $_REQUEST['UsersImport'];
|
||||||
|
// Decode JSON list of users to import
|
||||||
$usersImport = json_decode($usersImport, true);
|
$usersImport = json_decode($usersImport, true);
|
||||||
|
|
||||||
$authSources = new AuthSources();
|
$authSources = new AuthSources();
|
||||||
$responseProxy = $authSources->importUsers($authSourceUid, $usersImport);
|
$responseProxy = $authSources->importUsers($authSourceUid, $usersImport);
|
||||||
break;
|
break;
|
||||||
|
/**
|
||||||
|
* Load/search departments from an authentication source
|
||||||
|
* Required parameter: authUid (auth source UID)
|
||||||
|
*/
|
||||||
case 'authSourcesImportLoadDepartment':
|
case 'authSourcesImportLoadDepartment':
|
||||||
if (!isset($_REQUEST['authUid'])) {
|
if (!isset($_REQUEST['authUid'])) {
|
||||||
throw new Exception('No auth source UID was sent');
|
throw new Exception('No auth source UID was sent');
|
||||||
@@ -140,14 +202,22 @@ try {
|
|||||||
|
|
||||||
$authSourceUid = $_REQUEST['authUid'];
|
$authSourceUid = $_REQUEST['authUid'];
|
||||||
$authSources = new AuthSources();
|
$authSources = new AuthSources();
|
||||||
$responseProxy = $authSources->searchDepartaments($authSourceUid);
|
$responseProxy = $authSources->searchDepartments($authSourceUid);
|
||||||
break;
|
break;
|
||||||
|
/**
|
||||||
|
* Save/import selected departments from an authentication source
|
||||||
|
* Required parameters: departmentsDN, authUid
|
||||||
|
*/
|
||||||
case 'authSourcesImportSaveDepartment':
|
case 'authSourcesImportSaveDepartment':
|
||||||
$authSources = new AuthSources();
|
$authSources = new AuthSources();
|
||||||
$departmentsDN = $_REQUEST['departmentsDN'];
|
$departmentsDN = $_REQUEST['departmentsDN'];
|
||||||
$authSourceUid = $_REQUEST['authUid'];
|
$authSourceUid = $_REQUEST['authUid'];
|
||||||
$responseProxy = $authSources->saveDepartments($departmentsDN, $authSourceUid);
|
$responseProxy = $authSources->saveDepartments($departmentsDN, $authSourceUid);
|
||||||
break;
|
break;
|
||||||
|
/**
|
||||||
|
* Load/search groups from an authentication source
|
||||||
|
* Required parameter: authUid (auth source UID)
|
||||||
|
*/
|
||||||
case 'authSourcesImportLoadGroup':
|
case 'authSourcesImportLoadGroup':
|
||||||
if (!isset($_REQUEST['authUid'])) {
|
if (!isset($_REQUEST['authUid'])) {
|
||||||
throw new Exception('No auth source UID was sent');
|
throw new Exception('No auth source UID was sent');
|
||||||
@@ -157,23 +227,31 @@ try {
|
|||||||
$authSources = new AuthSources();
|
$authSources = new AuthSources();
|
||||||
$responseProxy = $authSources->searchGroups($authSourceUid);
|
$responseProxy = $authSources->searchGroups($authSourceUid);
|
||||||
break;
|
break;
|
||||||
|
/**
|
||||||
|
* Save/import selected groups from an authentication source
|
||||||
|
* Required parameters: groupsDN, authUid
|
||||||
|
*/
|
||||||
case 'authSourcesImportSaveGroup':
|
case 'authSourcesImportSaveGroup':
|
||||||
$authSources = new AuthSources();
|
$authSources = new AuthSources();
|
||||||
$groupsDN = $_REQUEST['groupsDN'];
|
$groupsDN = $_REQUEST['groupsDN'];
|
||||||
$authSourceUid = $_REQUEST['authUid'];
|
$authSourceUid = $_REQUEST['authUid'];
|
||||||
$responseProxy = $authSources->saveGroups($groupsDN, $authSourceUid);
|
$responseProxy = $authSources->saveGroups($groupsDN, $authSourceUid);
|
||||||
break;
|
break;
|
||||||
|
/**
|
||||||
|
* Handle invalid/unknown actions
|
||||||
|
*/
|
||||||
default:
|
default:
|
||||||
throw new Exception('The action "' . $action . '" is not allowed');
|
throw new Exception('The action "' . $action . '" is not allowed');
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return successful response as JSON
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
echo json_encode($responseProxy, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
echo json_encode($responseProxy, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
|
// Handle any exceptions and return error response
|
||||||
$responseProxy['success'] = false;
|
$responseProxy['success'] = false;
|
||||||
$responseProxy['message'] = htmlentities($exception->getMessage(), ENT_QUOTES, 'UTF-8');
|
$responseProxy['message'] = 'An error occurred while processing your request: ';
|
||||||
|
$responseProxy['message'] .= htmlentities($exception->getMessage(), ENT_QUOTES, 'UTF-8');
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
echo json_encode($responseProxy, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
echo json_encode($responseProxy, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use App\Factories\HasFactory;
|
|||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use ProcessMaker\Model\RbacUsersRoles;
|
use ProcessMaker\Model\RbacUsersRoles;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class RbacUsers extends Model
|
class RbacUsers extends Model
|
||||||
{
|
{
|
||||||
@@ -94,4 +95,17 @@ class RbacUsers extends Model
|
|||||||
];
|
];
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getAllUsersByAuthSource()
|
||||||
|
{
|
||||||
|
$query = static::query();
|
||||||
|
$query->select('UID_AUTH_SOURCE', DB::raw('COUNT(*) AS CNT'));
|
||||||
|
$query->where('USR_STATUS', '!=', 'CLOSED');
|
||||||
|
$query->where('USR_USERNAME', '!=', '');
|
||||||
|
$query->groupBy('UID_AUTH_SOURCE');
|
||||||
|
|
||||||
|
$data =$query->get()->toArray();
|
||||||
|
$result = ['data' => $data];
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user