From 782a59cb5b5fa707d21d99aebd9a497f4a1820f5 Mon Sep 17 00:00:00 2001 From: Alexa Oana eliza <alexa.oanaeliza@fusiondirectory.org> Date: Wed, 2 Apr 2025 08:03:48 +0000 Subject: [PATCH] Revert "Merge branch '73-orchestrator-create-a-librabry-in-core-orchestrator' into 'dev'" This reverts merge request !78 --- library/plugins/MailUtils.php | 34 ---- library/plugins/ReminderTokenUtils.php | 208 ---------------------- library/plugins/Utils.php | 59 ------- plugins/tasks/Audit.php | 27 ++- plugins/tasks/Notifications.php | 50 +++++- plugins/tasks/Reminder.php | 235 ++++++++++++++++++++++++- 6 files changed, 297 insertions(+), 316 deletions(-) delete mode 100644 library/plugins/MailUtils.php delete mode 100644 library/plugins/ReminderTokenUtils.php delete mode 100644 library/plugins/Utils.php diff --git a/library/plugins/MailUtils.php b/library/plugins/MailUtils.php deleted file mode 100644 index 87f4c64..0000000 --- a/library/plugins/MailUtils.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -class MailUtils -{ - public function __construct () - { - } - - public function sendMail ($setFrom, $setBCC, $recipients, $body, $signature, $subject, $receipt, $attachments) - { - $mail_controller = new \FusionDirectory\Mail\MailLib($setFrom, - $setBCC, - $recipients, - $body, - $signature, - $subject, - $receipt, - $attachments); - - return $mail_controller->sendMail(); - } - - /** - * @return array - * Note : A simple retrieval methods of the mail backend configuration set in FusionDirectory - */ - public function getMailObjectConfiguration (TaskGateway $gateway): array - { - return $gateway->getLdapTasks( - "(objectClass=fdTasksConf)", - ["fdTasksConfLastExecTime", "fdTasksConfIntervalEmails", "fdTasksConfMaxEmails"] - ); - } -} \ No newline at end of file diff --git a/library/plugins/ReminderTokenUtils.php b/library/plugins/ReminderTokenUtils.php deleted file mode 100644 index bb08d24..0000000 --- a/library/plugins/ReminderTokenUtils.php +++ /dev/null @@ -1,208 +0,0 @@ -<?php - -class ReminderTokenUtils -{ - public function __construct () - { - } - - /** - * @param string $userDN - * @param int $timeStamp - * @return string - * @throws Exception - */ - public function generateToken (string $userDN, int $timeStamp, TaskGateway $gateway): string - { - $token = NULL; - // Salt has been generated with APG. - $salt = '8onOlEsItKond'; - $payload = json_encode($userDN . $salt); - // This allows the token to be different every time. - $time = time(); - - // Create hmac with sha256 alg and the key provided for JWT token signature in ENV. - $token_hmac = hash_hmac("sha256", $time . $payload, $_ENV["SECRET_KEY"], TRUE); - - // We need to have a token allowed to be used within an URL. - $token = $this->base64urlEncode($token_hmac); - - // Save token within LDAP - $this->saveTokenInLdap($userDN, $token, $timeStamp, $gateway); - - return $token; - } - - /** - * @param string $userDN - * @param string $token - * NOTE : UID is the full DN of the user. (uid=...). - * @param int $days - * @return bool - * @throws Exception - */ - private function saveTokenInLdap (string $userDN, string $token, int $days, TaskGateway $gateway): bool - { - $result = FALSE; - - $currentTimestamp = time(); - // Calculate the future timestamp by adding days to the current timestamp (We actually adds number of seconds). - $futureTimestamp = $currentTimestamp + ($days * 24 * 60 * 60); - - preg_match('/uid=([^,]+),ou=/', $userDN, $matches); - $uid = $matches[1]; - $dn = 'cn=' . $uid . ',' . 'ou=tokens' . ',' . $_ENV["LDAP_BASE"]; - - $ldap_entry["objectClass"] = ['top', 'fdTokenEntry']; - $ldap_entry["fdTokenUserDN"] = $userDN; - $ldap_entry["fdTokenType"] = 'reminder'; - $ldap_entry["fdToken"] = $token; - $ldap_entry["fdTokenTimestamp"] = $futureTimestamp; - $ldap_entry["cn"] = $uid; - - // set the dn for the token, only take what's between "uid=" and ",ou=" - - - // Verify if token ou branch exists - if (!$this->tokenBranchExist('ou=tokens' . ',' . $_ENV["LDAP_BASE"], $gateway)) { - // Create the branch - $this->createBranchToken($gateway); - } - - // The user token DN creation - $userTokenDN = 'cn=' . $uid . ',ou=tokens' . ',' . $_ENV["LDAP_BASE"]; - // Verify if a token already exists for specified user and remove it to create new one correctly. - if ($this->tokenBranchExist($userTokenDN, $gateway)) { - // Remove the user token - $this->removeUserToken($userTokenDN, $gateway); - } - - // Add token to LDAP for specific UID - try { - $result = ldap_add($gateway->ds, $dn, $ldap_entry); // bool returned - } catch (Exception $e) { - echo json_encode(["Ldap Error - Token could not be saved!" => "$e"]); // string returned - exit; - } - - return $result; - } - - /** - * @param int $subTaskCall - * @param int $firstCall - * @param int $secondCall - * @return int - * Note : Simply return the difference between first and second call. (First call can be null). - */ - public function getTokenExpiration (int $subTaskCall, int $firstCall, int $secondCall): int - { - // if firstCall is empty, secondCall is the timestamp expiry for the token. - $result = $secondCall; - - if (!empty($firstCall)) { - // Verification if the subTask is the second reminder or the first reminder. - if ($subTaskCall === $firstCall) { - $result = $firstCall - $secondCall; - } - } - - return $result; - } - - /** - * @param $userTokenDN - * @return void - * Note : Simply remove the token for specific user DN - */ - private function removeUserToken ($userTokenDN, TaskGateway $gateway): void - { - // Add token to LDAP for specific UID - try { - $result = ldap_delete($gateway->ds, $userTokenDN); // bool returned - } catch (Exception $e) { - echo json_encode(["Ldap Error - User token could not be removed!" => "$e"]); // string returned - exit; - } - } - - /** - * Create ou=pluginManager LDAP branch - * @throws Exception - */ - private function createBranchToken (TaskGateway $gateway): void - { - try { - ldap_add( - $gateway->ds, 'ou=tokens' . ',' . $_ENV["LDAP_BASE"], - [ - 'ou' => 'tokens', - 'objectClass' => 'organizationalUnit', - ] - ); - } catch (Exception $e) { - - echo json_encode(["Ldap Error - Impossible to create the token branch" => "$e"]); // string returned - exit; - } - } - - /** - * @param string $token - * @param array $mailTemplateForm - * @param string $taskDN - * @return array - */ - public function generateTokenUrl (string $token, array $mailTemplateForm, string $taskDN): array - { - //Only take the cn of the main task name : - preg_match('/cn=([^,]+),ou=/', $taskDN, $matches); - $taskName = $matches[1]; - - // Remove the API URI - $cleanedUrl = preg_replace('#/rest\.php/v1$#', '', $_ENV['FUSION_DIRECTORY_API_URL']); - $url = $cleanedUrl . '/accountProlongation.php?token=' . $token . '&task=' . $taskName; - - $mailTemplateForm['body'] .= $url; - - return $mailTemplateForm; - } - - /** - * @param string $dn - * @return bool - * Note : Simply inspect if the branch for token is existing. - */ - private function tokenBranchExist (string $dn, TaskGateway $gateway): bool - { - $result = FALSE; - - try { - $search = ldap_search($gateway->ds, $dn, "(objectClass=*)"); - // Check if the search was successful - if ($search) { - // Get the number of entries found - $entries = ldap_get_entries($gateway->ds, $search); - - // If entries are found, set result to true - if ($entries["count"] > 0) { - $result = TRUE; - } - } - } catch (Exception $e) { - $result = FALSE; - } - - return $result; - } - - /** - * @param string $text - * @return string - * Note : This come from jwtToken, as it is completely private - it is cloned here for now. - */ - private function base64urlEncode (string $text): string - { - return str_replace(["+", "/", "="], ["A", "B", ""], base64_encode($text)); - } -} \ No newline at end of file diff --git a/library/plugins/Utils.php b/library/plugins/Utils.php deleted file mode 100644 index 10eafe6..0000000 --- a/library/plugins/Utils.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php - -class Utils -{ - public function __construct () - { - } - - /** - * @param array $array - * @return array - * Note : Recursively filters out empty values and arrays at any depth. - */ - public function recursiveArrayFilter (array $array): array - { - return array_filter($array, function ($item) { - if (is_array($item)) { - $item = $this->recursiveArrayFilter($item); - } - return !empty($item); - }); - } - - /** - * Find matching keys between 2 lists. - * - * @param array|null $elements - * @param array $keys - * @return array - */ - public function findMatchingKeys (?array $elements, array $keys): array - { - $matching = []; - - if (!empty($elements)) { - foreach ($elements as $element) { - foreach ($keys as $key) { - if (!empty($element) && array_key_exists($key, $element)) { - $matching[] = $key; - } - } - } - } - - return $matching; - } - - /** - * @param $array - * @return array - * Note : simply return all values of a multi-dimensional array. - */ - public function getArrayValuesRecursive ($array) - { - return array_reduce($array, function ($carry, $value) { - return array_merge($carry, is_array($value) ? $this->getArrayValuesRecursive($value) : [$value]); - }, []); - } -} \ No newline at end of file diff --git a/plugins/tasks/Audit.php b/plugins/tasks/Audit.php index 9481831..6e51ae7 100644 --- a/plugins/tasks/Audit.php +++ b/plugins/tasks/Audit.php @@ -4,12 +4,10 @@ class Audit implements EndpointInterface { private TaskGateway $gateway; - private Utils $utils; public function __construct (TaskGateway $gateway) { $this->gateway = $gateway; - $this->utils = new Utils(); } /** @@ -49,7 +47,7 @@ class Audit implements EndpointInterface $result = $this->processAuditDeletion($this->gateway->getObjectTypeTask('Audit')); // Recursive function to filter out empty arrays at any depth - $nonEmptyResults = $this->utils->recursiveArrayFilter($result); + $nonEmptyResults = $this->recursiveArrayFilter($result); if (!empty($nonEmptyResults)) { return $nonEmptyResults; @@ -121,4 +119,27 @@ class Audit implements EndpointInterface return $audit; } + + /** + * @param array $array + * @return array + * Note : Recursively filters out empty values and arrays at any depth. + */ + private function recursiveArrayFilter (array $array): array + { + // First filter the array for non-empty elements + $filtered = array_filter($array, function ($item) { + if (is_array($item)) { + // Recursively filter the sub-array + $item = $this->recursiveArrayFilter($item); + // Only retain non-empty arrays + return !empty($item); + } else { + // Retain non-empty scalar values + return !empty($item); + } + }); + + return $filtered; + } } \ No newline at end of file diff --git a/plugins/tasks/Notifications.php b/plugins/tasks/Notifications.php index 4547b87..f78ef5e 100644 --- a/plugins/tasks/Notifications.php +++ b/plugins/tasks/Notifications.php @@ -4,12 +4,10 @@ class Notifications implements EndpointInterface { private TaskGateway $gateway; - private Utils $utils; public function __construct (TaskGateway $gateway) { $this->gateway = $gateway; - $this->utils = new Utils(); } /** @@ -84,7 +82,7 @@ class Notifications implements EndpointInterface $this->gateway->unsetCountKeys($monitoredSupannResource); // Find matching attributes between audited and monitored attributes - $matchingAttrs = $this->utils->findMatchingKeys($auditAttributes, $monitoredAttrs); + $matchingAttrs = $this->findMatchingAttributes($auditAttributes, $monitoredAttrs); // Verify Supann resource state if applicable if ($this->shouldVerifySupannResource($monitoredSupannResource, $auditAttributes)) { @@ -167,6 +165,30 @@ class Notifications implements EndpointInterface return $auditAttributes; } + /** + * Find matching attributes between audit and monitored attributes. + * + * @param array|null $auditAttributes + * @param array $monitoredAttrs + * @return array + */ + private function findMatchingAttributes (?array $auditAttributes, array $monitoredAttrs): array + { + $matchingAttrs = []; + + if (!empty($auditAttributes)) { + foreach ($auditAttributes as $attributeName) { + foreach ($monitoredAttrs as $monitoredAttr) { + if (!empty($attributeName) && array_key_exists($monitoredAttr, $attributeName)) { + $matchingAttrs[] = $monitoredAttr; + } + } + } + } + + return $matchingAttrs; + } + /** * @param array $supannResource * @param array $auditedAttrs @@ -185,7 +207,7 @@ class Notifications implements EndpointInterface } // Get all the values only of a multidimensional array. - $auditedValues = $this->utils->getArrayValuesRecursive($auditedAttrs); + $auditedValues = $this->getArrayValuesRecursive($auditedAttrs); if (in_array($monitoredSupannState, $auditedValues)) { $result = TRUE; @@ -196,6 +218,26 @@ class Notifications implements EndpointInterface return $result; } + /** + * @param $array + * @return array + * Note : simply return all values of a multi-dimensional array. + */ + public function getArrayValuesRecursive ($array) + { + $values = []; + foreach ($array as $value) { + if (is_array($value)) { + // If value is an array, merge its values recursively + $values = array_merge($values, $this->getArrayValuesRecursive($value)); + } else { + // If value is not an array, add it to the result + $values[] = $value; + } + } + return $values; + } + /** * @param string $mainTaskDn * @return array diff --git a/plugins/tasks/Reminder.php b/plugins/tasks/Reminder.php index 180eca7..ca46b55 100644 --- a/plugins/tasks/Reminder.php +++ b/plugins/tasks/Reminder.php @@ -4,12 +4,10 @@ class Reminder implements EndpointInterface { private TaskGateway $gateway; - private ReminderTokenUtils $reminderTokenUtils; public function __construct (TaskGateway $gateway) { $this->gateway = $gateway; - $this->reminderTokenUtils = new ReminderTokenUtils(); } /** @@ -111,13 +109,13 @@ class Reminder implements EndpointInterface $reminders[$remindersMainTaskName]['subTask'][$task['cn'][0]]['uid'] = $task['fdtasksgranulardn'][0]; // Create timeStamp expiration for token - $tokenExpire = $this->reminderTokenUtils->getTokenExpiration($task['fdtasksgranularhelper'][0], + $tokenExpire = $this->getTokenExpiration($task['fdtasksgranularhelper'][0], $remindersMainTask[0]['fdtasksreminderfirstcall'][0], $remindersMainTask[0]['fdtasksremindersecondcall'][0]); // Create token for SubTask - $token = $this->reminderTokenUtils->generateToken($task['fdtasksgranulardn'][0], $tokenExpire, $this->gateway); + $token = $this->generateToken($task['fdtasksgranulardn'][0], $tokenExpire); // Edit the mailForm with the url link containing the token - $tokenMailTemplateForm = $this->reminderTokenUtils->generateTokenUrl($token, $mailTemplateForm, $remindersMainTaskName); + $tokenMailTemplateForm = $this->generateTokenUrl($token, $mailTemplateForm, $remindersMainTaskName); // Recipient email form $reminders[$remindersMainTaskName]['subTask'][$task['cn'][0]]['mail'] = $tokenMailTemplateForm; @@ -138,13 +136,13 @@ class Reminder implements EndpointInterface $reminders[$remindersMainTaskName]['subTask'][$task['cn'][0]]['uid'] = $task['fdtasksgranulardn'][0]; // Create timeStamp expiration for token - $tokenExpire = $this->reminderTokenUtils->getTokenExpiration($task['fdtasksgranularhelper'][0], + $tokenExpire = $this->getTokenExpiration($task['fdtasksgranularhelper'][0], $remindersMainTask[0]['fdtasksreminderfirstcall'][0], $remindersMainTask[0]['fdtasksremindersecondcall'][0]); // Create token for SubTask - $token = $this->reminderTokenUtils->generateToken($task['fdtasksgranulardn'][0], $tokenExpire, $this->gateway); + $token = $this->generateToken($task['fdtasksgranulardn'][0], $tokenExpire); // Edit the mailForm with the url link containing the token - $tokenMailTemplateForm = $this->reminderTokenUtils->generateTokenUrl($token, $mailTemplateForm, $remindersMainTaskName); + $tokenMailTemplateForm = $this->generateTokenUrl($token, $mailTemplateForm, $remindersMainTaskName); // Recipient email form $reminders[$remindersMainTaskName]['subTask'][$task['cn'][0]]['mail'] = $tokenMailTemplateForm; @@ -219,6 +217,207 @@ class Reminder implements EndpointInterface return $result; } + /** + * @param string $token + * @param array $mailTemplateForm + * @param string $taskDN + * @return array + */ + private function generateTokenUrl (string $token, array $mailTemplateForm, string $taskDN): array + { + //Only take the cn of the main task name : + preg_match('/cn=([^,]+),ou=/', $taskDN, $matches); + $taskName = $matches[1]; + + // Remove the API URI + $cleanedUrl = preg_replace('#/rest\.php/v1$#', '', $_ENV['FUSION_DIRECTORY_API_URL']); + $url = $cleanedUrl . '/accountProlongation.php?token=' . $token . '&task=' . $taskName; + + $mailTemplateForm['body'] .= $url; + + return $mailTemplateForm; + } + + /** + * @param int $subTaskCall + * @param int $firstCall + * @param int $secondCall + * @return int + * Note : Simply return the difference between first and second call. (First call can be null). + */ + private function getTokenExpiration (int $subTaskCall, int $firstCall, int $secondCall): int + { + // if firstCall is empty, secondCall is the timestamp expiry for the token. + $result = $secondCall; + + if (!empty($firstCall)) { + // Verification if the subTask is the second reminder or the first reminder. + if ($subTaskCall === $firstCall) { + $result = $firstCall - $secondCall; + } + } + + return $result; + } + + /** + * @param string $userDN + * @param int $timeStamp + * @return string + * @throws Exception + */ + private function generateToken (string $userDN, int $timeStamp): string + { + $token = NULL; + // Salt has been generated with APG. + $salt = '8onOlEsItKond'; + $payload = json_encode($userDN . $salt); + // This allows the token to be different every time. + $time = time(); + + // Create hmac with sha256 alg and the key provided for JWT token signature in ENV. + $token_hmac = hash_hmac("sha256", $time . $payload, $_ENV["SECRET_KEY"], TRUE); + + // We need to have a token allowed to be used within an URL. + $token = $this->base64urlEncode($token_hmac); + + // Save token within LDAP + $this->saveTokenInLdap($userDN, $token, $timeStamp); + + return $token; + } + + /** + * @param string $userDN + * @param string $token + * NOTE : UID is the full DN of the user. (uid=...). + * @param int $days + * @return bool + * @throws Exception + */ + private function saveTokenInLdap (string $userDN, string $token, int $days): bool + { + $result = FALSE; + + $currentTimestamp = time(); + // Calculate the future timestamp by adding days to the current timestamp (We actually adds number of seconds). + $futureTimestamp = $currentTimestamp + ($days * 24 * 60 * 60); + + preg_match('/uid=([^,]+),ou=/', $userDN, $matches); + $uid = $matches[1]; + $dn = 'cn=' . $uid . ',' . 'ou=tokens' . ',' . $_ENV["LDAP_BASE"]; + + $ldap_entry["objectClass"] = ['top', 'fdTokenEntry']; + $ldap_entry["fdTokenUserDN"] = $userDN; + $ldap_entry["fdTokenType"] = 'reminder'; + $ldap_entry["fdToken"] = $token; + $ldap_entry["fdTokenTimestamp"] = $futureTimestamp; + $ldap_entry["cn"] = $uid; + + // set the dn for the token, only take what's between "uid=" and ",ou=" + + + // Verify if token ou branch exists + if (!$this->tokenBranchExist('ou=tokens' . ',' . $_ENV["LDAP_BASE"])) { + // Create the branch + $this->createBranchToken(); + } + + // The user token DN creation + $userTokenDN = 'cn=' . $uid . ',ou=tokens' . ',' . $_ENV["LDAP_BASE"]; + // Verify if a token already exists for specified user and remove it to create new one correctly. + if ($this->tokenBranchExist($userTokenDN)) { + // Remove the user token + $this->removeUserToken($userTokenDN); + } + + // Add token to LDAP for specific UID + try { + $result = ldap_add($this->gateway->ds, $dn, $ldap_entry); // bool returned + } catch (Exception $e) { + echo json_encode(["Ldap Error - Token could not be saved!" => "$e"]); // string returned + exit; + } + + return $result; + } + + /** + * @param $userTokenDN + * @return void + * Note : Simply remove the token for specific user DN + */ + private function removeUserToken ($userTokenDN): void + { + // Add token to LDAP for specific UID + try { + $result = ldap_delete($this->gateway->ds, $userTokenDN); // bool returned + } catch (Exception $e) { + echo json_encode(["Ldap Error - User token could not be removed!" => "$e"]); // string returned + exit; + } + } + + /** + * Create ou=pluginManager LDAP branch + * @throws Exception + */ + protected function createBranchToken (): void + { + try { + ldap_add( + $this->gateway->ds, 'ou=tokens' . ',' . $_ENV["LDAP_BASE"], + [ + 'ou' => 'tokens', + 'objectClass' => 'organizationalUnit', + ] + ); + } catch (Exception $e) { + + echo json_encode(["Ldap Error - Impossible to create the token branch" => "$e"]); // string returned + exit; + } + } + + + /** + * @param string $dn + * @return bool + * Note : Simply inspect if the branch for token is existing. + */ + private function tokenBranchExist (string $dn): bool + { + $result = FALSE; + + try { + $search = ldap_search($this->gateway->ds, $dn, "(objectClass=*)"); + // Check if the search was successful + if ($search) { + // Get the number of entries found + $entries = ldap_get_entries($this->gateway->ds, $search); + + // If entries are found, set result to true + if ($entries["count"] > 0) { + $result = TRUE; + } + } + } catch (Exception $e) { + $result = FALSE; + } + + return $result; + } + + /** + * @param string $text + * @return string + * Note : This come from jwtToken, as it is completely private - it is cloned here for now. + */ + private function base64urlEncode (string $text): string + { + return str_replace(["+", "/", "="], ["A", "B", ""], base64_encode($text)); + } + /** * @param string $dn * @return string @@ -393,6 +592,26 @@ class Reminder implements EndpointInterface return DateTime::createFromFormat('Ymd', $dateString); } + /** + * @param $array + * @return array + * Note : simply return all values of a multi-dimensional array. + */ + public function getArrayValuesRecursive ($array) + { + $values = []; + foreach ($array as $value) { + if (is_array($value)) { + // If value is an array, merge its values recursively + $values = array_merge($values, $this->getArrayValuesRecursive($value)); + } else { + // If value is not an array, add it to the result + $values[] = $value; + } + } + return $values; + } + /** * @param string $mainTaskDn * @return array -- GitLab