use async_trait::async_trait;
use crate::runtime::security::PolicyLintFinding;
use super::bundle::{PolicyBundleConfig, SignedBundle};
use super::{AuthzQuery, AuthzSnapshot, Decision};
#[async_trait]
pub trait PolicyEngine: Send + Sync {
async fn decide(&self, req: &AuthzQuery<'_>) -> Decision;
async fn explain(&self, req: &AuthzQuery<'_>) -> Decision {
self.decide(req).await
}
async fn lint(&self) -> Vec<PolicyLintFinding>;
async fn bundle(
&self,
cfg: &PolicyBundleConfig,
tenant_id: &str,
project_id: &str,
now_unix: i64,
) -> Option<SignedBundle>;
fn bundle_version(&self) -> String;
fn relationship_version(&self) -> String {
String::new()
}
}
#[async_trait]
impl PolicyEngine for AuthzSnapshot {
async fn decide(&self, req: &AuthzQuery<'_>) -> Decision {
self.casbin_authorize(req).await
}
async fn lint(&self) -> Vec<PolicyLintFinding> {
if self.policies.is_empty() {
return crate::runtime::security::lint_policies(&[]);
}
Vec::new()
}
async fn bundle(
&self,
cfg: &PolicyBundleConfig,
tenant_id: &str,
project_id: &str,
now_unix: i64,
) -> Option<SignedBundle> {
cfg.sign(self, tenant_id, project_id, now_unix)
}
fn bundle_version(&self) -> String {
self.version.clone()
}
fn relationship_version(&self) -> String {
self.relationship_version.clone()
}
}