use crate::auth::UserContext;
use crate::error::AppError;
use super::pdp::{Decision, Pdp};
pub fn require(pdp: &Pdp, ctx: &UserContext, permission: &str) -> Result<(), AppError> {
if !pdp.ready() {
return Err(AppError::ServiceUnavailable {
message: "authorization service not ready".to_string(),
});
}
match pdp.check(&ctx.subject, ctx.acr.as_deref(), permission) {
Decision::Allow => Ok(()),
Decision::Deny { .. } => Err(AppError::Forbidden {
message: "forbidden".to_string(),
}),
Decision::NeedsStepUp { min_acr } => Err(AppError::Forbidden {
message: format!("step_up_required:{min_acr}"),
}),
Decision::NeedsQuorum => Err(AppError::Forbidden {
message: "quorum_required".to_string(),
}),
}
}
pub fn evaluate(pdp: &Pdp, ctx: &UserContext, permission: &str) -> (Decision, Result<(), AppError>) {
if !pdp.ready() {
return (
Decision::Deny { reason: super::pdp::DenyReason::NoBinding },
Err(AppError::ServiceUnavailable {
message: "authorization service not ready".to_string(),
}),
);
}
let decision = pdp.check(&ctx.subject, ctx.acr.as_deref(), permission);
let result = match &decision {
Decision::Allow => Ok(()),
Decision::Deny { .. } => Err(AppError::Forbidden { message: "forbidden".to_string() }),
Decision::NeedsStepUp { min_acr } => {
Err(AppError::Forbidden { message: format!("step_up_required:{min_acr}") })
}
Decision::NeedsQuorum => Err(AppError::Forbidden { message: "quorum_required".to_string() }),
};
(decision, result)
}