From f7fe86f9dee214a9fc0dcfb16a2cff9fb32ac2a4 Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Wed, 27 Nov 2024 18:03:14 +0100 Subject: [PATCH 1/5] refactor the builder API --- biscuit-auth/src/token/authorizer.rs | 82 +++++++++++--------- biscuit-auth/src/token/builder.rs | 62 +++++++-------- biscuit-auth/src/token/builder/biscuit.rs | 91 ++++++++++++++--------- biscuit-auth/src/token/builder/block.rs | 56 ++++++++------ biscuit-auth/src/token/builder_ext.rs | 14 ++-- biscuit-auth/src/token/mod.rs | 23 +++--- 6 files changed, 180 insertions(+), 148 deletions(-) diff --git a/biscuit-auth/src/token/authorizer.rs b/biscuit-auth/src/token/authorizer.rs index f43f1d01..3fe78241 100644 --- a/biscuit-auth/src/token/authorizer.rs +++ b/biscuit-auth/src/token/authorizer.rs @@ -209,22 +209,25 @@ impl Authorizer { } /// Add the rules, facts, and checks of another `BlockBuilder`. - pub fn merge_block(&mut self, other: BlockBuilder) { - self.authorizer_block_builder.merge(other) + pub fn merge_block(&mut self, other: BlockBuilder) -> Result<(), error::Token> { + self.authorizer_block_builder = self.authorizer_block_builder.merge(other); + Ok(()) } pub fn add_fact>(&mut self, fact: F) -> Result<(), error::Token> where error::Token: From<>::Error>, { - self.authorizer_block_builder.add_fact(fact) + self.authorizer_block_builder = self.authorizer_block_builder.add_fact(fact)?; + Ok(()) } pub fn add_rule>(&mut self, rule: Ru) -> Result<(), error::Token> where error::Token: From<>::Error>, { - self.authorizer_block_builder.add_rule(rule) + self.authorizer_block_builder = self.authorizer_block_builder.add_rule(rule)?; + Ok(()) } pub fn add_check>(&mut self, check: C) -> Result<(), error::Token> @@ -608,7 +611,7 @@ impl Authorizer { /// adds a fact with the current time pub fn set_time(&mut self) { let fact = fact("time", &[date(&SystemTime::now())]); - self.authorizer_block_builder.add_fact(fact).unwrap(); + self.authorizer_block_builder = self.authorizer_block_builder.add_fact(fact).unwrap(); } /// add a policy to the authorizer @@ -1213,15 +1216,18 @@ impl TryFrom for Authorizer { let mut authorizer = Self::new(); for fact in facts.into_iter() { - authorizer.authorizer_block_builder.add_fact(fact)?; + authorizer.authorizer_block_builder = + authorizer.authorizer_block_builder.add_fact(fact)?; } for rule in rules.into_iter() { - authorizer.authorizer_block_builder.add_rule(rule)?; + authorizer.authorizer_block_builder = + authorizer.authorizer_block_builder.add_rule(rule)?; } for check in checks.into_iter() { - authorizer.authorizer_block_builder.add_check(check)?; + authorizer.authorizer_block_builder = + authorizer.authorizer_block_builder.add_check(check)?; } for policy in policies { @@ -1271,11 +1277,12 @@ impl AuthorizerPolicies { pub type AuthorizerLimits = RunLimits; impl BuilderExt for Authorizer { - fn add_resource(&mut self, name: &str) { + fn add_resource(mut self, name: &str) -> Self { let f = fact("resource", &[string(name)]); self.add_fact(f).unwrap(); + self } - fn check_resource(&mut self, name: &str) { + fn check_resource(mut self, name: &str) -> Self { self.add_check(Check { queries: vec![rule( "resource_check", @@ -1285,12 +1292,14 @@ impl BuilderExt for Authorizer { kind: CheckKind::One, }) .unwrap(); + self } - fn add_operation(&mut self, name: &str) { + fn add_operation(mut self, name: &str) -> Self { let f = fact("operation", &[string(name)]); self.add_fact(f).unwrap(); + self } - fn check_operation(&mut self, name: &str) { + fn check_operation(mut self, name: &str) -> Self { self.add_check(Check { queries: vec![rule( "operation_check", @@ -1300,8 +1309,9 @@ impl BuilderExt for Authorizer { kind: CheckKind::One, }) .unwrap(); + self } - fn check_resource_prefix(&mut self, prefix: &str) { + fn check_resource_prefix(mut self, prefix: &str) -> Self { let check = constrained_rule( "prefix", &[var("resource")], @@ -1320,9 +1330,10 @@ impl BuilderExt for Authorizer { kind: CheckKind::One, }) .unwrap(); + self } - fn check_resource_suffix(&mut self, suffix: &str) { + fn check_resource_suffix(mut self, suffix: &str) -> Self { let check = constrained_rule( "suffix", &[var("resource")], @@ -1341,9 +1352,10 @@ impl BuilderExt for Authorizer { kind: CheckKind::One, }) .unwrap(); + self } - fn check_expiration_date(&mut self, exp: SystemTime) { + fn check_expiration_date(mut self, exp: SystemTime) -> Self { let check = constrained_rule( "expiration", &[var("time")], @@ -1362,6 +1374,7 @@ impl BuilderExt for Authorizer { kind: CheckKind::One, }) .unwrap(); + self } } @@ -1522,10 +1535,11 @@ mod tests { use crate::Biscuit; use crate::KeyPair; let keypair = KeyPair::new(Algorithm::Ed25519); - let mut builder = Biscuit::builder(); - builder.add_fact("user(\"John Doe\", 42)").unwrap(); - - let biscuit = builder.build(&keypair).unwrap(); + let biscuit = Biscuit::builder() + .add_fact("user(\"John Doe\", 42)") + .unwrap() + .build(&keypair) + .unwrap(); let mut authorizer = biscuit.authorizer().unwrap(); let res: Vec<(String, i64)> = authorizer @@ -1542,10 +1556,11 @@ mod tests { use crate::Biscuit; use crate::KeyPair; let keypair = KeyPair::new(Algorithm::Ed25519); - let mut builder = Biscuit::builder(); - builder.add_fact("user(\"John Doe\")").unwrap(); - - let biscuit = builder.build(&keypair).unwrap(); + let biscuit = Biscuit::builder() + .add_fact("user(\"John Doe\")") + .unwrap() + .build(&keypair) + .unwrap(); let mut authorizer = biscuit.authorizer().unwrap(); let res: Vec<(String,)> = authorizer.query("data($name) <- user($name)").unwrap(); @@ -1559,25 +1574,24 @@ mod tests { let root = KeyPair::new(Algorithm::Ed25519); let external = KeyPair::new(Algorithm::Ed25519); - let mut builder = Biscuit::builder(); let mut scope_params = HashMap::new(); scope_params.insert("external_pub".to_string(), external.public()); - builder + + let biscuit1 = Biscuit::builder() .add_code_with_params( r#"right("read"); - check if group("admin") trusting {external_pub}; - "#, + check if group("admin") trusting {external_pub}; + "#, HashMap::new(), scope_params, ) + .unwrap() + .build(&root) .unwrap(); - let biscuit1 = builder.build(&root).unwrap(); - let req = biscuit1.third_party_request().unwrap(); - let mut builder = BlockBuilder::new(); - builder + let builder = BlockBuilder::new() .add_code( r#"group("admin"); check if right("read"); @@ -1741,8 +1755,7 @@ mod tests { fn authorizer_display_before_and_after_authorization() { let root = KeyPair::new(Algorithm::Ed25519); - let mut token_builder = BiscuitBuilder::new(); - token_builder + let token = BiscuitBuilder::new() .add_code( r#" authority_fact(true); @@ -1750,8 +1763,9 @@ mod tests { check if authority_fact(true), authority_rule(true); "#, ) + .unwrap() + .build(&root) .unwrap(); - let token = token_builder.build(&root).unwrap(); let mut authorizer = token.authorizer().unwrap(); authorizer diff --git a/biscuit-auth/src/token/builder.rs b/biscuit-auth/src/token/builder.rs index 6af2a438..98ed41fd 100644 --- a/biscuit-auth/src/token/builder.rs +++ b/biscuit-auth/src/token/builder.rs @@ -249,7 +249,7 @@ mod tests { .unwrap(); let mut scope_params = HashMap::new(); scope_params.insert("pk".to_string(), pubkey); - builder + builder = builder .add_code_with_params( r#"fact({p1}, "value"); rule($head_var) <- f1($head_var), {p2} > 0 trusting {pk}; @@ -270,52 +270,46 @@ check if true trusting ed25519/6e9e6d5a75cf0c0e87ec1256b4dfed0ca3ba452912d213fcc #[test] fn forbid_unbound_parameters() { - let mut builder = BlockBuilder::new(); + let builder = BlockBuilder::new(); let mut fact = Fact::try_from("fact({p1}, {p4})").unwrap(); fact.set("p1", "hello").unwrap(); - let res = builder.add_fact(fact); + let res = builder.clone().add_fact(fact); assert_eq!( - res, - Err(error::Token::Language( - biscuit_parser::error::LanguageError::Parameters { - missing_parameters: vec!["p4".to_string()], - unused_parameters: vec![], - } - )) + res.unwrap_err(), + error::Token::Language(biscuit_parser::error::LanguageError::Parameters { + missing_parameters: vec!["p4".to_string()], + unused_parameters: vec![], + }) ); let mut rule = Rule::try_from( "fact($var1, {p2}) <- f1($var1, $var3), f2({p2}, $var3, {p4}), $var3.starts_with({p2})", ) .unwrap(); rule.set("p2", "hello").unwrap(); - let res = builder.add_rule(rule); + let res = builder.clone().add_rule(rule); assert_eq!( - res, - Err(error::Token::Language( - biscuit_parser::error::LanguageError::Parameters { - missing_parameters: vec!["p4".to_string()], - unused_parameters: vec![], - } - )) + res.unwrap_err(), + error::Token::Language(biscuit_parser::error::LanguageError::Parameters { + missing_parameters: vec!["p4".to_string()], + unused_parameters: vec![], + }) ); let mut check = Check::try_from("check if {p4}, {p3}").unwrap(); check.set("p3", true).unwrap(); - let res = builder.add_check(check); + let res = builder.clone().add_check(check); assert_eq!( - res, - Err(error::Token::Language( - biscuit_parser::error::LanguageError::Parameters { - missing_parameters: vec!["p4".to_string()], - unused_parameters: vec![], - } - )) + res.unwrap_err(), + error::Token::Language(biscuit_parser::error::LanguageError::Parameters { + missing_parameters: vec!["p4".to_string()], + unused_parameters: vec![], + }) ); } #[test] fn forbid_unbound_parameters_in_set_code() { - let mut builder = BlockBuilder::new(); + let builder = BlockBuilder::new(); let mut params = HashMap::new(); params.insert("p1".to_string(), "hello".into()); params.insert("p2".to_string(), 1i64.into()); @@ -330,13 +324,11 @@ check if true trusting ed25519/6e9e6d5a75cf0c0e87ec1256b4dfed0ca3ba452912d213fcc ); assert_eq!( - res, - Err(error::Token::Language( - biscuit_parser::error::LanguageError::Parameters { - missing_parameters: vec!["p3".to_string()], - unused_parameters: vec![], - } - )) - ) + res.unwrap_err(), + error::Token::Language(biscuit_parser::error::LanguageError::Parameters { + missing_parameters: vec!["p3".to_string()], + unused_parameters: vec![], + }) + ); } } diff --git a/biscuit-auth/src/token/builder/biscuit.rs b/biscuit-auth/src/token/builder/biscuit.rs index 8d1fd82e..5bcdce3e 100644 --- a/biscuit-auth/src/token/builder/biscuit.rs +++ b/biscuit-auth/src/token/builder/biscuit.rs @@ -25,65 +25,77 @@ impl BiscuitBuilder { } } - pub fn merge(&mut self, other: BlockBuilder) { - self.inner.merge(other) + pub fn merge(mut self, other: BlockBuilder) -> Self { + self.inner = self.inner.merge(other); + self } - pub fn add_fact>(&mut self, fact: F) -> Result<(), error::Token> + pub fn add_fact>(mut self, fact: F) -> Result where error::Token: From<>::Error>, { - self.inner.add_fact(fact) + self.inner = self.inner.add_fact(fact)?; + Ok(self) } - pub fn add_rule>(&mut self, rule: Ru) -> Result<(), error::Token> + pub fn add_rule>(mut self, rule: Ru) -> Result where error::Token: From<>::Error>, { - self.inner.add_rule(rule) + self.inner = self.inner.add_rule(rule)?; + Ok(self) } - pub fn add_check>(&mut self, check: C) -> Result<(), error::Token> + pub fn add_check>(mut self, check: C) -> Result where error::Token: From<>::Error>, { - self.inner.add_check(check) + self.inner = self.inner.add_check(check)?; + Ok(self) } - pub fn add_code>(&mut self, source: T) -> Result<(), error::Token> { - self.inner - .add_code_with_params(source, HashMap::new(), HashMap::new()) + pub fn add_code>(mut self, source: T) -> Result { + self.inner = self + .inner + .add_code_with_params(source, HashMap::new(), HashMap::new())?; + Ok(self) } pub fn add_code_with_params>( - &mut self, + mut self, source: T, params: HashMap, scope_params: HashMap, - ) -> Result<(), error::Token> { - self.inner - .add_code_with_params(source, params, scope_params) + ) -> Result { + self.inner = self + .inner + .add_code_with_params(source, params, scope_params)?; + Ok(self) } - pub fn add_scope(&mut self, scope: Scope) { - self.inner.add_scope(scope); + pub fn add_scope(mut self, scope: Scope) -> Self { + self.inner = self.inner.add_scope(scope); + self } #[cfg(test)] - pub(crate) fn add_right(&mut self, resource: &str, right: &str) { + pub(crate) fn add_right(self, resource: &str, right: &str) -> Self { use crate::builder::fact; use super::string; - let _ = self.add_fact(fact("right", &[string(resource), string(right)])); + self.add_fact(fact("right", &[string(resource), string(right)])) + .unwrap() } - pub fn set_context(&mut self, context: String) { - self.inner.set_context(context); + pub fn set_context(mut self, context: String) -> Self { + self.inner = self.inner.set_context(context); + self } - pub fn set_root_key_id(&mut self, root_key_id: u32) { + pub fn set_root_key_id(mut self, root_key_id: u32) -> Self { self.root_key_id = Some(root_key_id); + self } /// returns all of the datalog loaded in the biscuit builder @@ -154,25 +166,32 @@ impl fmt::Display for BiscuitBuilder { } impl BuilderExt for BiscuitBuilder { - fn add_resource(&mut self, name: &str) { - self.inner.add_resource(name); + fn add_resource(mut self, name: &str) -> Self { + self.inner = self.inner.add_resource(name); + self } - fn check_resource(&mut self, name: &str) { - self.inner.check_resource(name); + fn check_resource(mut self, name: &str) -> Self { + self.inner = self.inner.check_resource(name); + self } - fn check_resource_prefix(&mut self, prefix: &str) { - self.inner.check_resource_prefix(prefix); + fn check_resource_prefix(mut self, prefix: &str) -> Self { + self.inner = self.inner.check_resource_prefix(prefix); + self } - fn check_resource_suffix(&mut self, suffix: &str) { - self.inner.check_resource_suffix(suffix); + fn check_resource_suffix(mut self, suffix: &str) -> Self { + self.inner = self.inner.check_resource_suffix(suffix); + self } - fn add_operation(&mut self, name: &str) { - self.inner.add_operation(name); + fn add_operation(mut self, name: &str) -> Self { + self.inner = self.inner.add_operation(name); + self } - fn check_operation(&mut self, name: &str) { - self.inner.check_operation(name); + fn check_operation(mut self, name: &str) -> Self { + self.inner = self.inner.check_operation(name); + self } - fn check_expiration_date(&mut self, date: SystemTime) { - self.inner.check_expiration_date(date); + fn check_expiration_date(mut self, date: SystemTime) -> Self { + self.inner = self.inner.check_expiration_date(date); + self } } diff --git a/biscuit-auth/src/token/builder/block.rs b/biscuit-auth/src/token/builder/block.rs index 4967d07e..677d11bf 100644 --- a/biscuit-auth/src/token/builder/block.rs +++ b/biscuit-auth/src/token/builder/block.rs @@ -26,17 +26,18 @@ impl BlockBuilder { BlockBuilder::default() } - pub fn merge(&mut self, mut other: BlockBuilder) { + pub fn merge(mut self, mut other: BlockBuilder) -> Self { self.facts.append(&mut other.facts); self.rules.append(&mut other.rules); self.checks.append(&mut other.checks); if let Some(c) = other.context { - self.set_context(c); + self.context = Some(c); } + self } - pub fn add_fact>(&mut self, fact: F) -> Result<(), error::Token> + pub fn add_fact>(mut self, fact: F) -> Result where error::Token: From<>::Error>, { @@ -44,41 +45,41 @@ impl BlockBuilder { fact.validate()?; self.facts.push(fact); - Ok(()) + Ok(self) } - pub fn add_rule>(&mut self, rule: R) -> Result<(), error::Token> + pub fn add_rule>(mut self, rule: R) -> Result where error::Token: From<>::Error>, { let rule = rule.try_into()?; rule.validate_parameters()?; self.rules.push(rule); - Ok(()) + Ok(self) } - pub fn add_check>(&mut self, check: C) -> Result<(), error::Token> + pub fn add_check>(mut self, check: C) -> Result where error::Token: From<>::Error>, { let check = check.try_into()?; check.validate_parameters()?; self.checks.push(check); - Ok(()) + Ok(self) } - pub fn add_code>(&mut self, source: T) -> Result<(), error::Token> { + pub fn add_code>(self, source: T) -> Result { 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, + mut self, source: T, params: HashMap, scope_params: HashMap, - ) -> Result<(), error::Token> { + ) -> Result { let input = source.as_ref(); let source_result = parse_block_source(input).map_err(|e| { @@ -164,15 +165,17 @@ impl BlockBuilder { self.checks.push(check); } - Ok(()) + Ok(self) } - pub fn add_scope(&mut self, scope: Scope) { + pub fn add_scope(mut self, scope: Scope) -> Self { self.scopes.push(scope); + self } - pub fn set_context(&mut self, context: String) { + pub fn set_context(mut self, context: String) -> Self { self.context = Some(context); + self } pub(crate) fn build(self, mut symbols: SymbolTable) -> Block { @@ -247,7 +250,7 @@ impl BlockBuilder { // still used in tests but does not make sense for the public API #[cfg(test)] - pub(crate) fn check_right(&mut self, right: &str) { + pub(crate) fn check_right(self, right: &str) -> Result { use crate::builder::{pred, string, var}; use super::rule; @@ -263,7 +266,7 @@ impl BlockBuilder { ], ); - let _ = self.add_check(check); + self.add_check(check) } } @@ -286,10 +289,11 @@ impl fmt::Display for BlockBuilder { } impl BuilderExt for BlockBuilder { - fn add_resource(&mut self, name: &str) { + fn add_resource(mut self, name: &str) -> Self { self.facts.push(fact("resource", &[string(name)])); + self } - fn check_resource(&mut self, name: &str) { + fn check_resource(mut self, name: &str) -> Self { self.checks.push(Check { queries: vec![rule( "resource_check", @@ -298,11 +302,13 @@ impl BuilderExt for BlockBuilder { )], kind: CheckKind::One, }); + self } - fn add_operation(&mut self, name: &str) { + fn add_operation(mut self, name: &str) -> Self { self.facts.push(fact("operation", &[string(name)])); + self } - fn check_operation(&mut self, name: &str) { + fn check_operation(mut self, name: &str) -> Self { self.checks.push(Check { queries: vec![rule( "operation_check", @@ -311,8 +317,9 @@ impl BuilderExt for BlockBuilder { )], kind: CheckKind::One, }); + self } - fn check_resource_prefix(&mut self, prefix: &str) { + fn check_resource_prefix(mut self, prefix: &str) -> Self { let check = constrained_rule( "prefix", &[var("resource")], @@ -330,9 +337,10 @@ impl BuilderExt for BlockBuilder { queries: vec![check], kind: CheckKind::One, }); + self } - fn check_resource_suffix(&mut self, suffix: &str) { + fn check_resource_suffix(mut self, suffix: &str) -> Self { let check = constrained_rule( "suffix", &[var("resource")], @@ -350,9 +358,10 @@ impl BuilderExt for BlockBuilder { queries: vec![check], kind: CheckKind::One, }); + self } - fn check_expiration_date(&mut self, exp: SystemTime) { + fn check_expiration_date(mut self, exp: SystemTime) -> Self { let empty: Vec = Vec::new(); let ops = vec![ Op::Value(var("time")), @@ -370,5 +379,6 @@ impl BuilderExt for BlockBuilder { queries: vec![check], kind: CheckKind::One, }); + self } } diff --git a/biscuit-auth/src/token/builder_ext.rs b/biscuit-auth/src/token/builder_ext.rs index 021cb44a..2983d6c3 100644 --- a/biscuit-auth/src/token/builder_ext.rs +++ b/biscuit-auth/src/token/builder_ext.rs @@ -1,13 +1,13 @@ use std::time::SystemTime; pub trait BuilderExt { - fn add_resource(&mut self, name: &str); - fn check_resource(&mut self, name: &str); - fn check_resource_prefix(&mut self, prefix: &str); - fn check_resource_suffix(&mut self, suffix: &str); - fn add_operation(&mut self, name: &str); - fn check_operation(&mut self, name: &str); - fn check_expiration_date(&mut self, date: SystemTime); + fn add_resource(self, name: &str) -> Self; + fn check_resource(self, name: &str) -> Self; + fn check_resource_prefix(self, prefix: &str) -> Self; + fn check_resource_suffix(self, suffix: &str) -> Self; + fn add_operation(self, name: &str) -> Self; + fn check_operation(self, name: &str) -> Self; + fn check_expiration_date(self, date: SystemTime) -> Self; } pub trait AuthorizerExt { diff --git a/biscuit-auth/src/token/mod.rs b/biscuit-auth/src/token/mod.rs index b0aa3d40..07498b69 100644 --- a/biscuit-auth/src/token/mod.rs +++ b/biscuit-auth/src/token/mod.rs @@ -882,24 +882,21 @@ mod tests { let mut rng: StdRng = SeedableRng::seed_from_u64(0); let root = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - - builder.add_right("/folder1/file1", "read"); - builder.add_right("/folder1/file1", "write"); - builder.add_right("/folder1/file2", "read"); - builder.add_right("/folder1/file2", "write"); - builder.add_right("/folder2/file3", "read"); - - let biscuit1 = builder + let biscuit1 = Biscuit::builder() + .add_right("/folder1/file1", "read") + .add_right("/folder1/file1", "write") + .add_right("/folder1/file2", "read") + .add_right("/folder1/file2", "write") + .add_right("/folder2/file3", "read") .build_with_rng(&root, default_symbol_table(), &mut rng) .unwrap(); println!("biscuit1 (authority): {}", biscuit1); - let mut block2 = BlockBuilder::new(); - - block2.check_resource_prefix("/folder1/"); - block2.check_right("read"); + let block2 = BlockBuilder::new() + .check_resource_prefix("/folder1/") + .check_right("read") + .unwrap(); let keypair2 = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); let biscuit2 = biscuit1.append_with_keypair(&keypair2, block2).unwrap(); From e0948d5b5df7807a32ffc49bd8393c0ec4080b28 Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Wed, 27 Nov 2024 18:15:02 +0100 Subject: [PATCH 2/5] use the new API in tests --- biscuit-auth/src/token/mod.rs | 183 +++++++++++--------------- biscuit-auth/src/token/third_party.rs | 14 +- 2 files changed, 82 insertions(+), 115 deletions(-) diff --git a/biscuit-auth/src/token/mod.rs b/biscuit-auth/src/token/mod.rs index 07498b69..78fd96c0 100644 --- a/biscuit-auth/src/token/mod.rs +++ b/biscuit-auth/src/token/mod.rs @@ -720,13 +720,13 @@ mod tests { let root = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); let serialized1 = { - let mut builder = Biscuit::builder(); - - builder.add_fact("right(\"file1\", \"read\")").unwrap(); - builder.add_fact("right(\"file2\", \"read\")").unwrap(); - builder.add_fact("right(\"file1\", \"write\")").unwrap(); - - let biscuit1 = builder + let biscuit1 = Biscuit::builder() + .add_fact("right(\"file1\", \"read\")") + .unwrap() + .add_fact("right(\"file2\", \"read\")") + .unwrap() + .add_fact("right(\"file1\", \"write\")") + .unwrap() .build_with_rng(&root, default_symbol_table(), &mut rng) .unwrap(); @@ -772,9 +772,7 @@ mod tests { let biscuit1_deser = Biscuit::from(&serialized1, root.public()).unwrap(); // new check: can only have read access1 - let mut block2 = BlockBuilder::new(); - - block2 + let block2 = BlockBuilder::new() .add_check(rule( "check1", &[var("resource")], @@ -803,9 +801,7 @@ mod tests { let biscuit2_deser = Biscuit::from(&serialized2, root.public()).unwrap(); // new check: can only access file1 - let mut block3 = BlockBuilder::new(); - - block3 + let block3 = BlockBuilder::new() .add_check(rule( "check2", &[string("file1")], @@ -963,21 +959,18 @@ mod tests { let mut rng: StdRng = SeedableRng::seed_from_u64(0); let root = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - - builder.add_right("file1", "read"); - builder.add_right("file2", "read"); - - let biscuit1 = builder + let biscuit1 = Biscuit::builder() + .add_right("file1", "read") + .add_right("file2", "read") .build_with_rng(&root, default_symbol_table(), &mut rng) .unwrap(); println!("biscuit1 (authority): {}", biscuit1); - let mut block2 = BlockBuilder::new(); - - block2.check_expiration_date(SystemTime::now() + Duration::from_secs(30)); - block2.add_fact("key(1234)").unwrap(); + let block2 = BlockBuilder::new() + .check_expiration_date(SystemTime::now() + Duration::from_secs(30)) + .add_fact("key(1234)") + .unwrap(); let keypair2 = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); let biscuit2 = biscuit1.append_with_keypair(&keypair2, block2).unwrap(); @@ -1021,24 +1014,21 @@ mod tests { fn sealed_token() { let mut rng: StdRng = SeedableRng::seed_from_u64(0); let root = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - - builder.add_right("/folder1/file1", "read"); - builder.add_right("/folder1/file1", "write"); - builder.add_right("/folder1/file2", "read"); - builder.add_right("/folder1/file2", "write"); - builder.add_right("/folder2/file3", "read"); - - let biscuit1 = builder + let biscuit1 = Biscuit::builder() + .add_right("/folder1/file1", "read") + .add_right("/folder1/file1", "write") + .add_right("/folder1/file2", "read") + .add_right("/folder1/file2", "write") + .add_right("/folder2/file3", "read") .build_with_rng(&root, default_symbol_table(), &mut rng) .unwrap(); println!("biscuit1 (authority): {}", biscuit1); - let mut block2 = BlockBuilder::new(); - - block2.check_resource_prefix("/folder1/"); - block2.check_right("read"); + let block2 = BlockBuilder::new() + .check_resource_prefix("/folder1/") + .check_right("read") + .unwrap(); let keypair2 = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); let biscuit2 = biscuit1.append_with_keypair(&keypair2, block2).unwrap(); @@ -1086,19 +1076,13 @@ mod tests { let mut rng: StdRng = SeedableRng::seed_from_u64(1234); let root = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - - builder + let biscuit1 = Biscuit::builder() .add_fact(fact("right", &[string("file1"), string("read")])) - .unwrap(); - builder + .unwrap() .add_fact(fact("right", &[string("file2"), string("read")])) - .unwrap(); - builder + .unwrap() .add_fact(fact("right", &[string("file1"), string("write")])) - .unwrap(); - - let biscuit1 = builder + .unwrap() .build_with_rng(&root, default_symbol_table(), &mut rng) .unwrap(); println!("{}", biscuit1); @@ -1134,30 +1118,28 @@ mod tests { let mut rng: StdRng = SeedableRng::seed_from_u64(0); let root = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - - builder.add_right("file1", "read"); - builder.add_right("file2", "read"); - builder.add_fact("key(0000)").unwrap(); - - let biscuit1 = builder + let biscuit1 = Biscuit::builder() + .add_right("file1", "read") + .add_right("file2", "read") + .add_fact("key(0000)") + .unwrap() .build_with_rng(&root, default_symbol_table(), &mut rng) .unwrap(); println!("biscuit1 (authority): {}", biscuit1); - let mut block2 = BlockBuilder::new(); - - block2.check_expiration_date(SystemTime::now() + Duration::from_secs(30)); - block2.add_fact("key(1234)").unwrap(); + let block2 = BlockBuilder::new() + .check_expiration_date(SystemTime::now() + Duration::from_secs(30)) + .add_fact("key(1234)") + .unwrap(); let keypair2 = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); let biscuit2 = biscuit1.append_with_keypair(&keypair2, block2).unwrap(); - let mut block3 = BlockBuilder::new(); - - block3.check_expiration_date(SystemTime::now() + Duration::from_secs(10)); - block3.add_fact("key(5678)").unwrap(); + let block3 = BlockBuilder::new() + .check_expiration_date(SystemTime::now() + Duration::from_secs(10)) + .add_fact("key(5678)") + .unwrap(); let keypair3 = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); let biscuit3 = biscuit2.append_with_keypair(&keypair3, block3).unwrap(); @@ -1222,24 +1204,21 @@ mod tests { let mut rng: StdRng = SeedableRng::seed_from_u64(0); let root = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - - builder + let biscuit1 = Biscuit::builder() .add_check(check( &[pred("resource", &[string("hello")])], CheckKind::One, )) - .unwrap(); - - let biscuit1 = builder + .unwrap() .build_with_rng(&root, default_symbol_table(), &mut rng) .unwrap(); println!("biscuit1 (authority): {}", biscuit1); // new check: can only have read access1 - let mut block2 = BlockBuilder::new(); - block2.add_fact(fact("check1", &[string("test")])).unwrap(); + let block2 = BlockBuilder::new() + .add_fact(fact("check1", &[string("test")])) + .unwrap(); let keypair2 = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); let biscuit2 = biscuit1.append_with_keypair(&keypair2, block2).unwrap(); @@ -1326,16 +1305,15 @@ mod tests { let mut rng: StdRng = SeedableRng::seed_from_u64(0); let root = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - builder.add_fact("bytes(hex:0102AB)").unwrap(); - let biscuit1 = builder + let biscuit1 = Biscuit::builder() + .add_fact("bytes(hex:0102AB)") + .unwrap() .build_with_rng(&root, default_symbol_table(), &mut rng) .unwrap(); println!("biscuit1 (authority): {}", biscuit1); - let mut block2 = BlockBuilder::new(); - block2 + let block2 = BlockBuilder::new() .add_rule("has_bytes($0) <- bytes($0), { hex:00000000, hex:0102AB }.contains($0)") .unwrap(); let keypair2 = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); @@ -1373,20 +1351,15 @@ mod tests { let root = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); let serialized1 = { - let mut builder = Biscuit::builder(); - - builder + let biscuit1 = Biscuit::builder() .add_fact("right(\"/folder1/file1\", \"read\")") - .unwrap(); - builder + .unwrap() .add_fact("right(\"/folder1/file1\", \"write\")") - .unwrap(); - builder + .unwrap() .add_fact("right(\"/folder2/file1\", \"read\")") - .unwrap(); - builder.add_check("check if operation(\"read\")").unwrap(); - - let biscuit1 = builder + .unwrap() + .add_check("check if operation(\"read\")") + .unwrap() .build_with_rng(&root, default_symbol_table(), &mut rng) .unwrap(); @@ -1403,20 +1376,18 @@ mod tests { let biscuit1_deser = Biscuit::from(&serialized1, |_| Ok(root.public())).unwrap(); // new check: can only have read access1 - let mut block2 = BlockBuilder::new(); + let block2 = BlockBuilder::new() // Bypass `check if operation("read")` from authority block - block2 .add_rule("operation(\"read\") <- operation($any)") - .unwrap(); + .unwrap() // Bypass `check if resource($file), $file.starts_with("/folder1/")` from block #1 - block2 .add_rule("resource(\"/folder1/\") <- resource($any)") - .unwrap(); + .unwrap() // Add missing rights - block2.add_rule("right($file, $right) <- right($any1, $any2), resource($file), operation($right)") + .add_rule("right($file, $right) <- right($any1, $any2), resource($file), operation($right)") .unwrap(); let keypair2 = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); @@ -1458,21 +1429,17 @@ mod tests { let mut rng: StdRng = SeedableRng::seed_from_u64(0); let root = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - - builder.add_check("check if fact($v), $v < 1").unwrap(); - - let biscuit1 = builder + let biscuit1 = Biscuit::builder() + .add_check("check if fact($v), $v < 1") + .unwrap() .build_with_rng(&root, default_symbol_table(), &mut rng) .unwrap(); println!("biscuit1 (authority): {}", biscuit1); - let mut builder = Biscuit::builder(); - - builder.add_check("check all fact($v), $v < 1").unwrap(); - - let biscuit2 = builder + let biscuit2 = Biscuit::builder() + .add_check("check all fact($v), $v < 1") + .unwrap() .build_with_rng(&root, default_symbol_table(), &mut rng) .unwrap(); @@ -1579,13 +1546,13 @@ mod tests { fn verified_unverified_consistency() { let mut rng: StdRng = SeedableRng::seed_from_u64(0); let root = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - - builder.add_fact("right(\"file1\", \"read\")").unwrap(); - builder.add_fact("right(\"file2\", \"read\")").unwrap(); - builder.add_fact("right(\"file1\", \"write\")").unwrap(); - - let biscuit1 = builder + let biscuit1 = Biscuit::builder() + .add_fact("right(\"file1\", \"read\")") + .unwrap() + .add_fact("right(\"file2\", \"read\")") + .unwrap() + .add_fact("right(\"file1\", \"write\")") + .unwrap() .build_with_rng(&root, default_symbol_table(), &mut rng) .unwrap(); diff --git a/biscuit-auth/src/token/third_party.rs b/biscuit-auth/src/token/third_party.rs index e5b7ea62..acd022a2 100644 --- a/biscuit-auth/src/token/third_party.rs +++ b/biscuit-auth/src/token/third_party.rs @@ -159,13 +159,13 @@ mod tests { fn third_party_request_roundtrip() { let mut rng: rand::rngs::StdRng = rand::SeedableRng::seed_from_u64(0); let root = KeyPair::new_with_rng(crate::builder::Algorithm::Ed25519, &mut rng); - let mut builder = crate::Biscuit::builder(); - - builder.add_fact("right(\"file1\", \"read\")").unwrap(); - builder.add_fact("right(\"file2\", \"read\")").unwrap(); - builder.add_fact("right(\"file1\", \"write\")").unwrap(); - - let biscuit1 = builder + let biscuit1 = crate::Biscuit::builder() + .add_fact("right(\"file1\", \"read\")") + .unwrap() + .add_fact("right(\"file2\", \"read\")") + .unwrap() + .add_fact("right(\"file1\", \"write\")") + .unwrap() .build_with_rng(&root, crate::token::default_symbol_table(), &mut rng) .unwrap(); let req = biscuit1.third_party_request().unwrap(); From cdf646d39c4d752ec4899fbe117975d57af32144 Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Wed, 27 Nov 2024 18:44:30 +0100 Subject: [PATCH 3/5] update tests --- biscuit-auth/benches/token.rs | 373 ++++++++++++++------------- biscuit-auth/examples/testcases.rs | 27 +- biscuit-auth/examples/third_party.rs | 14 +- biscuit-auth/src/token/authorizer.rs | 22 +- biscuit-auth/tests/macros.rs | 6 +- biscuit-auth/tests/rights.rs | 32 +-- biscuit-capi/src/lib.rs | 2 +- biscuit-quote/src/lib.rs | 8 +- 8 files changed, 254 insertions(+), 230 deletions(-) diff --git a/biscuit-auth/benches/token.rs b/biscuit-auth/benches/token.rs index 58239b1f..86c0fe29 100644 --- a/biscuit-auth/benches/token.rs +++ b/biscuit-auth/benches/token.rs @@ -13,12 +13,13 @@ fn create_block_1(b: &mut Bencher) { let mut rng = OsRng; let root = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); let data = token.to_vec().unwrap(); @@ -26,15 +27,16 @@ fn create_block_1(b: &mut Bencher) { b.bytes = data.len() as u64; assert_eq!(b.bytes, 206); b.iter(|| { - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); - let data = token.to_vec().unwrap(); + let _data = token.to_vec().unwrap(); }); } @@ -43,19 +45,20 @@ fn append_block_2(b: &mut Bencher) { let root = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let keypair2 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); let base_data = token.to_vec().unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); let data = token2.to_vec().unwrap(); @@ -64,12 +67,12 @@ fn append_block_2(b: &mut Bencher) { assert_eq!(b.bytes, 189); b.iter(|| { let token = Biscuit::from(&base_data, &root.public()).unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); - let data = token2.to_vec().unwrap(); + let _data = token2.to_vec().unwrap(); }); } @@ -81,19 +84,20 @@ fn append_block_5(b: &mut Bencher) { let keypair4 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let keypair5 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); let base_data = token.to_vec().unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); let data = token2.to_vec().unwrap(); @@ -102,28 +106,34 @@ fn append_block_5(b: &mut Bencher) { assert_eq!(b.bytes, 189); b.iter(|| { let token2 = Biscuit::from(&data, &root.public()).unwrap(); - let mut b = BlockBuilder::new(); - b.check_resource("file1"); - b.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); - let token3 = token2.append_with_keypair(&keypair3, b).unwrap(); + let token3 = token2 + .append_with_keypair(&keypair3, block_builder) + .unwrap(); let data = token3.to_vec().unwrap(); let token3 = Biscuit::from(&data, &root.public()).unwrap(); - let mut b = BlockBuilder::new(); - b.check_resource("file1"); - b.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); - let token4 = token3.append_with_keypair(&keypair4, b).unwrap(); + let token4 = token3 + .append_with_keypair(&keypair4, block_builder) + .unwrap(); let data = token4.to_vec().unwrap(); let token4 = Biscuit::from(&data, &root.public()).unwrap(); - let mut b = BlockBuilder::new(); - b.check_resource("file1"); - b.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); - let token5 = token4.append_with_keypair(&keypair5, b).unwrap(); - let data = token5.to_vec().unwrap(); + let token5 = token4 + .append_with_keypair(&keypair5, block_builder) + .unwrap(); + let _data = token5.to_vec().unwrap(); }); } @@ -132,19 +142,20 @@ fn unverified_append_block_2(b: &mut Bencher) { let root = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let keypair2 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); let base_data = token.to_vec().unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); let data = token2.to_vec().unwrap(); @@ -153,12 +164,12 @@ fn unverified_append_block_2(b: &mut Bencher) { assert_eq!(b.bytes, 189); b.iter(|| { let token = UnverifiedBiscuit::from(&base_data).unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); - let data = token2.to_vec().unwrap(); + let _data = token2.to_vec().unwrap(); }); } @@ -170,19 +181,20 @@ fn unverified_append_block_5(b: &mut Bencher) { let keypair4 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let keypair5 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); let base_data = token.to_vec().unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); let data = token2.to_vec().unwrap(); @@ -191,28 +203,34 @@ fn unverified_append_block_5(b: &mut Bencher) { assert_eq!(b.bytes, 189); b.iter(|| { let token2 = UnverifiedBiscuit::from(&data).unwrap(); - let mut b = BlockBuilder::new(); - b.check_resource("file1"); - b.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); - let token3 = token2.append_with_keypair(&keypair3, b).unwrap(); + let token3 = token2 + .append_with_keypair(&keypair3, block_builder) + .unwrap(); let data = token3.to_vec().unwrap(); let token3 = UnverifiedBiscuit::from(&data).unwrap(); - let mut b = BlockBuilder::new(); - b.check_resource("file1"); - b.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); - let token4 = token3.append_with_keypair(&keypair4, b).unwrap(); + let token4 = token3 + .append_with_keypair(&keypair4, block_builder) + .unwrap(); let data = token4.to_vec().unwrap(); let token4 = UnverifiedBiscuit::from(&data).unwrap(); - let mut b = BlockBuilder::new(); - b.check_resource("file1"); - b.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); - let token5 = token4.append_with_keypair(&keypair5, b).unwrap(); - let data = token5.to_vec().unwrap(); + let token5 = token4 + .append_with_keypair(&keypair5, block_builder) + .unwrap(); + let _data = token5.to_vec().unwrap(); }); } @@ -222,19 +240,20 @@ fn verify_block_2(b: &mut Bencher) { let keypair2 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let data = { - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); - let base_data = token.to_vec().unwrap(); + let _base_data = token.to_vec().unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); token2.to_vec().unwrap() @@ -276,41 +295,42 @@ fn verify_block_5(b: &mut Bencher) { let keypair5 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let data = { - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); - let base_data = token.to_vec().unwrap(); + let _base_data = token.to_vec().unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token3 = token2 .append_with_keypair(&keypair3, block_builder) .unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token4 = token3 .append_with_keypair(&keypair4, block_builder) .unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token5 = token4 .append_with_keypair(&keypair5, block_builder) @@ -352,19 +372,20 @@ fn check_signature_2(b: &mut Bencher) { let keypair2 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let data = { - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); - let base_data = token.to_vec().unwrap(); + let _base_data = token.to_vec().unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); token2.to_vec().unwrap() @@ -384,7 +405,7 @@ fn check_signature_2(b: &mut Bencher) { b.bytes = data.len() as u64; b.iter(|| { - let token = Biscuit::from(&data, &root.public()).unwrap(); + let _token = Biscuit::from(&data, &root.public()).unwrap(); }); } @@ -397,40 +418,41 @@ fn check_signature_5(b: &mut Bencher) { let keypair5 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let data = { - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); - let base_data = token.to_vec().unwrap(); + let _base_data = token.to_vec().unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token3 = token2 .append_with_keypair(&keypair3, block_builder) .unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token4 = token3 .append_with_keypair(&keypair4, block_builder) .unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token5 = token4 .append_with_keypair(&keypair5, block_builder) @@ -452,7 +474,7 @@ fn check_signature_5(b: &mut Bencher) { b.bytes = data.len() as u64; b.iter(|| { - let token = Biscuit::from(&data, &root.public()).unwrap(); + let _token = Biscuit::from(&data, &root.public()).unwrap(); }); } @@ -462,19 +484,20 @@ fn checks_block_2(b: &mut Bencher) { let keypair2 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let data = { - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); - let base_data = token.to_vec().unwrap(); + let _base_data = token.to_vec().unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); token2.to_vec().unwrap() @@ -514,19 +537,20 @@ fn checks_block_create_verifier2(b: &mut Bencher) { let keypair2 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let data = { - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); - let base_data = token.to_vec().unwrap(); + let _base_data = token.to_vec().unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); token2.to_vec().unwrap() @@ -547,7 +571,7 @@ fn checks_block_create_verifier2(b: &mut Bencher) { let token = Biscuit::from(&data, &root.public()).unwrap(); b.bytes = data.len() as u64; b.iter(|| { - let mut verifier = token.authorizer().unwrap(); + let _verifier = token.authorizer().unwrap(); }); } @@ -557,19 +581,20 @@ fn checks_block_verify_only2(b: &mut Bencher) { let keypair2 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let data = { - let mut builder = Biscuit::builder(); - builder.add_fact(fact("right", &[string("file1"), string("read")])); - builder.add_fact(fact("right", &[string("file2"), string("read")])); - builder.add_fact(fact("right", &[string("file1"), string("write")])); - - let token = builder + let token = Biscuit::builder() + .add_fact(fact("right", &[string("file1"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file2"), string("read")])) + .unwrap() + .add_fact(fact("right", &[string("file1"), string("write")])) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); - let base_data = token.to_vec().unwrap(); + let _base_data = token.to_vec().unwrap(); - let mut block_builder = BlockBuilder::new(); - block_builder.check_resource("file1"); - block_builder.check_operation("read"); + let block_builder = BlockBuilder::new() + .check_resource("file1") + .check_operation("read"); let token2 = token.append_with_keypair(&keypair2, block_builder).unwrap(); token2.to_vec().unwrap() diff --git a/biscuit-auth/examples/testcases.rs b/biscuit-auth/examples/testcases.rs index d8a33d9f..faf6b021 100644 --- a/biscuit-auth/examples/testcases.rs +++ b/biscuit-auth/examples/testcases.rs @@ -878,9 +878,9 @@ fn scoped_rules(target: &str, root: &KeyPair, test: bool) -> TestResult { ) .unwrap(); - let mut block3 = BlockBuilder::new(); - - block3.add_fact(r#"owner("alice", "file2")"#).unwrap(); + let block3 = BlockBuilder::new() + .add_fact(r#"owner("alice", "file2")"#) + .unwrap(); let keypair3 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let biscuit3 = biscuit2.append_with_keypair(&keypair3, block3).unwrap(); @@ -973,14 +973,13 @@ fn expired_token(target: &str, root: &KeyPair, test: bool) -> TestResult { .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); - let mut block2 = block!(r#"check if resource("file1");"#); - - // January 1 2019 - block2.check_expiration_date( - UNIX_EPOCH - .checked_add(Duration::from_secs(49 * 365 * 24 * 3600)) - .unwrap(), - ); + let block2 = block!(r#"check if resource("file1");"#) + // January 1 2019 + .check_expiration_date( + UNIX_EPOCH + .checked_add(Duration::from_secs(49 * 365 * 24 * 3600)) + .unwrap(), + ); let keypair2 = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let biscuit2 = biscuit1.append_with_keypair(&keypair2, block2).unwrap(); @@ -1410,10 +1409,8 @@ fn unbound_variables_in_rule(target: &str, root: &KeyPair, test: bool) -> TestRe .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); - let mut block2 = BlockBuilder::new(); - - // this one does not go through the parser because it checks for unused variables - block2 + let block2 = BlockBuilder::new() + // this one does not go through the parser because it checks for unused variables .add_rule(rule( "operation", &[var("unbound"), string("read")], diff --git a/biscuit-auth/examples/third_party.rs b/biscuit-auth/examples/third_party.rs index 67fd6d99..1a206e08 100644 --- a/biscuit-auth/examples/third_party.rs +++ b/biscuit-auth/examples/third_party.rs @@ -7,18 +7,13 @@ fn main() { let mut rng: StdRng = SeedableRng::seed_from_u64(0); let root = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); let external = KeyPair::new_with_rng(Algorithm::Ed25519, &mut rng); - - let mut builder = Biscuit::builder(); - let external_pub = hex::encode(external.public().to_bytes()); - builder + let biscuit1 = Biscuit::builder() .add_check( format!("check if external_fact(\"hello\") trusting ed25519/{external_pub}").as_str(), ) - .unwrap(); - - let biscuit1 = builder + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); @@ -27,8 +22,9 @@ fn main() { let serialized_req = biscuit1.third_party_request().unwrap().serialize().unwrap(); let req = biscuit_auth::ThirdPartyRequest::deserialize(&serialized_req).unwrap(); - let mut builder = BlockBuilder::new(); - builder.add_fact("external_fact(\"hello\")").unwrap(); + let builder = BlockBuilder::new() + .add_fact("external_fact(\"hello\")") + .unwrap(); let res = req.create_block(&external.private(), builder).unwrap(); let biscuit2 = biscuit1.append_third_party(external.public(), res).unwrap(); diff --git a/biscuit-auth/src/token/authorizer.rs b/biscuit-auth/src/token/authorizer.rs index 3fe78241..b348aed8 100644 --- a/biscuit-auth/src/token/authorizer.rs +++ b/biscuit-auth/src/token/authorizer.rs @@ -203,14 +203,15 @@ impl Authorizer { /// Add the rules, facts, checks, and policies of another `Authorizer`. /// If a token has already been added to `other`, it is not merged into `self`. - pub fn merge(&mut self, mut other: Authorizer) { - self.merge_block(other.authorizer_block_builder); + pub fn merge(&mut self, mut other: Authorizer) -> Result<(), error::Token> { + self.merge_block(other.authorizer_block_builder)?; self.policies.append(&mut other.policies); + Ok(()) } /// Add the rules, facts, and checks of another `BlockBuilder`. pub fn merge_block(&mut self, other: BlockBuilder) -> Result<(), error::Token> { - self.authorizer_block_builder = self.authorizer_block_builder.merge(other); + self.authorizer_block_builder = self.authorizer_block_builder.clone().merge(other); Ok(()) } @@ -218,7 +219,7 @@ impl Authorizer { where error::Token: From<>::Error>, { - self.authorizer_block_builder = self.authorizer_block_builder.add_fact(fact)?; + self.authorizer_block_builder = self.authorizer_block_builder.clone().add_fact(fact)?; Ok(()) } @@ -226,7 +227,7 @@ impl Authorizer { where error::Token: From<>::Error>, { - self.authorizer_block_builder = self.authorizer_block_builder.add_rule(rule)?; + self.authorizer_block_builder = self.authorizer_block_builder.clone().add_rule(rule)?; Ok(()) } @@ -234,7 +235,8 @@ impl Authorizer { where error::Token: From<>::Error>, { - self.authorizer_block_builder.add_check(check) + self.authorizer_block_builder = self.authorizer_block_builder.clone().add_check(check)?; + Ok(()) } /// adds some datalog code to the authorizer @@ -383,7 +385,7 @@ impl Authorizer { } pub fn add_scope(&mut self, scope: Scope) { - self.authorizer_block_builder.add_scope(scope); + self.authorizer_block_builder = self.authorizer_block_builder.clone().add_scope(scope); } /// Returns the runtime limits of the authorizer @@ -611,7 +613,11 @@ impl Authorizer { /// adds a fact with the current time pub fn set_time(&mut self) { let fact = fact("time", &[date(&SystemTime::now())]); - self.authorizer_block_builder = self.authorizer_block_builder.add_fact(fact).unwrap(); + self.authorizer_block_builder = self + .authorizer_block_builder + .clone() + .add_fact(fact) + .unwrap(); } /// add a policy to the authorizer diff --git a/biscuit-auth/tests/macros.rs b/biscuit-auth/tests/macros.rs index 0922b342..3df56965 100644 --- a/biscuit-auth/tests/macros.rs +++ b/biscuit-auth/tests/macros.rs @@ -23,7 +23,7 @@ fn block_macro() { ); let is_true = true; - block_merge!(&mut b, r#"appended({is_true});"#); + b = block_merge!(b, r#"appended({is_true});"#); assert_eq!( b.to_string(), @@ -123,8 +123,8 @@ fn biscuit_macro() { b.set_root_key_id(2); let is_true = true; - biscuit_merge!( - &mut b, + b = biscuit_merge!( + b, r#"appended({is_true}); check if true; "# diff --git a/biscuit-auth/tests/rights.rs b/biscuit-auth/tests/rights.rs index 3741abad..89a8019e 100644 --- a/biscuit-auth/tests/rights.rs +++ b/biscuit-auth/tests/rights.rs @@ -11,22 +11,22 @@ fn main() { let mut rng: StdRng = SeedableRng::seed_from_u64(1234); let root = KeyPair::new_with_rng(builder::Algorithm::Ed25519, &mut rng); - let mut builder = Biscuit::builder(); - - builder.add_fact(fact( - "right", - &[string("authority"), string("file1"), string("read")], - )); - builder.add_fact(fact( - "right", - &[string("authority"), string("file2"), string("read")], - )); - builder.add_fact(fact( - "right", - &[string("authority"), string("file1"), string("write")], - )); - - let biscuit1 = builder + let biscuit1 = Biscuit::builder() + .add_fact(fact( + "right", + &[string("authority"), string("file1"), string("read")], + )) + .unwrap() + .add_fact(fact( + "right", + &[string("authority"), string("file2"), string("read")], + )) + .unwrap() + .add_fact(fact( + "right", + &[string("authority"), string("file1"), string("write")], + )) + .unwrap() .build_with_rng(&root, SymbolTable::default(), &mut rng) .unwrap(); println!("{}", biscuit1); diff --git a/biscuit-capi/src/lib.rs b/biscuit-capi/src/lib.rs index 2232c47f..235029cc 100644 --- a/biscuit-capi/src/lib.rs +++ b/biscuit-capi/src/lib.rs @@ -858,7 +858,7 @@ pub unsafe extern "C" fn block_builder_add_fact( return false; } - builder + builder.0 = builder .0 .add_fact(s.unwrap()) .map_err(|e| { diff --git a/biscuit-quote/src/lib.rs b/biscuit-quote/src/lib.rs index 8b2380dc..4a660668 100644 --- a/biscuit-quote/src/lib.rs +++ b/biscuit-quote/src/lib.rs @@ -349,7 +349,7 @@ impl Item { }, middle: TokenStream::new(), end: quote! { - __biscuit_auth_builder.add_fact(__biscuit_auth_item).unwrap(); + __biscuit_auth_builder = __biscuit_auth_builder.add_fact(__biscuit_auth_item).unwrap(); }, } } @@ -361,7 +361,7 @@ impl Item { }, middle: TokenStream::new(), end: quote! { - __biscuit_auth_builder.add_rule(__biscuit_auth_item).unwrap(); + __biscuit_auth_builder = __biscuit_auth_builder.add_rule(__biscuit_auth_item).unwrap(); }, } } @@ -374,7 +374,7 @@ impl Item { }, middle: TokenStream::new(), end: quote! { - __biscuit_auth_builder.add_check(__biscuit_auth_item).unwrap(); + __biscuit_auth_builder =__biscuit_auth_builder.add_check(__biscuit_auth_item).unwrap(); }, } } @@ -387,7 +387,7 @@ impl Item { }, middle: TokenStream::new(), end: quote! { - __biscuit_auth_builder.add_policy(__biscuit_auth_item).unwrap(); + __biscuit_auth_builder = __biscuit_auth_builder.add_policy(__biscuit_auth_item).unwrap(); }, } } From 15389afdcbf3b2cc47e061ca79e32bc402ba0930 Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Wed, 27 Nov 2024 18:55:59 +0100 Subject: [PATCH 4/5] update the capi --- biscuit-capi/src/lib.rs | 92 ++++++++++++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 15 deletions(-) diff --git a/biscuit-capi/src/lib.rs b/biscuit-capi/src/lib.rs index 235029cc..d156306a 100644 --- a/biscuit-capi/src/lib.rs +++ b/biscuit-capi/src/lib.rs @@ -292,8 +292,8 @@ pub extern "C" fn error_check_is_authorizer(check_index: u64) -> bool { pub struct Biscuit(biscuit_auth::Biscuit); pub struct KeyPair(biscuit_auth::KeyPair); pub struct PublicKey(biscuit_auth::PublicKey); -pub struct BiscuitBuilder(biscuit_auth::builder::BiscuitBuilder); -pub struct BlockBuilder(biscuit_auth::builder::BlockBuilder); +pub struct BiscuitBuilder(Option); +pub struct BlockBuilder(Option); pub struct Authorizer(biscuit_auth::Authorizer); #[repr(C)] @@ -422,9 +422,45 @@ pub unsafe extern "C" fn public_key_deserialize( #[no_mangle] pub unsafe extern "C" fn public_key_free(_kp: Option>) {} +impl BiscuitBuilder { + fn set_context(&mut self, context: &str) { + let mut inner = self.0.take().unwrap(); + inner = inner.set_context(context.to_string()); + self.0 = Some(inner); + } + + fn set_root_key_id(&mut self, root_key_id: u32) { + let mut inner = self.0.take().unwrap(); + inner = inner.set_root_key_id(root_key_id); + self.0 = Some(inner); + } + + fn add_fact(&mut self, fact: &str) -> Result<(), biscuit_auth::error::Token> { + let mut inner = self.0.take().unwrap(); + inner = inner.add_fact(fact)?; + self.0 = Some(inner); + Ok(()) + } + + fn add_rule(&mut self, rule: &str) -> Result<(), biscuit_auth::error::Token> { + let mut inner = self.0.take().unwrap(); + inner = inner.add_rule(rule)?; + self.0 = Some(inner); + Ok(()) + } + + fn add_check(&mut self, check: &str) -> Result<(), biscuit_auth::error::Token> { + let mut inner = self.0.take().unwrap(); + inner = inner.add_check(check)?; + self.0 = Some(inner); + Ok(()) + } +} #[no_mangle] pub unsafe extern "C" fn biscuit_builder() -> Option> { - Some(Box::new(BiscuitBuilder(biscuit_auth::Biscuit::builder()))) + Some(Box::new(BiscuitBuilder(Some( + biscuit_auth::Biscuit::builder(), + )))) } #[no_mangle] @@ -446,7 +482,7 @@ pub unsafe extern "C" fn biscuit_builder_set_context( false } Ok(context) => { - builder.0.set_context(context.to_string()); + builder.set_context(context); true } } @@ -463,7 +499,7 @@ pub unsafe extern "C" fn biscuit_builder_set_root_key_id( } let builder = builder.unwrap(); - builder.0.set_root_key_id(root_key_id); + builder.set_root_key_id(root_key_id); true } @@ -486,7 +522,6 @@ pub unsafe extern "C" fn biscuit_builder_add_fact( } builder - .0 .add_fact(s.unwrap()) .map_err(|e| { update_last_error(Error::Biscuit(e)); @@ -513,7 +548,6 @@ pub unsafe extern "C" fn biscuit_builder_add_rule( } builder - .0 .add_rule(s.unwrap()) .map_err(|e| { update_last_error(Error::Biscuit(e)); @@ -540,7 +574,6 @@ pub unsafe extern "C" fn biscuit_builder_add_check( } builder - .0 .add_check(s.unwrap()) .map_err(|e| { update_last_error(Error::Biscuit(e)); @@ -577,6 +610,7 @@ pub unsafe extern "C" fn biscuit_builder_build( (*builder) .0 .clone() + .expect("builder is none") .build_with_rng(&key_pair.0, SymbolTable::default(), &mut rng) .map(Biscuit) .map(Box::new) @@ -762,9 +796,40 @@ pub unsafe extern "C" fn biscuit_block_context( } } +impl BlockBuilder { + fn set_context(&mut self, context: &str) { + let mut inner = self.0.take().unwrap(); + inner = inner.set_context(context.to_string()); + self.0 = Some(inner); + } + + fn add_fact(&mut self, fact: &str) -> Result<(), biscuit_auth::error::Token> { + let mut inner = self.0.take().unwrap(); + inner = inner.add_fact(fact)?; + self.0 = Some(inner); + Ok(()) + } + + fn add_rule(&mut self, rule: &str) -> Result<(), biscuit_auth::error::Token> { + let mut inner = self.0.take().unwrap(); + inner = inner.add_rule(rule)?; + self.0 = Some(inner); + Ok(()) + } + + fn add_check(&mut self, check: &str) -> Result<(), biscuit_auth::error::Token> { + let mut inner = self.0.take().unwrap(); + inner = inner.add_check(check)?; + self.0 = Some(inner); + Ok(()) + } +} + #[no_mangle] pub unsafe extern "C" fn create_block() -> Box { - Box::new(BlockBuilder(biscuit_auth::builder::BlockBuilder::new())) + Box::new(BlockBuilder(Some( + biscuit_auth::builder::BlockBuilder::new(), + ))) } #[no_mangle] @@ -790,7 +855,7 @@ pub unsafe extern "C" fn biscuit_append_block( match biscuit .0 - .append_with_keypair(&key_pair.0, builder.0.clone()) + .append_with_keypair(&key_pair.0, builder.0.clone().expect("builder is none")) { Ok(token) => Some(Box::new(Biscuit(token))), Err(e) => { @@ -834,7 +899,7 @@ pub unsafe extern "C" fn block_builder_set_context( false } Ok(context) => { - builder.0.set_context(context.to_string()); + builder.set_context(context); true } } @@ -858,8 +923,7 @@ pub unsafe extern "C" fn block_builder_add_fact( return false; } - builder.0 = builder - .0 + builder .add_fact(s.unwrap()) .map_err(|e| { update_last_error(Error::Biscuit(e)); @@ -886,7 +950,6 @@ pub unsafe extern "C" fn block_builder_add_rule( } builder - .0 .add_rule(s.unwrap()) .map_err(|e| { update_last_error(Error::Biscuit(e)); @@ -913,7 +976,6 @@ pub unsafe extern "C" fn block_builder_add_check( } builder - .0 .add_check(s.unwrap()) .map_err(|e| { update_last_error(Error::Biscuit(e)); From aff9748596f9194849a56a02b6c3e5e9c2e4f115 Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Wed, 27 Nov 2024 19:00:21 +0100 Subject: [PATCH 5/5] update macros --- biscuit-quote/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biscuit-quote/src/lib.rs b/biscuit-quote/src/lib.rs index 4a660668..f917e736 100644 --- a/biscuit-quote/src/lib.rs +++ b/biscuit-quote/src/lib.rs @@ -476,7 +476,7 @@ impl ToTokens for Builder { let builder_type = &self.builder_type; let builder_quote = if let Some(target) = &self.target { quote! { - let __biscuit_auth_builder: &mut #builder_type = #target; + let mut __biscuit_auth_builder: #builder_type = #target; } } else { quote! {