Skip to main content

oxigdal_security/audit/
mod.rs

1//! Audit logging framework.
2
3pub mod events;
4pub mod logger;
5pub mod query;
6pub mod storage;
7
8use chrono::{DateTime, Utc};
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11
12/// Audit log entry.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct AuditLogEntry {
15    /// Entry ID.
16    pub id: String,
17    /// Timestamp.
18    pub timestamp: DateTime<Utc>,
19    /// Event type.
20    pub event_type: AuditEventType,
21    /// Subject (user/service).
22    pub subject: Option<String>,
23    /// Resource.
24    pub resource: Option<String>,
25    /// Action.
26    pub action: Option<String>,
27    /// Result (success/failure).
28    pub result: AuditResult,
29    /// Source IP.
30    pub source_ip: Option<String>,
31    /// Tenant ID.
32    pub tenant_id: Option<String>,
33    /// Additional metadata.
34    pub metadata: HashMap<String, String>,
35    /// Message.
36    pub message: Option<String>,
37}
38
39impl AuditLogEntry {
40    /// Create a new audit log entry.
41    pub fn new(event_type: AuditEventType, result: AuditResult) -> Self {
42        Self {
43            id: uuid::Uuid::new_v4().to_string(),
44            timestamp: Utc::now(),
45            event_type,
46            subject: None,
47            resource: None,
48            action: None,
49            result,
50            source_ip: None,
51            tenant_id: None,
52            metadata: HashMap::new(),
53            message: None,
54        }
55    }
56
57    /// Set subject.
58    pub fn with_subject(mut self, subject: String) -> Self {
59        self.subject = Some(subject);
60        self
61    }
62
63    /// Set resource.
64    pub fn with_resource(mut self, resource: String) -> Self {
65        self.resource = Some(resource);
66        self
67    }
68
69    /// Set action.
70    pub fn with_action(mut self, action: String) -> Self {
71        self.action = Some(action);
72        self
73    }
74
75    /// Set source IP.
76    pub fn with_source_ip(mut self, ip: String) -> Self {
77        self.source_ip = Some(ip);
78        self
79    }
80
81    /// Set tenant ID.
82    pub fn with_tenant_id(mut self, tenant_id: String) -> Self {
83        self.tenant_id = Some(tenant_id);
84        self
85    }
86
87    /// Add metadata.
88    pub fn with_metadata(mut self, key: String, value: String) -> Self {
89        self.metadata.insert(key, value);
90        self
91    }
92
93    /// Set message.
94    pub fn with_message(mut self, message: String) -> Self {
95        self.message = Some(message);
96        self
97    }
98}
99
100/// Audit event type.
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
102pub enum AuditEventType {
103    /// Authentication.
104    Authentication,
105    /// Authorization.
106    Authorization,
107    /// Data access.
108    DataAccess,
109    /// Data modification.
110    DataModification,
111    /// Configuration change.
112    ConfigChange,
113    /// User management.
114    UserManagement,
115    /// Role management.
116    RoleManagement,
117    /// Key management.
118    KeyManagement,
119    /// Encryption operation.
120    Encryption,
121    /// Decryption operation.
122    Decryption,
123    /// Compliance operation.
124    Compliance,
125    /// Security scan.
126    SecurityScan,
127    /// System event.
128    System,
129}
130
131/// Audit result.
132#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
133pub enum AuditResult {
134    /// Operation succeeded.
135    Success,
136    /// Operation failed.
137    Failure,
138    /// Access denied.
139    Denied,
140}
141
142/// Audit log severity.
143#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
144pub enum AuditSeverity {
145    /// Informational.
146    Info,
147    /// Warning.
148    Warning,
149    /// Error.
150    Error,
151    /// Critical.
152    Critical,
153}
154
155#[cfg(test)]
156mod tests {
157    use super::*;
158
159    #[test]
160    fn test_audit_log_entry_creation() {
161        let entry = AuditLogEntry::new(AuditEventType::Authentication, AuditResult::Success)
162            .with_subject("user-123".to_string())
163            .with_action("login".to_string())
164            .with_source_ip("192.168.1.1".to_string());
165
166        assert_eq!(entry.event_type, AuditEventType::Authentication);
167        assert_eq!(entry.result, AuditResult::Success);
168        assert_eq!(entry.subject, Some("user-123".to_string()));
169    }
170
171    #[test]
172    fn test_audit_entry_serialization() {
173        let entry = AuditLogEntry::new(AuditEventType::DataAccess, AuditResult::Success);
174        let json = serde_json::to_string(&entry).expect("Serialization failed");
175        let deserialized: AuditLogEntry =
176            serde_json::from_str(&json).expect("Deserialization failed");
177
178        assert_eq!(deserialized.event_type, entry.event_type);
179        assert_eq!(deserialized.result, entry.result);
180    }
181}