spawn-access-control 0.1.12

A Rust library for access control management with WebAssembly support, including role-based access control (RBAC), permissions, and audit logging.
Documentation
// src/audit_log.rs
use serde::{Serialize, Deserialize};
use chrono::{DateTime, Utc};
use crate::error::AuditError;
use std::sync::Arc;
use tokio::sync::RwLock;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditLogEntry {
    pub id: String,
    pub timestamp: DateTime<Utc>,
    pub event_type: AuditEventType,
    pub user: String,
    pub resource: String,
    pub action: String,
    pub result: ActionResult,
    pub metadata: AuditMetadata,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AuditEventType {
    Authentication,
    Authorization,
    ResourceAccess,
    Configuration,
    SystemEvent,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ActionResult {
    Success,
    Failure { reason: String },
    Warning { message: String },
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditMetadata {
    pub ip_address: String,
    pub user_agent: String,
    pub session_id: Option<String>,
    pub request_id: String,
    pub additional_info: serde_json::Value,
}

pub struct AuditLogger {
    entries: Arc<RwLock<Vec<AuditLogEntry>>>,
    config: AuditConfig,
}

#[derive(Clone)]
pub struct AuditConfig {
    pub retention_days: u32,
    pub log_level: AuditLogLevel,
    pub storage_path: String,
}

#[derive(Clone, PartialEq)]
pub enum AuditLogLevel {
    Low,
    Medium,
    High,
}

impl AuditLogger {
    pub fn new(config: AuditConfig) -> Self {
        Self {
            entries: Arc::new(RwLock::new(Vec::new())),
            config,
        }
    }

    pub async fn log_event(&self, entry: AuditLogEntry) -> Result<(), AuditError> {
        // Log seviyesi kontrolü
        if !self.should_log(&entry.event_type) {
            return Ok(());
        }

        let mut entries = self.entries.write().await;
        entries.push(entry.clone());

        // Retention policy uygula
        self.apply_retention_policy(&mut entries).await?;

        // Disk'e kaydet
        self.persist_to_storage(&entry).await?;

        Ok(())
    }

    async fn apply_retention_policy(&self, entries: &mut Vec<AuditLogEntry>) -> Result<(), AuditError> {
        let retention_date = Utc::now() - chrono::Duration::days(self.config.retention_days as i64);
        entries.retain(|entry| entry.timestamp > retention_date);
        Ok(())
    }

    async fn persist_to_storage(&self, entry: &AuditLogEntry) -> Result<(), AuditError> {
        // JSON formatında diske kaydet
        let json = serde_json::to_string_pretty(entry).map_err(|e| AuditError {
            error_type: crate::error::AuditErrorType::StorageFailed,
            message: e.to_string(),
            timestamp: Utc::now().timestamp(),
        })?;

        // Dosya adı oluştur
        let filename = format!("{}/audit_{}.json", 
            self.config.storage_path,
            entry.timestamp.format("%Y%m%d_%H%M%S"));

        // Dosyaya yaz
        tokio::fs::write(&filename, json).await.map_err(|e| AuditError {
            error_type: crate::error::AuditErrorType::StorageFailed,
            message: e.to_string(),
            timestamp: Utc::now().timestamp(),
        })?;

        Ok(())
    }

    fn should_log(&self, event_type: &AuditEventType) -> bool {
        match self.config.log_level {
            AuditLogLevel::Low => matches!(event_type, AuditEventType::Authentication | AuditEventType::Authorization),
            AuditLogLevel::Medium => !matches!(event_type, AuditEventType::SystemEvent),
            AuditLogLevel::High => true,
        }
    }
}