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 std::collections::HashSet;
use serde::{Serialize, Deserialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Permission {
    pub name: String,
    pub resource: String,
    pub actions: HashSet<Action>,
    pub conditions: Vec<PermissionCondition>,
}

#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub enum Action {
    Read,
    Write,
    Delete,
    Execute,
    Admin,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PermissionCondition {
    TimeBasedAccess {
        start_hour: u8,
        end_hour: u8,
        allowed_days: Vec<Weekday>,
    },
    IPBasedAccess {
        allowed_ips: Vec<String>,
        allowed_ranges: Vec<String>,
    },
    MFARequired,
}

impl Permission {
    pub fn new(name: &str, resource: &str) -> Self {
        Self {
            name: name.to_string(),
            resource: resource.to_string(),
            actions: HashSet::new(),
            conditions: Vec::new(),
        }
    }

    pub fn add_action(&mut self, action: Action) {
        self.actions.insert(action);
    }

    pub fn add_condition(&mut self, condition: PermissionCondition) {
        self.conditions.push(condition);
    }

    pub fn check_conditions(&self, context: &AccessContext) -> bool {
        for condition in &self.conditions {
            match condition {
                PermissionCondition::TimeBasedAccess { start_hour, end_hour, allowed_days } => {
                    if !self.check_time_based_access(*start_hour, *end_hour, allowed_days) {
                        return false;
                    }
                }
                PermissionCondition::IPBasedAccess { allowed_ips, allowed_ranges } => {
                    if !self.check_ip_based_access(context.ip_address, allowed_ips, allowed_ranges) {
                        return false;
                    }
                }
                PermissionCondition::MFARequired => {
                    if !context.mfa_verified {
                        return false;
                    }
                }
            }
        }
        true
    }

    fn check_time_based_access(&self, start_hour: u8, end_hour: u8, allowed_days: &[Weekday]) -> bool {
        use chrono::{Local, Weekday};
        
        let now = Local::now();
        let current_hour = now.hour() as u8;
        let current_day = now.weekday();

        current_hour >= start_hour && 
        current_hour <= end_hour && 
        allowed_days.contains(&current_day)
    }

    fn check_ip_based_access(&self, ip: &str, allowed_ips: &[String], allowed_ranges: &[String]) -> bool {
        if allowed_ips.contains(&ip.to_string()) {
            return true;
        }

        // IP range kontrolü
        for range in allowed_ranges {
            if self.ip_in_range(ip, range) {
                return true;
            }
        }
        false
    }

    fn ip_in_range(&self, ip: &str, range: &str) -> bool {
        // IP range kontrolü implementasyonu
        // CIDR notation kontrolü yapılabilir
        true // Şimdilik basit implementasyon
    }
}

#[derive(Debug)]
pub struct AccessContext {
    pub ip_address: String,
    pub timestamp: i64,
    pub mfa_verified: bool,
    pub user_agent: String,
}