use std::sync::{Arc, Mutex};
use crate::action::Action;
use crate::decision::{Decision, DenyReason};
use crate::enforcer::Authorizer;
use crate::resource::ResourceRef;
use crate::subject::Subject;
#[derive(Clone)]
pub struct MockAuthorizer {
decision: Decision,
call_count: Arc<Mutex<usize>>,
}
impl MockAuthorizer {
pub fn allow() -> Self {
Self {
decision: Decision::Allow {
obligations: vec![],
},
call_count: Arc::new(Mutex::new(0)),
}
}
pub fn deny(reason: DenyReason) -> Self {
Self {
decision: Decision::Deny { reason },
call_count: Arc::new(Mutex::new(0)),
}
}
#[must_use]
pub fn call_count(&self) -> usize {
*self.call_count.lock().unwrap()
}
}
impl Authorizer for MockAuthorizer {
fn authorize<'a>(
&'a self,
_subject: &'a Subject,
_action: &'a Action,
_resource: &'a ResourceRef,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Decision> + Send + 'a>> {
let decision = self.decision.clone();
let count = self.call_count.clone();
Box::pin(async move {
*count.lock().unwrap() += 1;
decision
})
}
}
#[must_use]
pub fn test_subject(actor_id: &str, roles: &[&str]) -> Subject {
Subject {
actor_id: actor_id.to_owned(),
tenant_id: None,
roles: roles.iter().map(|r| r.to_string()).collect(),
attributes: Default::default(),
}
}
#[must_use]
pub fn test_subject_with_tenant(actor_id: &str, tenant_id: &str, roles: &[&str]) -> Subject {
Subject {
actor_id: actor_id.to_owned(),
tenant_id: Some(tenant_id.to_owned()),
roles: roles.iter().map(|r| r.to_string()).collect(),
attributes: Default::default(),
}
}