Skip to content

Commit

Permalink
Merge pull request #255 from biscuit-auth/authorizer-debug
Browse files Browse the repository at this point in the history
Authorizer API improvements
  • Loading branch information
divarvel authored Dec 5, 2024
2 parents 3bd7a7b + 0328663 commit c8057ce
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 18 deletions.
46 changes: 33 additions & 13 deletions biscuit-auth/src/token/authorizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ mod snapshot;
/// used to check authorization policies on a token
///
/// can be created from [Biscuit::authorizer] or [Authorizer::new]
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct Authorizer {
pub(crate) authorizer_block_builder: BlockBuilder,
pub(crate) world: datalog::World,
Expand All @@ -31,10 +31,24 @@ pub struct Authorizer {
pub(crate) blocks: Option<Vec<Block>>,
pub(crate) public_key_to_block_id: HashMap<usize, Vec<usize>>,
pub(crate) limits: AuthorizerLimits,
pub(crate) execution_time: Duration,
pub(crate) execution_time: Option<Duration>,
}

impl Authorizer {
pub fn run(&mut self) -> Result<Duration, error::Token> {
match self.execution_time {
Some(execution_time) => Ok(execution_time),
None => {
let start = Instant::now();
self.world
.run_with_limits(&self.symbols, self.limits.clone())?;
let execution_time = start.elapsed();
self.execution_time = Some(execution_time);
Ok(execution_time)
}
}
}

pub(crate) fn from_token(token: &Biscuit) -> Result<Self, error::Token> {
AuthorizerBuilder::new().build(token)
}
Expand Down Expand Up @@ -62,7 +76,7 @@ impl Authorizer {
blocks: None,
public_key_to_block_id: HashMap::new(),
limits: AuthorizerLimits::default(),
execution_time: Duration::default(),
execution_time: None,
}
}

Expand Down Expand Up @@ -129,12 +143,13 @@ impl Authorizer {
where
error::Token: From<<R as TryInto<Rule>>::Error>,
{
let execution_time = self.run()?;
let mut limits = self.limits.clone();
limits.max_iterations -= self.world.iterations;
if self.execution_time >= limits.max_time {
if execution_time >= limits.max_time {
return Err(error::Token::RunLimit(error::RunLimit::Timeout));
}
limits.max_time -= self.execution_time;
limits.max_time -= execution_time;

self.query_with_limits(rule, limits)
}
Expand All @@ -152,11 +167,12 @@ impl Authorizer {
where
error::Token: From<<R as TryInto<Rule>>::Error>,
{
let execution_time = self.run()?;
let rule = rule.try_into()?.convert(&mut self.symbols);

let start = Instant::now();
let result = self.query_inner(rule, limits);
self.execution_time += start.elapsed();
self.execution_time = Some(start.elapsed() + execution_time);

result
}
Expand Down Expand Up @@ -218,12 +234,13 @@ impl Authorizer {
where
error::Token: From<<R as TryInto<Rule>>::Error>,
{
let execution_time = self.run()?;
let mut limits = self.limits.clone();
limits.max_iterations -= self.world.iterations;
if self.execution_time >= limits.max_time {
if execution_time >= limits.max_time {
return Err(error::Token::RunLimit(error::RunLimit::Timeout));
}
limits.max_time -= self.execution_time;
limits.max_time -= execution_time;

self.query_all_with_limits(rule, limits)
}
Expand All @@ -245,11 +262,12 @@ impl Authorizer {
where
error::Token: From<<R as TryInto<Rule>>::Error>,
{
let execution_time = self.run()?;
let rule = rule.try_into()?.convert(&mut self.symbols);

let start = Instant::now();
let result = self.query_all_inner(rule, limits);
self.execution_time += start.elapsed();
self.execution_time = Some(execution_time + start.elapsed());

result
}
Expand Down Expand Up @@ -289,7 +307,7 @@ impl Authorizer {
}

/// returns the elapsed execution time
pub fn execution_time(&self) -> Duration {
pub fn execution_time(&self) -> Option<Duration> {
self.execution_time
}

Expand All @@ -308,12 +326,13 @@ impl Authorizer {
/// on error, this can return a list of all the failed checks or deny policy
/// on success, it returns the index of the policy that matched
pub fn authorize(&mut self) -> Result<usize, error::Token> {
let execution_time = self.run()?;
let mut limits = self.limits.clone();
limits.max_iterations -= self.world.iterations;
if self.execution_time >= limits.max_time {
if execution_time >= limits.max_time {
return Err(error::Token::RunLimit(error::RunLimit::Timeout));
}
limits.max_time -= self.execution_time;
limits.max_time -= execution_time;

self.authorize_with_limits(limits)
}
Expand All @@ -327,9 +346,10 @@ impl Authorizer {
&mut self,
limits: AuthorizerLimits,
) -> Result<usize, error::Token> {
let execution_time = self.run()?;
let start = Instant::now();
let result = self.authorize_inner(limits);
self.execution_time += start.elapsed();
self.execution_time = Some(execution_time + start.elapsed());

result
}
Expand Down
5 changes: 3 additions & 2 deletions biscuit-auth/src/token/authorizer/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ impl super::Authorizer {
authorizer.authorizer_block_builder = authorizer_block_builder;
authorizer.policies = policies;
authorizer.limits = limits;
authorizer.execution_time = execution_time;
authorizer.execution_time =
Some(execution_time).filter(|_| execution_time > Duration::default());

let mut public_key_to_block_id: HashMap<usize, Vec<usize>> = HashMap::new();
let mut blocks = Vec::new();
Expand Down Expand Up @@ -207,7 +208,7 @@ impl super::Authorizer {

Ok(schema::AuthorizerSnapshot {
world,
execution_time: self.execution_time.as_nanos() as u64,
execution_time: self.execution_time.unwrap_or_default().as_nanos() as u64,
limits: schema::RunLimits {
max_facts: self.limits.max_facts,
max_iterations: self.limits.max_iterations,
Expand Down
6 changes: 4 additions & 2 deletions biscuit-auth/src/token/builder/authorizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{
collections::HashMap,
convert::TryInto,
fmt::Write,
time::{Duration, Instant, SystemTime},
time::{Duration, SystemTime},
};

use biscuit_parser::parser::parse_source;
Expand Down Expand Up @@ -384,9 +384,11 @@ impl AuthorizerBuilder {
world.rules.insert(usize::MAX, &rule_trusted_origins, rule);
}

/*
let start = Instant::now();
world.run_with_limits(&symbols, self.limits.clone())?;
let execution_time = start.elapsed();
*/

Ok(Authorizer {
authorizer_block_builder: self.authorizer_block_builder,
Expand All @@ -397,7 +399,7 @@ impl AuthorizerBuilder {
blocks,
public_key_to_block_id,
limits: self.limits,
execution_time,
execution_time: None,
})
}
}
Expand Down
3 changes: 2 additions & 1 deletion biscuit-auth/tests/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,14 @@ fn authorizer_macro() {
"#
);

let authorizer = b
let mut authorizer = b
.limits(RunLimits {
max_time: Duration::from_secs(10),
..Default::default()
})
.build_unauthenticated()
.unwrap();
authorizer.run().unwrap();
assert_eq!(
authorizer.dump_code(),
r#"appended(true);
Expand Down

0 comments on commit c8057ce

Please sign in to comment.