diff --git a/src/FusionDirectory/Audit/AuditLib.php b/src/FusionDirectory/Audit/AuditLib.php index f7e63062257f3232db977021bc25cdd102134d48..e74379a2282308a11075ab59e6ee44324a960506 100644 --- a/src/FusionDirectory/Audit/AuditLib.php +++ b/src/FusionDirectory/Audit/AuditLib.php @@ -2,72 +2,139 @@ namespace FusionDirectory\Audit; +// Simplify the base code by import (using) base php classes +use DateTime; +use DateTimeZone; +use Exception; +use FusionDirectory\Ldap; + class AuditLib { - private $subTaskDN, $subTaskCN; - private int $auditRetention; + private string $subTaskDN, $subTaskCN; + private int $auditRetention; // Usage of CLI bool is to make sure we use proper method in case of direct CLI call. (Instead of Orchestrator). - private bool $CLI; + private array $auditList; + private Ldap\Link $ldapBind; + private object $gateway; - public function __construct (INT $auditRetention, BOOL $CLI = FALSE, STRING $subTaskDN = NULL, STRING $subTaskCN = NULL) + public function __construct (int $auditRetention, array $auditList, $gateway = NULL, string $subTaskDN = NULL, string $subTaskCN = NULL, $ldapBind = NULL) { - $this->auditRetention = $auditRetention; - $this->CLI = $CLI; - $this->subTaskDN = $subTaskDN; - $this->subTaskCN = $subTaskCN; + $this->auditRetention = $auditRetention; + $this->subTaskDN = $subTaskDN; + $this->subTaskCN = $subTaskCN; + $this->auditList = $auditList; + $this->ldapBind = $ldapBind; + $this->gateway = $gateway; } /** - * @param $auditRetention - * @param $subTaskDN - * @param $subTaskCN * @return array * Note : This will return a validation of audit log suppression + * @throws Exception */ - - public function checkAuditPassedRetention ($auditRetention, $subTaskDN, $subTaskCN): array + public function checkAuditPassedRetentionOrchestrator (): array { $result = []; - // Date time object will use the timezone defined in FD, code is in index.php $today = new DateTime(); - // Search in LDAP for audit entries (All entries ! This can be pretty heavy. - $audit = $this->gateway->getLdapTasks('(objectClass=fdAuditEvent)', ['fdAuditDateTime'], '', ''); - // Remove the count key from the audit array. - $this->gateway->unsetCountKeys($audit); - // In case no audit exists, we have to update the tasks as well. Meaning below loop won't be reached. - if (empty($audit)) { - $result[$subTaskCN]['result'] = TRUE; - $result[$subTaskCN]['info'] = 'No audit to be removed.'; - $result[$subTaskCN]['statusUpdate'] = $this->gateway->updateTaskStatus($subTaskDN, $subTaskCN, "2"); + if (empty($this->auditList)) { + $result[$this->subTaskCN]['result'] = TRUE; + $result[$this->subTaskCN]['info'] = 'No audit to be removed.'; + $result[$this->subTaskCN]['statusUpdate'] = $this->gateway->updateTaskStatus($this->subTaskDN, $this->subTaskCN, "2"); } - foreach ($audit as $record) { + foreach ($this->auditList as $record) { // Record in Human Readable date time object $auditDateTime = $this->generalizeLdapTimeToPhpObject($record['fdauditdatetime'][0]); $interval = $today->diff($auditDateTime); // Check if the interval is equal or greater than auditRetention setting - if ($interval->days >= $auditRetention) { + if ($interval->days >= $this->auditRetention) { // If greater, delete the DN audit entry, we reuse removeSubTask method from gateway and get ldap response.(bool). - $result[$subTaskCN]['result'] = $this->gateway->removeSubTask($record['dn']); - $result[$subTaskCN]['info'] = 'Audit record removed.'; + $result[$this->subTaskCN]['result'] = $this->gateway->removeSubTask($record['dn']); + $result[$this->subTaskCN]['info'] = 'Audit record removed.'; // Update tasks accordingly if LDAP succeeded. TRUE Boolean returned by ldap. - if ($result[$subTaskCN]['result']) { + if ($result[$this->subTaskCN]['result']) { // Update the subtask with the status completed a.k.a "2". - $result[$subTaskCN]['statusUpdate'] = $this->gateway->updateTaskStatus($subTaskDN, $subTaskCN, "2"); + $result[$this->subTaskCN]['statusUpdate'] = $this->gateway->updateTaskStatus($this->subTaskDN, $this->subTaskCN, "2"); } else { // Update the task with the LDAP potential error code. - $result[$subTaskCN]['statusUpdate'] = $this->gateway->updateTaskStatus($subTaskDN, $subTaskCN, $result[$record['dn']]['result']); + $result[$this->subTaskCN]['statusUpdate'] = $this->gateway->updateTaskStatus($this->subTaskDN, $this->subTaskCN, $result[$record['dn']]['result']); + } + } + } + + return $result; + } + + + /** + * @return array + * Note : This will return a validation of audit log suppression + * @throws Exception + */ + + public function checkAuditPassedRetentionCLI (): array + { + $result = []; + + $today = new DateTime(); + + // Enter condition if lib is used by CLI tools + // In case no audit exists, we have to update the tasks as well. Meaning below loop won't be reached. + if (empty($this->auditList)) { + return ['No audit entries found.']; + } + + foreach ($this->auditList as $record) { + // Record in Human Readable date time object + $auditDateTime = $this->generalizeLdapTimeToPhpObject($record['fdauditdatetime'][0]); + + $interval = $today->diff($auditDateTime); + + // Check if the interval is equal or greater than auditRetention setting + if ($interval->days >= $this->auditRetention) { + // If greater, delete the DN audit entry, we reuse removeSubTask method from gateway and get ldap response.(bool). + + if ($this->ldapBind->delete($record['dn'])) { + $result[$record['dn']] = 'audit removed'; + } else { + $result[$record['dn']] = 'Error during audit deletion'; } + } } return $result; } + + /** + * @param $generalizeLdapDateTime + * @return DateTime|string[] + * @throws Exception + * Note : Simply take a generalized Ldap time (with UTC = Z) and transform it to php object dateTime. + */ + public function generalizeLdapTimeToPhpObject ($generalizeLdapDateTime) + { + // Extract the date part (first 8 characters: YYYYMMDD), we do not care about hour and seconds. + $auditTimeFormatted = substr($generalizeLdapDateTime, 0, 8); + + // Create a DateTime object using only the date part, carefully setting the timezone to UTC. Audit timestamp is UTC + $auditDate = DateTime::createFromFormat('Ymd', $auditTimeFormatted, new DateTimeZone('UTC')); + + // Check if the DateTime object was created successfully + if (!$auditDate) { + return ['Error in Time conversion from Audit record with timestamp :' . $generalizeLdapDateTime]; + } + + // Transform dateTime object from UTC to local defined dateTime. (Timezone is set in index.php if used by orchestrator). + $auditDate->setTimezone(new DateTimeZone(date_default_timezone_get())); + + return $auditDate; + } } \ No newline at end of file