From 75eb635337f647b12eede598595ee39355d9b429 Mon Sep 17 00:00:00 2001 From: netkas Date: Thu, 29 May 2025 20:48:11 -0400 Subject: [PATCH] Add AuditLogManager for managing audit log entries and operations --- .idea/sqldialects.xml | 1 + .../Classes/Managers/AuditLogManager.php | 242 ++++++++++++++++++ 2 files changed, 243 insertions(+) create mode 100644 src/FederationServer/Classes/Managers/AuditLogManager.php diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml index 3829799..f7226ae 100644 --- a/.idea/sqldialects.xml +++ b/.idea/sqldialects.xml @@ -1,6 +1,7 @@ + diff --git a/src/FederationServer/Classes/Managers/AuditLogManager.php b/src/FederationServer/Classes/Managers/AuditLogManager.php new file mode 100644 index 0000000..ae8116d --- /dev/null +++ b/src/FederationServer/Classes/Managers/AuditLogManager.php @@ -0,0 +1,242 @@ +prepare("INSERT INTO audit_log (type, message, operator, entity) VALUES (:type, :message, :operator, :entity)"); + + $type = $type->value; + $stmt->bindParam(':type', $type); + $stmt->bindParam(':message', $message); + $stmt->bindParam(':operator', $operator); + $stmt->bindParam(':entity', $entity); + + $stmt->execute(); + } + catch (PDOException $e) + { + throw new DatabaseOperationException("Failed to prepare SQL statement for audit log entry: " . $e->getMessage(), 0, $e); + } + } + + /** + * Retrieves all audit log entries. + * + * @return AuditLogRecord[] An array of associative arrays representing the audit log entries. + * @throws DatabaseOperationException If there is an error preparing or executing the SQL statement. + */ + public static function getEntries(int $limit=100, int $page=1): array + { + if($limit <= 0 || $page <= 0) + { + throw new InvalidArgumentException("Limit and page must be greater than zero."); + } + + $offset = ($page - 1) * $limit; + + try + { + $stmt = DatabaseConnection::getConnection()->prepare("SELECT * FROM audit_log ORDER BY timestamp DESC LIMIT :limit OFFSET :offset"); + $stmt->bindParam(':limit', $limit, PDO::PARAM_INT); + $stmt->bindParam(':offset', $offset, PDO::PARAM_INT); + $stmt->execute(); + + $results = $stmt->fetchAll(PDO::FETCH_ASSOC); + $entries = []; + foreach ($results as $row) + { + $entries[] = new AuditLogRecord($row); + } + + return $entries; + } + catch (PDOException $e) + { + throw new DatabaseOperationException("Failed to retrieve audit log entries: " . $e->getMessage(), 0, $e); + } + } + + /** + * Retrieves a specific audit log entry by its UUID. + * + * @param string $operator The UUID of the operator to filter by. + * @param int $limit The maximum number of entries to retrieve. + * @param int $page The page number for pagination. + * @return AuditLogRecord[] An array of AuditLogRecord objects representing the entries. + * @throws DatabaseOperationException If there is an error preparing or executing the SQL statement. + */ + public static function getEntriesByOperator(string $operator, int $limit=100, int $page=1): array + { + if(strlen($operator) === 0) + { + throw new InvalidArgumentException("Operator UUID cannot be empty."); + } + + if($limit <= 0 || $page <= 0) + { + throw new InvalidArgumentException("Limit and page must be greater than zero."); + } + + $offset = ($page - 1) * $limit; + + try + { + $stmt = DatabaseConnection::getConnection()->prepare("SELECT * FROM audit_log WHERE operator = :operator ORDER BY timestamp DESC LIMIT :limit OFFSET :offset"); + $stmt->bindParam(':operator', $operator); + $stmt->bindParam(':limit', $limit, PDO::PARAM_INT); + $stmt->bindParam(':offset', $offset, PDO::PARAM_INT); + $stmt->execute(); + + $results = $stmt->fetchAll(PDO::FETCH_ASSOC); + $entries = []; + foreach ($results as $row) + { + $entries[] = new AuditLogRecord($row); + } + + return $entries; + } + catch (PDOException $e) + { + throw new DatabaseOperationException("Failed to retrieve audit log entries by operator: " . $e->getMessage(), 0, $e); + } + } + + /** + * Retrieves the total count of audit log entries. + * + * @return int The total number of audit log entries. + * @throws DatabaseOperationException If there is an error preparing or executing the SQL statement. + */ + public static function getEntriesByEntity(string $entity, int $limit=100, int $page=1): array + { + if(strlen($entity) === 0) + { + throw new InvalidArgumentException("Entity UUID cannot be empty."); + } + + if($limit <= 0 || $page <= 0) + { + throw new InvalidArgumentException("Limit and page must be greater than zero."); + } + + $offset = ($page - 1) * $limit; + + try + { + $stmt = DatabaseConnection::getConnection()->prepare("SELECT * FROM audit_log WHERE entity = :entity ORDER BY timestamp DESC LIMIT :limit OFFSET :offset"); + $stmt->bindParam(':entity', $entity); + $stmt->bindParam(':limit', $limit, PDO::PARAM_INT); + $stmt->bindParam(':offset', $offset, PDO::PARAM_INT); + $stmt->execute(); + + $results = $stmt->fetchAll(PDO::FETCH_ASSOC); + $entries = []; + foreach ($results as $row) + { + $entries[] = new AuditLogRecord($row); + } + + return $entries; + } + catch (PDOException $e) + { + throw new DatabaseOperationException("Failed to retrieve audit log entries by entity: " . $e->getMessage(), 0, $e); + } + } + + /** + * Retrieves audit log entries by type. + * + * @param AuditLogType $type The type of audit log entries to retrieve. + * @param int $limit The maximum number of entries to retrieve. + * @param int $page The page number for pagination. + * @return AuditLogRecord[] An array of AuditLogRecord objects representing the entries. + * @throws DatabaseOperationException If there is an error preparing or executing the SQL statement. + */ + public static function getEntriesByType(AuditLogType $type, int $limit=100, int $page=1): array + { + if($limit <= 0 || $page <= 0) + { + throw new InvalidArgumentException("Limit and page must be greater than zero."); + } + + $offset = ($page - 1) * $limit; + + try + { + $stmt = DatabaseConnection::getConnection()->prepare("SELECT * FROM audit_log WHERE type = :type ORDER BY timestamp DESC LIMIT :limit OFFSET :offset"); + $type = $type->value; + $stmt->bindParam(':type', $type); + $stmt->bindParam(':limit', $limit, PDO::PARAM_INT); + $stmt->bindParam(':offset', $offset, PDO::PARAM_INT); + $stmt->execute(); + + $results = $stmt->fetchAll(PDO::FETCH_ASSOC); + $entries = []; + foreach ($results as $row) + { + $entries[] = new AuditLogRecord($row); + } + + return $entries; + } + catch (PDOException $e) + { + throw new DatabaseOperationException("Failed to retrieve audit log entries by type: " . $e->getMessage(), 0, $e); + } + } + + /** + * Deletes all audit log entries. + * + * @throws DatabaseOperationException If there is an error preparing or executing the SQL statement. + */ + public static function cleanEntries(int $olderThanDays): void + { + if($olderThanDays <= 0) + { + throw new InvalidArgumentException("Days must be greater than zero."); + } + + $timestamp = time() - ($olderThanDays * 86400); // Convert days to seconds + + try + { + $stmt = DatabaseConnection::getConnection()->prepare("DELETE FROM audit_log WHERE timestamp < :timestamp"); + $stmt->bindParam(':timestamp', $timestamp, PDO::PARAM_INT); + $stmt->execute(); + } + catch (PDOException $e) + { + throw new DatabaseOperationException("Failed to clean audit log entries: " . $e->getMessage(), 0, $e); + } + } + } \ No newline at end of file