use crate::audit::{AuditEventType, AuditLogEntry, AuditResult};
use serde::{Deserialize, Serialize};
pub struct AuthenticationEvent {
subject: String,
method: Option<String>,
result: AuditResult,
reason: Option<String>,
}
impl AuthenticationEvent {
pub fn new(subject: String, result: AuditResult) -> Self {
Self {
subject,
method: None,
result,
reason: None,
}
}
pub fn with_method(mut self, method: String) -> Self {
self.method = Some(method);
self
}
pub fn with_reason(mut self, reason: String) -> Self {
self.reason = Some(reason);
self
}
pub fn build(self) -> AuditLogEntry {
let mut entry = AuditLogEntry::new(AuditEventType::Authentication, self.result)
.with_subject(self.subject);
if let Some(method) = self.method {
entry = entry.with_metadata("method".to_string(), method);
}
if let Some(reason) = self.reason {
entry = entry.with_message(reason);
}
entry
}
}
pub struct DataAccessEvent {
subject: String,
resource: String,
action: String,
result: AuditResult,
rows_accessed: Option<u64>,
}
impl DataAccessEvent {
pub fn new(subject: String, resource: String, action: String, result: AuditResult) -> Self {
Self {
subject,
resource,
action,
result,
rows_accessed: None,
}
}
pub fn with_rows_accessed(mut self, count: u64) -> Self {
self.rows_accessed = Some(count);
self
}
pub fn build(self) -> AuditLogEntry {
let mut entry = AuditLogEntry::new(AuditEventType::DataAccess, self.result)
.with_subject(self.subject)
.with_resource(self.resource)
.with_action(self.action);
if let Some(count) = self.rows_accessed {
entry = entry.with_metadata("rows_accessed".to_string(), count.to_string());
}
entry
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComplianceEvent {
pub event_type: String,
pub regulation: String,
pub subject: Option<String>,
pub data_subject: Option<String>,
pub result: AuditResult,
pub details: String,
}
impl ComplianceEvent {
pub fn new(event_type: String, regulation: String, result: AuditResult) -> Self {
Self {
event_type,
regulation,
subject: None,
data_subject: None,
result,
details: String::new(),
}
}
pub fn with_subject(mut self, subject: String) -> Self {
self.subject = Some(subject);
self
}
pub fn with_data_subject(mut self, data_subject: String) -> Self {
self.data_subject = Some(data_subject);
self
}
pub fn with_details(mut self, details: String) -> Self {
self.details = details;
self
}
pub fn build(self) -> AuditLogEntry {
let mut entry = AuditLogEntry::new(AuditEventType::Compliance, self.result)
.with_metadata("regulation".to_string(), self.regulation)
.with_metadata("event_type".to_string(), self.event_type)
.with_message(self.details);
if let Some(subject) = self.subject {
entry = entry.with_subject(subject);
}
if let Some(data_subject) = self.data_subject {
entry = entry.with_metadata("data_subject".to_string(), data_subject);
}
entry
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_authentication_event() {
let event = AuthenticationEvent::new("user-123".to_string(), AuditResult::Success)
.with_method("password".to_string())
.build();
assert_eq!(event.event_type, AuditEventType::Authentication);
assert_eq!(event.subject, Some("user-123".to_string()));
assert_eq!(event.metadata.get("method"), Some(&"password".to_string()));
}
#[test]
fn test_data_access_event() {
let event = DataAccessEvent::new(
"user-123".to_string(),
"dataset-456".to_string(),
"read".to_string(),
AuditResult::Success,
)
.with_rows_accessed(100)
.build();
assert_eq!(event.event_type, AuditEventType::DataAccess);
assert_eq!(
event.metadata.get("rows_accessed"),
Some(&"100".to_string())
);
}
}