use cedar_policy::Effect;
use cedar_policy_core::ast::{Policy, PolicySet};
use super::compiler::{compile, CompileResult, Footprint, Result};
use crate::{
term_factory::{and, any_true, eq, not, some_of},
SymEnv,
};
pub fn compile_with_effect(
effect: Effect,
policy: &Policy,
symenv: &SymEnv,
) -> Result<Option<CompileResult>> {
if policy.effect() == effect {
Ok(Some(compile(&policy.condition(), symenv)?))
} else {
Ok(None)
}
}
pub fn satisfied_policies(
effect: Effect,
policies: &PolicySet,
env: &SymEnv,
) -> Result<CompileResult> {
let ress = policies
.policies()
.filter_map(|p| compile_with_effect(effect, p, env).transpose())
.collect::<Result<Vec<CompileResult>>>()?;
Ok(CompileResult {
term: any_true(
|term| eq(term, some_of(true.into())),
ress.iter().map(|res| res.term.clone()),
),
footprint: Footprint::flatten(ress.into_iter().map(|res| res.footprint)),
})
}
pub fn is_authorized(policies: &PolicySet, env: &SymEnv) -> Result<CompileResult> {
let forbids = satisfied_policies(Effect::Forbid, policies, env)?;
let permits = satisfied_policies(Effect::Permit, policies, env)?;
Ok(CompileResult {
term: and(permits.term, not(forbids.term)),
footprint: permits.footprint.chain(forbids.footprint),
})
}