use crate::{EvaluationSession, PolicyEvalResult, SecurityRuleMetadata};
use async_trait::async_trait;
pub struct PolicyBatchItem<'a, Resource, Context> {
pub resource: &'a Resource,
pub context: &'a Context,
}
pub struct EvalCtx<'a, Subject, Resource, Action, Context> {
pub session: &'a EvaluationSession,
pub subject: &'a Subject,
pub action: &'a Action,
pub resource: &'a Resource,
pub context: &'a Context,
}
pub struct BatchEvalCtx<'a, Subject, Resource, Action, Context> {
pub session: &'a EvaluationSession,
pub subject: &'a Subject,
pub action: &'a Action,
pub items: &'a [PolicyBatchItem<'a, Resource, Context>],
}
#[async_trait]
pub trait Policy<Subject, Resource, Action, Context>: Send + Sync
where
Subject: Sync,
Resource: Sync,
Action: Sync,
Context: Sync,
{
async fn evaluate(
&self,
ctx: &EvalCtx<'_, Subject, Resource, Action, Context>,
) -> PolicyEvalResult;
async fn evaluate_batch<'item>(
&self,
ctx: &BatchEvalCtx<'item, Subject, Resource, Action, Context>,
) -> Vec<PolicyEvalResult> {
let mut results = Vec::with_capacity(ctx.items.len());
for item in ctx.items {
let item_ctx = EvalCtx {
session: ctx.session,
subject: ctx.subject,
action: ctx.action,
resource: item.resource,
context: item.context,
};
results.push(self.evaluate(&item_ctx).await);
}
results
}
fn policy_type(&self) -> &str;
fn security_rule(&self) -> SecurityRuleMetadata {
SecurityRuleMetadata::default()
}
}
#[async_trait]
impl<S, R, A, C> Policy<S, R, A, C> for Box<dyn Policy<S, R, A, C>>
where
S: Send + Sync,
R: Send + Sync,
A: Send + Sync,
C: Send + Sync,
{
async fn evaluate(&self, ctx: &EvalCtx<'_, S, R, A, C>) -> PolicyEvalResult {
(**self).evaluate(ctx).await
}
async fn evaluate_batch<'item>(
&self,
ctx: &BatchEvalCtx<'item, S, R, A, C>,
) -> Vec<PolicyEvalResult> {
(**self).evaluate_batch(ctx).await
}
fn policy_type(&self) -> &str {
(**self).policy_type()
}
fn security_rule(&self) -> SecurityRuleMetadata {
(**self).security_rule()
}
}