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 smartcore::linalg::basic::matrix::DenseMatrix;
use smartcore::ensemble::random_forest_classifier::RandomForestClassifier;
use smartcore::model_selection::train_test_split;
use crate::behavioral::AccessEvent;
use chrono::{DateTime, Utc, Timelike, Datelike};
use serde::Serialize;
use crate::ml_metrics::{ModelMetrics, ConfusionMatrix};
use std::time::Instant;
use std::collections::HashMap;

#[derive(Debug, Serialize)]
pub struct MLPrediction {
    pub is_anomaly: bool,
    pub confidence: f64,
    pub features: Vec<String>,
    pub timestamp: DateTime<Utc>,
}

pub struct MLAnalyzer {
    model: Option<RandomForestClassifier<f64, i32, DenseMatrix<f64>, Vec<i32>>>,
    feature_names: Vec<String>,
}

impl MLAnalyzer {
    pub fn new() -> Self {
        Self {
            model: None,
            feature_names: vec![
                "hour_of_day".to_string(),
                "day_of_week".to_string(),
                "duration_seconds".to_string(),
                "resource_frequency".to_string(),
                "success_rate".to_string(),
            ],
        }
    }

    pub fn train(&mut self, events: &[AccessEvent], anomalies: &[AccessEvent]) {
        let (features, labels) = self.prepare_training_data(events, anomalies);
        
        if features.is_empty() {
            return;
        }

        let x = DenseMatrix::from_2d_vec(&features);
        let y = labels.iter().map(|&x| x as i32).collect::<Vec<_>>();

        // Train-test split
        let (x_train, _x_test, y_train, _y_test) = train_test_split(
            &x, 
            &y, 
            0.2, 
            true,
            Some(42)
        );

        // Train model
        let model = RandomForestClassifier::fit(
            &x_train, 
            &y_train,
            Default::default()
        ).unwrap();

        self.model = Some(model);
    }

    pub fn predict(&self, event: &AccessEvent) -> Option<MLPrediction> {
        let model = self.model.as_ref()?;
        
        let features = self.extract_features(event);
        let x = DenseMatrix::from_2d_vec(&vec![features]);
        
        let prediction = model.predict(&x).ok()?;
        
        // Basit bir güven skoru hesapla
        let confidence = if prediction[0] == 1 { 0.8 } else { 0.2 };

        Some(MLPrediction {
            is_anomaly: prediction[0] == 1,
            confidence,
            features: self.feature_names.clone(),
            timestamp: Utc::now(),
        })
    }

    fn extract_features(&self, event: &AccessEvent) -> Vec<f64> {
        vec![
            event.timestamp.hour() as f64,
            event.timestamp.weekday().num_days_from_monday() as f64,
            event.duration.as_secs_f64(),
            1.0, // Resource frequency (placeholder)
            if event.success { 1.0 } else { 0.0 },
        ]
    }

    fn prepare_training_data(&self, events: &[AccessEvent], anomalies: &[AccessEvent]) 
        -> (Vec<Vec<f64>>, Vec<f64>) 
    {
        let mut features = Vec::new();
        let mut labels = Vec::new();

        for event in events {
            features.push(self.extract_features(event));
            
            // Eğer event bir anomaliye denk geliyorsa label'ı 1, değilse 0
            let is_anomaly = anomalies.iter().any(|a| {
                (event.timestamp - a.timestamp).num_minutes().abs() < 1
            });
            
            labels.push(if is_anomaly { 1.0 } else { 0.0 });
        }

        (features, labels)
    }

    pub fn evaluate_model(&self, test_events: &[AccessEvent], test_anomalies: &[AccessEvent]) -> Option<ModelMetrics> {
        let model = self.model.as_ref()?;
        let start_time = Instant::now();
        
        let (features, actual_labels) = self.prepare_training_data(test_events, test_anomalies);
        if features.is_empty() {
            return None;
        }

        let x = DenseMatrix::from_2d_vec(&features);
        let predictions = model.predict(&x).ok()?;
        
        // Confusion matrix hesapla
        let mut confusion_matrix = ConfusionMatrix::new();
        for (pred, actual) in predictions.iter().zip(actual_labels.iter()) {
            confusion_matrix.update(
                (*pred as i32) == 1,
                (*actual as i32) == 1
            );
        }

        // Feature importance hesapla
        let feature_importance = self.calculate_feature_importance();

        Some(ModelMetrics {
            model_id: format!("rf_model_{}", Utc::now().timestamp()),
            timestamp: Utc::now(),
            accuracy: confusion_matrix.accuracy(),
            precision: confusion_matrix.precision(),
            recall: confusion_matrix.recall(),
            f1_score: confusion_matrix.f1_score(),
            confusion_matrix,
            feature_importance,
            training_duration: start_time.elapsed(),
        })
    }

    fn calculate_feature_importance(&self) -> HashMap<String, f64> {
        let mut importance = HashMap::new();
        
        // Her özellik için basit bir önem skoru hesapla
        for (idx, name) in self.feature_names.iter().enumerate() {
            let score = 1.0 / (idx + 1) as f64; // Basit bir skor hesaplama
            importance.insert(name.clone(), score);
        }

        // Skorları normalize et
        let total: f64 = importance.values().sum();
        for score in importance.values_mut() {
            *score /= total;
        }

        importance
    }

    pub fn predict_with_threshold(&self, event: &AccessEvent, threshold: f64) -> Option<MLPrediction> {
        let prediction = self.predict(event)?;
        
        // Eğer güven skoru threshold'un altındaysa anomali olarak işaretle
        let is_anomaly = prediction.confidence > threshold;
        
        Some(MLPrediction {
            is_anomaly,
            ..prediction
        })
    }

    pub fn update_model(&mut self, new_events: &[AccessEvent], new_anomalies: &[AccessEvent]) -> Option<ModelMetrics> {
        // Modeli yeni verilerle güncelle
        self.train(new_events, new_anomalies);
        
        // Model performansını değerlendir
        self.evaluate_model(new_events, new_anomalies)
    }
}