Commit 782a59cb authored by Alexa Oana eliza's avatar Alexa Oana eliza
Browse files

Revert "Merge branch '73-orchestrator-create-a-librabry-in-core-orchestrator' into 'dev'"

This reverts merge request !78
1 merge request!84Revert "Merge branch '73-orchestrator-create-a-librabry-in-core-orchestrator' into 'dev'"
Pipeline #32505 passed with stages
in 52 seconds
Showing with 297 additions and 316 deletions
+297 -316
<?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
<?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
<?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
...@@ -4,12 +4,10 @@ class Audit implements EndpointInterface ...@@ -4,12 +4,10 @@ class Audit implements EndpointInterface
{ {
private TaskGateway $gateway; private TaskGateway $gateway;
private Utils $utils;
public function __construct (TaskGateway $gateway) public function __construct (TaskGateway $gateway)
{ {
$this->gateway = $gateway; $this->gateway = $gateway;
$this->utils = new Utils();
} }
/** /**
...@@ -49,7 +47,7 @@ class Audit implements EndpointInterface ...@@ -49,7 +47,7 @@ class Audit implements EndpointInterface
$result = $this->processAuditDeletion($this->gateway->getObjectTypeTask('Audit')); $result = $this->processAuditDeletion($this->gateway->getObjectTypeTask('Audit'));
// Recursive function to filter out empty arrays at any depth // Recursive function to filter out empty arrays at any depth
$nonEmptyResults = $this->utils->recursiveArrayFilter($result); $nonEmptyResults = $this->recursiveArrayFilter($result);
if (!empty($nonEmptyResults)) { if (!empty($nonEmptyResults)) {
return $nonEmptyResults; return $nonEmptyResults;
...@@ -121,4 +119,27 @@ class Audit implements EndpointInterface ...@@ -121,4 +119,27 @@ class Audit implements EndpointInterface
return $audit; 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
...@@ -4,12 +4,10 @@ class Notifications implements EndpointInterface ...@@ -4,12 +4,10 @@ class Notifications implements EndpointInterface
{ {
private TaskGateway $gateway; private TaskGateway $gateway;
private Utils $utils;
public function __construct (TaskGateway $gateway) public function __construct (TaskGateway $gateway)
{ {
$this->gateway = $gateway; $this->gateway = $gateway;
$this->utils = new Utils();
} }
/** /**
...@@ -84,7 +82,7 @@ class Notifications implements EndpointInterface ...@@ -84,7 +82,7 @@ class Notifications implements EndpointInterface
$this->gateway->unsetCountKeys($monitoredSupannResource); $this->gateway->unsetCountKeys($monitoredSupannResource);
// Find matching attributes between audited and monitored attributes // 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 // Verify Supann resource state if applicable
if ($this->shouldVerifySupannResource($monitoredSupannResource, $auditAttributes)) { if ($this->shouldVerifySupannResource($monitoredSupannResource, $auditAttributes)) {
...@@ -167,6 +165,30 @@ class Notifications implements EndpointInterface ...@@ -167,6 +165,30 @@ class Notifications implements EndpointInterface
return $auditAttributes; 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 $supannResource
* @param array $auditedAttrs * @param array $auditedAttrs
...@@ -185,7 +207,7 @@ class Notifications implements EndpointInterface ...@@ -185,7 +207,7 @@ class Notifications implements EndpointInterface
} }
// Get all the values only of a multidimensional array. // Get all the values only of a multidimensional array.
$auditedValues = $this->utils->getArrayValuesRecursive($auditedAttrs); $auditedValues = $this->getArrayValuesRecursive($auditedAttrs);
if (in_array($monitoredSupannState, $auditedValues)) { if (in_array($monitoredSupannState, $auditedValues)) {
$result = TRUE; $result = TRUE;
...@@ -196,6 +218,26 @@ class Notifications implements EndpointInterface ...@@ -196,6 +218,26 @@ class Notifications implements EndpointInterface
return $result; 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 * @param string $mainTaskDn
* @return array * @return array
......
...@@ -4,12 +4,10 @@ class Reminder implements EndpointInterface ...@@ -4,12 +4,10 @@ class Reminder implements EndpointInterface
{ {
private TaskGateway $gateway; private TaskGateway $gateway;
private ReminderTokenUtils $reminderTokenUtils;
public function __construct (TaskGateway $gateway) public function __construct (TaskGateway $gateway)
{ {
$this->gateway = $gateway; $this->gateway = $gateway;
$this->reminderTokenUtils = new ReminderTokenUtils();
} }
/** /**
...@@ -111,13 +109,13 @@ class Reminder implements EndpointInterface ...@@ -111,13 +109,13 @@ class Reminder implements EndpointInterface
$reminders[$remindersMainTaskName]['subTask'][$task['cn'][0]]['uid'] = $task['fdtasksgranulardn'][0]; $reminders[$remindersMainTaskName]['subTask'][$task['cn'][0]]['uid'] = $task['fdtasksgranulardn'][0];
// Create timeStamp expiration for token // Create timeStamp expiration for token
$tokenExpire = $this->reminderTokenUtils->getTokenExpiration($task['fdtasksgranularhelper'][0], $tokenExpire = $this->getTokenExpiration($task['fdtasksgranularhelper'][0],
$remindersMainTask[0]['fdtasksreminderfirstcall'][0], $remindersMainTask[0]['fdtasksreminderfirstcall'][0],
$remindersMainTask[0]['fdtasksremindersecondcall'][0]); $remindersMainTask[0]['fdtasksremindersecondcall'][0]);
// Create token for SubTask // 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 // 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 // Recipient email form
$reminders[$remindersMainTaskName]['subTask'][$task['cn'][0]]['mail'] = $tokenMailTemplateForm; $reminders[$remindersMainTaskName]['subTask'][$task['cn'][0]]['mail'] = $tokenMailTemplateForm;
...@@ -138,13 +136,13 @@ class Reminder implements EndpointInterface ...@@ -138,13 +136,13 @@ class Reminder implements EndpointInterface
$reminders[$remindersMainTaskName]['subTask'][$task['cn'][0]]['uid'] = $task['fdtasksgranulardn'][0]; $reminders[$remindersMainTaskName]['subTask'][$task['cn'][0]]['uid'] = $task['fdtasksgranulardn'][0];
// Create timeStamp expiration for token // Create timeStamp expiration for token
$tokenExpire = $this->reminderTokenUtils->getTokenExpiration($task['fdtasksgranularhelper'][0], $tokenExpire = $this->getTokenExpiration($task['fdtasksgranularhelper'][0],
$remindersMainTask[0]['fdtasksreminderfirstcall'][0], $remindersMainTask[0]['fdtasksreminderfirstcall'][0],
$remindersMainTask[0]['fdtasksremindersecondcall'][0]); $remindersMainTask[0]['fdtasksremindersecondcall'][0]);
// Create token for SubTask // 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 // 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 // Recipient email form
$reminders[$remindersMainTaskName]['subTask'][$task['cn'][0]]['mail'] = $tokenMailTemplateForm; $reminders[$remindersMainTaskName]['subTask'][$task['cn'][0]]['mail'] = $tokenMailTemplateForm;
...@@ -219,6 +217,207 @@ class Reminder implements EndpointInterface ...@@ -219,6 +217,207 @@ class Reminder implements EndpointInterface
return $result; 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 * @param string $dn
* @return string * @return string
...@@ -393,6 +592,26 @@ class Reminder implements EndpointInterface ...@@ -393,6 +592,26 @@ class Reminder implements EndpointInterface
return DateTime::createFromFormat('Ymd', $dateString); 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 * @param string $mainTaskDn
* @return array * @return array
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment