use tokio::sync::RwLock;
use std::sync::Arc;
use crate::{AccessControl, Resource, Role, error::AccessError};
use tracing::{info, error};
pub struct AsyncAccessManager {
access_controls: Arc<RwLock<Vec<AccessControl>>>,
metrics: Arc<RwLock<AccessMetrics>>,
}
impl AsyncAccessManager {
pub fn new() -> Self {
Self {
access_controls: Arc::new(RwLock::new(Vec::new())),
metrics: Arc::new(RwLock::new(AccessMetrics::new())),
}
}
pub async fn add_access_control(&self, control: AccessControl) -> Result<(), AccessError> {
let mut controls = self.access_controls.write().await;
controls.push(control);
info!("New access control added");
Ok(())
}
pub async fn check_access(&self, resource: &Resource) -> Result<bool, AccessError> {
let controls = self.access_controls.read().await;
let mut metrics = self.metrics.write().await;
metrics.access_checks += 1;
let result = controls.iter().any(|ac| ac.has_access(resource));
if result {
metrics.successful_checks += 1;
}
Ok(result)
}
pub async fn get_metrics(&self) -> AccessMetrics {
self.metrics.read().await.clone()
}
}
#[derive(Clone, Debug)]
struct AccessMetrics {
access_checks: u64,
successful_checks: u64,
}
impl AccessMetrics {
fn new() -> Self {
Self {
access_checks: 0,
successful_checks: 0,
}
}
}