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
use crate::monitoring::{self, HealthAlert};
use chrono::{DateTime, Utc};
use serde::{Serialize, Deserialize};
use tokio::sync::broadcast;
use std::collections::HashMap;
use async_trait::async_trait;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AlertSeverity {
    Critical,
    Warning,
    Info,
}

impl std::fmt::Display for AlertSeverity {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Critical => write!(f, "CRITICAL"),
            Self::Warning => write!(f, "WARNING"),
            Self::Info => write!(f, "INFO"),
        }
    }
}

impl From<&monitoring::AlertSeverity> for AlertSeverity {
    fn from(severity: &monitoring::AlertSeverity) -> Self {
        match severity {
            monitoring::AlertSeverity::Critical => AlertSeverity::Critical,
            monitoring::AlertSeverity::Warning => AlertSeverity::Warning,
            monitoring::AlertSeverity::Info => AlertSeverity::Info,
        }
    }
}

#[derive(Debug, Clone, Serialize)]
pub struct AlertNotification {
    pub alert: HealthAlert,
    pub notification_channels: Vec<NotificationChannel>,
    pub escalation_level: EscalationLevel,
    pub context: AlertContext,
}

#[derive(Debug, Clone, Serialize)]
pub enum NotificationChannel {
    Email(String),
    Slack(String),
    WebHook(String),
    PagerDuty(String),
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
pub enum EscalationLevel {
    Low,
    Medium,
    High,
    Critical,
}

#[derive(Debug, Clone, Serialize)]
pub struct AlertContext {
    pub incident_id: String,
    pub affected_components: Vec<String>,
    pub additional_info: HashMap<String, String>,
    pub created_at: DateTime<Utc>,
}

pub struct AlertManager {
    config: AlertConfig,
    alert_tx: broadcast::Sender<AlertNotification>,
    notification_handlers: Vec<NotificationHandlerType>,
}

#[derive(Clone)]
pub struct AlertConfig {
    pub alert_ttl: chrono::Duration,
    pub max_alerts_per_window: usize,
    pub notification_channels: Vec<NotificationChannel>,
    pub escalation_policies: HashMap<AlertSeverity, EscalationPolicy>,
}

#[derive(Clone)]
pub struct EscalationPolicy {
    pub initial_delay: chrono::Duration,
    pub repeat_interval: chrono::Duration,
    pub max_escalations: usize,
    pub notification_channels: Vec<NotificationChannel>,
}

#[async_trait]
pub trait NotificationHandler: Send + Sync {
    async fn send_notification(&self, notification: &AlertNotification) -> Result<(), NotificationError>;
}

#[derive(Debug, thiserror::Error)]
pub enum NotificationError {
    #[error("Failed to send notification: {0}")]
    SendError(String),
    
    #[error("Channel configuration error: {0}")]
    ConfigError(String),
    
    #[error("Rate limit exceeded")]
    RateLimitExceeded,
}

#[derive(Clone)]
pub enum NotificationHandlerType {
    Email(crate::notification::EmailNotificationHandler),
    Slack(crate::notification::SlackNotificationHandler),
}

impl NotificationHandlerType {
    async fn send_notification(&self, notification: &AlertNotification) -> Result<(), NotificationError> {
        match self {
            Self::Email(handler) => handler.send_notification(notification).await,
            Self::Slack(handler) => handler.send_notification(notification).await,
        }
    }
}

impl AlertManager {
    pub fn new(config: AlertConfig) -> Self {
        let (tx, _) = broadcast::channel(100);
        Self {
            config,
            alert_tx: tx,
            notification_handlers: Vec::new(),
        }
    }

    pub fn register_handler(&mut self, handler: NotificationHandlerType) {
        self.notification_handlers.push(handler);
    }

    pub async fn process_alert(&self, alert: HealthAlert) -> Result<(), NotificationError> {
        let notification = self.create_notification(alert);
        
        // Alert'i broadcast et
        let _ = self.alert_tx.send(notification.clone());

        // Notification handler'ları çalıştır
        for handler in &self.notification_handlers {
            handler.send_notification(&notification).await?;
        }

        Ok(())
    }

    fn create_notification(&self, alert: HealthAlert) -> AlertNotification {
        let severity = AlertSeverity::from(&alert.severity);
        let channels = self.get_notification_channels(&severity);
        
        AlertNotification {
            alert,
            notification_channels: channels,
            escalation_level: self.determine_escalation_level(&severity),
            context: AlertContext {
                incident_id: uuid::Uuid::new_v4().to_string(),
                affected_components: Vec::new(),
                additional_info: HashMap::new(),
                created_at: Utc::now(),
            },
        }
    }

    fn get_notification_channels(&self, severity: &AlertSeverity) -> Vec<NotificationChannel> {
        self.config
            .escalation_policies
            .get(severity)
            .map(|policy| policy.notification_channels.clone())
            .unwrap_or_else(|| self.config.notification_channels.clone())
    }

    fn determine_escalation_level(&self, severity: &AlertSeverity) -> EscalationLevel {
        match severity {
            AlertSeverity::Critical => EscalationLevel::Critical,
            AlertSeverity::Warning => EscalationLevel::High,
            AlertSeverity::Info => EscalationLevel::Low,
        }
    }
}