diff --git a/biscuit-auth/src/token/authorizer.rs b/biscuit-auth/src/token/authorizer.rs index f43f1d01..a891555e 100644 --- a/biscuit-auth/src/token/authorizer.rs +++ b/biscuit-auth/src/token/authorizer.rs @@ -622,17 +622,6 @@ impl Authorizer { Ok(()) } - /// todo remove, it's covered in BuilderExt - /// adds a `allow if true` policy - pub fn allow(&mut self) -> Result<(), error::Token> { - self.add_policy("allow if true") - } - - /// adds a `deny if true` policy - pub fn deny(&mut self) -> Result<(), error::Token> { - self.add_policy("deny if true") - } - /// returns the elapsed execution time pub fn execution_time(&self) -> Duration { self.execution_time diff --git a/biscuit-auth/src/token/builder.rs b/biscuit-auth/src/token/builder.rs index 94360f75..a83dacb8 100644 --- a/biscuit-auth/src/token/builder.rs +++ b/biscuit-auth/src/token/builder.rs @@ -22,6 +22,9 @@ pub use crate::datalog::{ Unary as DatalogUnary, }; +mod authorizer; +pub use authorizer::*; + /// creates a Block content to append to an existing token #[derive(Clone, Debug, Default)] pub struct BlockBuilder { diff --git a/biscuit-auth/src/token/builder/authorizer.rs b/biscuit-auth/src/token/builder/authorizer.rs new file mode 100644 index 00000000..7feab78a --- /dev/null +++ b/biscuit-auth/src/token/builder/authorizer.rs @@ -0,0 +1,117 @@ +use std::{collections::HashMap, convert::TryInto, time::SystemTime}; + +use crate::{ + builder_ext::{AuthorizerExt, BuilderExt}, + error, Authorizer, Biscuit, PublicKey, +}; + +use super::{BlockBuilder, Check, Fact, Policy, Rule, Scope, Term}; + +#[derive(Clone, Debug, Default)] +pub struct AuthorizerBuilder<'a> { + block: BlockBuilder, + policies: Vec, + token: Option<&'a Biscuit>, +} + +impl<'a> AuthorizerBuilder<'a> { + pub fn new() -> AuthorizerBuilder<'a> { + AuthorizerBuilder::default() + } + + pub fn add_fact>(&mut self, fact: F) -> Result<(), error::Token> + where + error::Token: From<>::Error>, + { + self.block.add_fact(fact) + } + + pub fn add_rule>(&mut self, rule: R) -> Result<(), error::Token> + where + error::Token: From<>::Error>, + { + self.block.add_rule(rule) + } + + pub fn add_check>(&mut self, check: C) -> Result<(), error::Token> + where + error::Token: From<>::Error>, + { + self.block.add_check(check) + } + + pub fn add_code>(&mut self, source: T) -> Result<(), error::Token> { + self.add_code_with_params(source, HashMap::new(), HashMap::new()) + } + + /// Add datalog code to the builder, performing parameter subsitution as required + /// Unknown parameters are ignored + pub fn add_code_with_params>( + &mut self, + source: T, + params: HashMap, + scope_params: HashMap, + ) -> Result<(), error::Token> { + self.block + .add_code_with_params(source, params, scope_params) + } + + pub fn add_scope(&mut self, scope: Scope) { + self.block.add_scope(scope); + } + + /// add a policy to the authorizer + pub fn add_policy>(&mut self, policy: P) -> Result<(), error::Token> + where + error::Token: From<

>::Error>, + { + let policy = policy.try_into()?; + policy.validate_parameters()?; + self.policies.push(policy); + Ok(()) + } + + pub fn add_token(&mut self, token: &'a Biscuit) { + self.token = Some(token); + } + + pub fn build(self) -> Result { + let authorizer = Authorizer::new(); + Ok(authorizer) + } +} + +impl<'a> BuilderExt for AuthorizerBuilder<'a> { + fn add_resource(&mut self, name: &str) { + self.block.add_resource(name); + } + fn check_resource(&mut self, name: &str) { + self.block.check_resource(name); + } + fn add_operation(&mut self, name: &str) { + self.block.add_operation(name); + } + fn check_operation(&mut self, name: &str) { + self.block.check_operation(name); + } + fn check_resource_prefix(&mut self, prefix: &str) { + self.block.check_resource_prefix(prefix); + } + + fn check_resource_suffix(&mut self, suffix: &str) { + self.block.check_resource_suffix(suffix); + } + + fn check_expiration_date(&mut self, exp: SystemTime) { + self.block.check_expiration_date(exp); + } +} + +impl<'a> AuthorizerExt for AuthorizerBuilder<'a> { + fn add_allow_all(&mut self) { + self.add_policy("allow if true").unwrap(); + } + fn add_deny_all(&mut self) { + self.add_policy("deny if true").unwrap(); + } +}