use crate::domain::permission::{
PermissionAction, PermissionChecker, PermissionConfig, PermissionError, PermissionLifecycle, PermissionProvider,
PolicyManager, RolePolicy,
};
use async_trait::async_trait;
use std::collections::HashMap;
use std::sync::RwLock;
pub struct MemoryPermissionProvider {
config: PermissionConfig,
policies: RwLock<HashMap<String, RolePolicy>>,
}
impl MemoryPermissionProvider {
pub fn new() -> Self {
Self {
config: PermissionConfig::default(),
policies: RwLock::new(HashMap::new()),
}
}
}
impl Default for MemoryPermissionProvider {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl PermissionChecker for MemoryPermissionProvider {
async fn check(&self, role: &str, table: &str, action: PermissionAction) -> Result<bool, PermissionError> {
if role == self.config.admin_role {
return Ok(true);
}
let guard = self.policies.read().unwrap();
let policy = guard
.get(role)
.ok_or_else(|| PermissionError::RoleNotFound(role.into()))?;
Ok(policy.allows(table, &action))
}
}
#[async_trait]
impl PolicyManager for MemoryPermissionProvider {
async fn get_policy(&self, role: &str) -> Result<Option<RolePolicy>, PermissionError> {
let guard = self.policies.read().unwrap();
Ok(guard.get(role).cloned())
}
async fn refresh(&self) -> Result<(), PermissionError> {
Ok(())
}
}
#[async_trait]
impl PermissionLifecycle for MemoryPermissionProvider {
async fn health_check(&self) -> anyhow::Result<()> {
Ok(())
}
async fn shutdown(&self) {
let mut guard = self.policies.write().unwrap();
guard.clear();
}
}
impl PermissionProvider for MemoryPermissionProvider {}