Skip to content

Commit

Permalink
create an AuthorizerBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
Geal committed Nov 27, 2024
1 parent 255abf2 commit ccec5d5
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 11 deletions.
11 changes: 0 additions & 11 deletions biscuit-auth/src/token/authorizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions biscuit-auth/src/token/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
117 changes: 117 additions & 0 deletions biscuit-auth/src/token/builder/authorizer.rs
Original file line number Diff line number Diff line change
@@ -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<Policy>,
token: Option<&'a Biscuit>,
}

impl<'a> AuthorizerBuilder<'a> {
pub fn new() -> AuthorizerBuilder<'a> {
AuthorizerBuilder::default()
}

pub fn add_fact<F: TryInto<Fact>>(&mut self, fact: F) -> Result<(), error::Token>
where
error::Token: From<<F as TryInto<Fact>>::Error>,
{
self.block.add_fact(fact)
}

pub fn add_rule<R: TryInto<Rule>>(&mut self, rule: R) -> Result<(), error::Token>
where
error::Token: From<<R as TryInto<Rule>>::Error>,
{
self.block.add_rule(rule)
}

pub fn add_check<C: TryInto<Check>>(&mut self, check: C) -> Result<(), error::Token>
where
error::Token: From<<C as TryInto<Check>>::Error>,
{
self.block.add_check(check)
}

pub fn add_code<T: AsRef<str>>(&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<T: AsRef<str>>(
&mut self,
source: T,
params: HashMap<String, Term>,
scope_params: HashMap<String, PublicKey>,
) -> 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<P: TryInto<Policy>>(&mut self, policy: P) -> Result<(), error::Token>
where
error::Token: From<<P as TryInto<Policy>>::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<Authorizer, error::Token> {
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();
}
}

0 comments on commit ccec5d5

Please sign in to comment.