use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::time::SystemTime;
use thiserror::Error;
use uvb_core::TenantId;
#[derive(Debug, Error)]
pub enum AuditError {
#[error("storage error: {0}")]
Storage(String),
#[error("serialization error: {0}")]
Serialization(String),
#[error("decryption error: {0}")]
Decryption(String),
#[error("configuration error: {0}")]
Configuration(String),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AuditEvent {
pub id: String,
pub timestamp: SystemTime,
pub event_type: AuditEventType,
pub user_id: Option<String>,
pub tenant_id: TenantId,
pub transaction_id: Option<String>,
pub factor_id: Option<String>,
pub success: bool,
pub ip_address: Option<String>,
pub user_agent: Option<String>,
pub error_code: Option<String>,
pub metadata: serde_json::Value,
pub previous_hash: Option<String>,
pub entry_hash: Option<String>,
pub geo_country: Option<String>,
pub geo_region: Option<String>,
pub geo_city: Option<String>,
pub geo_latitude: Option<f64>,
pub geo_longitude: Option<f64>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub enum AuditEventType {
VerificationStarted,
VerificationSucceeded,
VerificationFailed,
FactorChallengeIssued,
FactorVerified,
FactorFailed,
FactorEnrolled,
FactorUnenrolled,
FactorSuspended,
FactorRevoked,
SessionCreated,
SessionExtended,
SessionExpired,
SessionRevoked,
PolicyUpdated,
ConfigurationChanged,
SecretRotated,
RateLimitExceeded,
SuspiciousActivity,
AccountLockout,
}
#[async_trait]
pub trait AuditLogStore: Send + Sync {
async fn log(&self, event: AuditEvent) -> Result<(), AuditError>;
async fn query(&self, filters: AuditQueryFilters) -> Result<Vec<AuditEvent>, AuditError>;
async fn count(&self, filters: AuditQueryFilters) -> Result<u64, AuditError>;
}
#[derive(Clone, Debug, Default)]
pub struct AuditQueryFilters {
pub user_id: Option<String>,
pub tenant_id: Option<TenantId>,
pub event_types: Option<Vec<AuditEventType>>,
pub start_time: Option<SystemTime>,
pub end_time: Option<SystemTime>,
pub success: Option<bool>,
pub limit: Option<usize>,
pub offset: Option<usize>,
}