diff --git a/Cargo.toml b/Cargo.toml index 85b440d0..4ed130e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["biscuit-auth", "biscuit-quote", "biscuit-parser", "biscuit-capi"] +members = ["biscuit-auth", "biscuit-proto", "biscuit-quote", "biscuit-parser", "biscuit-capi"] resolver = "2" # Used by capi crate diff --git a/biscuit-auth/Cargo.toml b/biscuit-auth/Cargo.toml index a7756e39..28758d1b 100644 --- a/biscuit-auth/Cargo.toml +++ b/biscuit-auth/Cargo.toml @@ -4,7 +4,6 @@ version = "6.0.0" description = "an authorization token with decentralized verification and offline attenuation" authors = ["Geoffroy Couprie "] edition = "2018" -build = "build.rs" license = "Apache-2.0" documentation = "https://docs.rs/biscuit-auth" homepage = "https://github.com/biscuit-auth/biscuit" @@ -29,7 +28,7 @@ pem = ["ed25519-dalek/pem", "ed25519-dalek/pkcs8"] rand_core = "^0.6" sha2 = "^0.9" prost = "0.10" -prost-types = "0.10" +biscuit-proto = { version = "0.1.0", path = "../biscuit-proto" } regex = { version = "1.5", default-features = false, features = ["std"] } nom = { version = "7", default-features = false, features = ["std"] } hex = "0.4" @@ -59,14 +58,10 @@ bencher = "0.1.5" rand = "0.8" chrono = { version = "0.4.26", features = ["serde", "clock"] } colored-diff = "0.2.3" -prost-build = "0.10" serde = { version = "1.0.130", features = ["derive"] } serde_json = "1.0.67" codspeed-bencher-compat = "2.6.0" -#[build-dependencies] -#prost-build = "0.10" - [[example]] name = "testcases" required-features = ["serde-error"] diff --git a/biscuit-auth/build.rs b/biscuit-auth/build.rs deleted file mode 100644 index cd7b954b..00000000 --- a/biscuit-auth/build.rs +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2019 Geoffroy Couprie and Contributors to the Eclipse Foundation. - * SPDX-License-Identifier: Apache-2.0 - */ -fn main() { - println!("cargo:rerun-if-changed=src/format/schema.proto"); - //prost_build::compile_protos(&["src/format/schema.proto"], &["src/"]).unwrap(); -} diff --git a/biscuit-auth/examples/testcases.rs b/biscuit-auth/examples/testcases.rs index eedcefa5..876a205a 100644 --- a/biscuit-auth/examples/testcases.rs +++ b/biscuit-auth/examples/testcases.rs @@ -9,10 +9,9 @@ extern crate biscuit_auth as biscuit; use biscuit::builder::BlockBuilder; use biscuit::datalog::SymbolTable; use biscuit::error; -use biscuit::format::convert; use biscuit::macros::*; use biscuit::{builder::*, builder_ext::*, Biscuit}; -use biscuit::{KeyPair, PrivateKey, PublicKey}; +use biscuit::{KeyPair, PrivateKey}; use biscuit_auth::builder; use biscuit_auth::builder::Algorithm; use biscuit_auth::datalog::ExternFunc; @@ -22,12 +21,7 @@ use rand::prelude::*; use serde::Serialize; use std::collections::HashMap; use std::sync::Arc; -use std::{ - collections::{BTreeMap, BTreeSet}, - fs::File, - io::Write, - time::*, -}; +use std::{collections::BTreeMap, fs::File, io::Write, time::*}; fn main() { let mut args = std::env::args(); @@ -294,7 +288,7 @@ struct AuthorizerWorld { #[derive(Debug, Serialize, PartialEq, Eq, PartialOrd, Ord)] struct Facts { - origin: BTreeSet>, + origin: Vec>, facts: Vec, } @@ -371,102 +365,37 @@ fn validate_token_with_limits_and_external_functions( let res = authorizer.authorize_with_limits(run_limits); //println!("authorizer world:\n{}", authorizer.print_world()); - let (_, _, _, policies) = authorizer.dump(); - let snapshot = authorizer.snapshot().unwrap(); - - let symbols = SymbolTable::from_symbols_and_public_keys( - snapshot.world.symbols, - snapshot - .world - .public_keys - .iter() - .map(|k| PublicKey::from_proto(k).unwrap()) - .collect(), - ) - .unwrap(); + let facts_with_origin = authorizer.dump_facts_with_origins(); + let rules_with_origin = authorizer.dump_rules_with_origins(); + let checks_with_origin = authorizer.dump_checks_with_origins(); + let policies = authorizer.dump_policies(); let mut authorizer_facts = Vec::new(); let mut authorizer_rules = Vec::new(); let mut authorizer_checks = Vec::new(); - for (i, block) in snapshot.world.blocks.iter().enumerate() { - let mut rules: Vec = Vec::new(); - for rule in block.rules.iter() { - let r = - convert::proto_rule_to_token_rule(rule, snapshot.world.version.unwrap()).unwrap(); - rules.push(symbols.print_rule(&r.0)); - } - if !rules.is_empty() { - rules.sort(); - authorizer_rules.push(Rules { - origin: Some(i), - rules, - }); - } - - let mut checks = Vec::new(); - for check in block.checks.iter() { - let c = convert::proto_check_to_token_check(check, snapshot.world.version.unwrap()) - .unwrap(); - checks.push(symbols.print_check(&c)); - } - if !checks.is_empty() { - checks.sort(); - authorizer_checks.push(Checks { - origin: Some(i), - checks, - }); - } - } - - let mut rules: Vec = Vec::new(); - for rule in snapshot.world.authorizer_block.rules { - let r = convert::proto_rule_to_token_rule(&rule, snapshot.world.version.unwrap()).unwrap(); - rules.push(symbols.print_rule(&r.0)); - } - if !rules.is_empty() { + for (origin, rules) in rules_with_origin { + let mut rules: Vec = rules.into_iter().map(|r| r.to_string()).collect(); rules.sort(); authorizer_rules.push(Rules { - origin: Some(usize::MAX), + origin: Some(origin.unwrap_or(usize::MAX)), rules, }); } - let mut checks = Vec::new(); - for check in snapshot.world.authorizer_block.checks { - let c = - convert::proto_check_to_token_check(&check, snapshot.world.version.unwrap()).unwrap(); - checks.push(symbols.print_check(&c)); - } - if !checks.is_empty() { + for (origin, checks) in checks_with_origin { + let mut checks: Vec = checks.into_iter().map(|c| c.to_string()).collect(); checks.sort(); authorizer_checks.push(Checks { - origin: Some(usize::MAX), + origin: Some(origin.unwrap_or(usize::MAX)), checks, }); } - for factset in snapshot.world.generated_facts { - use biscuit_auth::format::schema::origin::Content; - let mut origin = BTreeSet::new(); - - for o in factset.origins { - match o.content.unwrap() { - Content::Authorizer(_) => origin.insert(None), - Content::Origin(i) => origin.insert(Some(i as usize)), - }; - } - - let mut facts = Vec::new(); - - for fact in factset.facts { - let f = convert::proto_fact_to_token_fact(&fact).unwrap(); - facts.push(symbols.print_fact(&f)); - } - if !facts.is_empty() { - facts.sort(); - authorizer_facts.push(Facts { origin, facts }); - } + for (origin, facts) in facts_with_origin { + let mut facts: Vec = facts.into_iter().map(|f| f.to_string()).collect(); + facts.sort(); + authorizer_facts.push(Facts { origin, facts }); } authorizer_facts.sort(); @@ -663,8 +592,8 @@ fn invalid_signature_format(target: &str, root: &KeyPair, test: bool) -> TestRes let data = if test { load_testcase(target, &filename) } else { - let serialized = biscuit2.container(); - let mut proto = serialized.to_proto(); + let serialized = biscuit2.to_vec().unwrap(); + let mut proto = biscuit_proto::Biscuit::decode(&serialized[..]).unwrap(); proto.authority.signature.truncate(16); let mut data = Vec::new(); proto.encode(&mut data).unwrap(); @@ -714,8 +643,8 @@ fn random_block(target: &str, root: &KeyPair, test: bool) -> TestResult { let data = if test { load_testcase(target, &filename) } else { - let serialized = biscuit2.container(); - let mut proto = serialized.to_proto(); + let serialized = biscuit2.to_vec().unwrap(); + let mut proto = biscuit_proto::Biscuit::decode(&serialized[..]).unwrap(); let arr: [u8; 32] = rng.gen(); proto.blocks[0].block = Vec::from(&arr[..]); let mut data = Vec::new(); @@ -766,8 +695,8 @@ fn invalid_signature(target: &str, root: &KeyPair, test: bool) -> TestResult { let data = if test { load_testcase(target, &filename) } else { - let serialized = biscuit2.container(); - let mut proto = serialized.to_proto(); + let serialized = biscuit2.to_vec().unwrap(); + let mut proto = biscuit_proto::Biscuit::decode(&serialized[..]).unwrap(); proto.authority.signature[0] += 1; let mut data = Vec::new(); proto.encode(&mut data).unwrap(); diff --git a/biscuit-auth/src/crypto/ed25519.rs b/biscuit-auth/src/crypto/ed25519.rs index 36fb86b5..94b391da 100644 --- a/biscuit-auth/src/crypto/ed25519.rs +++ b/biscuit-auth/src/crypto/ed25519.rs @@ -275,7 +275,7 @@ impl PartialEq for PublicKey { impl Hash for PublicKey { fn hash(&self, state: &mut H) { - (crate::format::schema::public_key::Algorithm::Ed25519 as i32).hash(state); + (biscuit_proto::public_key::Algorithm::Ed25519 as i32).hash(state); self.0.to_bytes().hash(state); } } diff --git a/biscuit-auth/src/crypto/mod.rs b/biscuit-auth/src/crypto/mod.rs index e0128032..a10991b0 100644 --- a/biscuit-auth/src/crypto/mod.rs +++ b/biscuit-auth/src/crypto/mod.rs @@ -12,7 +12,6 @@ //! The implementation is based on [ed25519_dalek](https://github.com/dalek-cryptography/ed25519-dalek). #![allow(non_snake_case)] use crate::builder::Algorithm; -use crate::format::schema; use crate::format::ThirdPartyVerificationMode; use super::error; @@ -60,13 +59,13 @@ impl KeyPair { /// deserializes from a byte array pub fn from_bytes( bytes: &[u8], - algorithm: schema::public_key::Algorithm, + algorithm: biscuit_proto::public_key::Algorithm, ) -> Result { match algorithm { - schema::public_key::Algorithm::Ed25519 => { + biscuit_proto::public_key::Algorithm::Ed25519 => { Ok(KeyPair::Ed25519(ed25519::KeyPair::from_bytes(bytes)?)) } - schema::public_key::Algorithm::Secp256r1 => { + biscuit_proto::public_key::Algorithm::Secp256r1 => { Ok(KeyPair::P256(p256::KeyPair::from_bytes(bytes)?)) } } @@ -145,10 +144,10 @@ impl KeyPair { } } - pub fn algorithm(&self) -> crate::format::schema::public_key::Algorithm { + pub fn algorithm(&self) -> Algorithm { match self { - KeyPair::Ed25519(_) => crate::format::schema::public_key::Algorithm::Ed25519, - KeyPair::P256(_) => crate::format::schema::public_key::Algorithm::Secp256r1, + KeyPair::Ed25519(_) => Algorithm::Ed25519, + KeyPair::P256(_) => Algorithm::Secp256r1, } } } @@ -199,8 +198,8 @@ impl PrivateKey { /// serializes to an hex-encoded string, prefixed with the key algorithm pub fn to_prefixed_string(&self) -> String { let algorithm = match self.algorithm() { - schema::public_key::Algorithm::Ed25519 => "ed25519-private", - schema::public_key::Algorithm::Secp256r1 => "secp256r1-private", + Algorithm::Ed25519 => "ed25519-private", + Algorithm::Secp256r1 => "secp256r1-private", }; format!("{algorithm}/{}", self.to_bytes_hex()) } @@ -272,10 +271,10 @@ impl PrivateKey { } } - pub fn algorithm(&self) -> crate::format::schema::public_key::Algorithm { + pub fn algorithm(&self) -> Algorithm { match self { - PrivateKey::Ed25519(_) => crate::format::schema::public_key::Algorithm::Ed25519, - PrivateKey::P256(_) => crate::format::schema::public_key::Algorithm::Secp256r1, + PrivateKey::Ed25519(_) => Algorithm::Ed25519, + PrivateKey::P256(_) => Algorithm::Secp256r1, } } } @@ -315,12 +314,12 @@ impl PublicKey { Self::from_bytes(&bytes, algorithm) } - pub fn from_proto(key: &schema::PublicKey) -> Result { - if key.algorithm == schema::public_key::Algorithm::Ed25519 as i32 { + pub(crate) fn from_proto(key: &biscuit_proto::PublicKey) -> Result { + if key.algorithm == biscuit_proto::public_key::Algorithm::Ed25519 as i32 { Ok(PublicKey::Ed25519(ed25519::PublicKey::from_bytes( &key.key, )?)) - } else if key.algorithm == schema::public_key::Algorithm::Secp256r1 as i32 { + } else if key.algorithm == biscuit_proto::public_key::Algorithm::Secp256r1 as i32 { Ok(PublicKey::P256(p256::PublicKey::from_bytes(&key.key)?)) } else { Err(error::Format::DeserializationError(format!( @@ -330,8 +329,8 @@ impl PublicKey { } } - pub fn to_proto(&self) -> schema::PublicKey { - schema::PublicKey { + pub(crate) fn to_proto(&self) -> biscuit_proto::PublicKey { + biscuit_proto::PublicKey { algorithm: self.algorithm() as i32, key: self.to_bytes(), } @@ -393,10 +392,10 @@ impl PublicKey { } } - pub fn algorithm(&self) -> crate::format::schema::public_key::Algorithm { + pub fn algorithm(&self) -> Algorithm { match self { - PublicKey::Ed25519(_) => crate::format::schema::public_key::Algorithm::Ed25519, - PublicKey::P256(_) => crate::format::schema::public_key::Algorithm::Secp256r1, + PublicKey::Ed25519(_) => Algorithm::Ed25519, + PublicKey::P256(_) => Algorithm::Secp256r1, } } diff --git a/biscuit-auth/src/crypto/p256.rs b/biscuit-auth/src/crypto/p256.rs index 153ede7b..41ce0910 100644 --- a/biscuit-auth/src/crypto/p256.rs +++ b/biscuit-auth/src/crypto/p256.rs @@ -286,7 +286,7 @@ impl PublicKey { impl Hash for PublicKey { fn hash(&self, state: &mut H) { - (crate::format::schema::public_key::Algorithm::Secp256r1 as i32).hash(state); + (biscuit_proto::public_key::Algorithm::Secp256r1 as i32).hash(state); self.to_bytes().hash(state); } } diff --git a/biscuit-auth/src/datalog/expression.rs b/biscuit-auth/src/datalog/expression.rs index 4d57984a..8df63c44 100644 --- a/biscuit-auth/src/datalog/expression.rs +++ b/biscuit-auth/src/datalog/expression.rs @@ -8,10 +8,7 @@ use super::{MapKey, SymbolIndex, Term}; use super::{SymbolTable, TemporarySymbolTable}; use regex::Regex; use std::sync::Arc; -use std::{ - collections::HashMap, - convert::TryFrom, -}; +use std::{collections::HashMap, convert::TryFrom}; #[derive(Clone)] pub struct ExternFunc( diff --git a/biscuit-auth/src/datalog/mod.rs b/biscuit-auth/src/datalog/mod.rs index b951deaf..395bbd50 100644 --- a/biscuit-auth/src/datalog/mod.rs +++ b/biscuit-auth/src/datalog/mod.rs @@ -151,46 +151,48 @@ impl Rule { let variables = MatchedVariables::new(self.variables_set()); CombineIt::new(variables, &self.body, facts, symbols) - .map(move |(origin, variables)| { - let mut temporary_symbols = TemporarySymbolTable::new(symbols); - for e in self.expressions.iter() { - match e.evaluate(&variables, &mut temporary_symbols, extern_funcs) { - Ok(Term::Bool(true)) => {} - Ok(Term::Bool(false)) => return Ok((origin, variables, false)), - Ok(_) => return Err(error::Expression::InvalidType), - Err(e) => { - //println!("expr returned {:?}", res); - return Err(e); - } + .map(move |(origin, variables)| { + let mut temporary_symbols = TemporarySymbolTable::new(symbols); + for e in self.expressions.iter() { + match e.evaluate(&variables, &mut temporary_symbols, extern_funcs) { + Ok(Term::Bool(true)) => {} + Ok(Term::Bool(false)) => return Ok((origin, variables, false)), + Ok(_) => return Err(error::Expression::InvalidType), + Err(e) => { + //println!("expr returned {:?}", res); + return Err(e); } } - Ok((origin, variables, true)) - }).filter_map(move |res/*(mut origin,h, expression_res)*/| { - match res { - Ok((mut origin,h , expression_res)) => { - if expression_res { - let mut p = head.clone(); - for index in 0..p.terms.len() { - match &p.terms[index] { - Term::Variable(i) => match h.get(i) { - Some(val) => p.terms[index] = val.clone(), - None => { - // head variables should be bound in the body predicates - return None; - } - }, - _ => continue, - }; - } - - origin.insert(rule_origin); - Some(Ok((origin, Fact { predicate: p }))) - } else {None} - }, - Err(e) => Some(Err(e)) - } + } + Ok((origin, variables, true)) + }) + .filter_map(move |res /*(mut origin,h, expression_res)*/| { + match res { + Ok((mut origin, h, expression_res)) => { + if expression_res { + let mut p = head.clone(); + for index in 0..p.terms.len() { + match &p.terms[index] { + Term::Variable(i) => match h.get(i) { + Some(val) => p.terms[index] = val.clone(), + None => { + // head variables should be bound in the body predicates + return None; + } + }, + _ => continue, + }; + } - }) + origin.insert(rule_origin); + Some(Ok((origin, Fact { predicate: p }))) + } else { + None + } + } + Err(e) => Some(Err(e)), + } + }) } pub fn find_match( diff --git a/biscuit-auth/src/format/convert.rs b/biscuit-auth/src/format/convert.rs index d1932601..3693d3c8 100644 --- a/biscuit-auth/src/format/convert.rs +++ b/biscuit-auth/src/format/convert.rs @@ -3,14 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ //! helper functions for conversion between internal structures and Protobuf +use biscuit_proto::{Empty, MapEntry}; -use super::schema; use crate::builder::Convert; use crate::crypto::PublicKey; use crate::datalog::*; use crate::error; -use crate::format::schema::Empty; -use crate::format::schema::MapEntry; use crate::token::public_keys::PublicKeys; use crate::token::Scope; use crate::token::{authorizer::AuthorizerPolicies, Block}; @@ -19,8 +17,8 @@ use crate::token::{DATALOG_3_1, DATALOG_3_2, DATALOG_3_3, MAX_SCHEMA_VERSION, MI use std::collections::BTreeMap; use std::collections::BTreeSet; -pub fn token_block_to_proto_block(input: &Block) -> schema::Block { - schema::Block { +pub fn token_block_to_proto_block(input: &Block) -> biscuit_proto::Block { + biscuit_proto::Block { symbols: input.symbols.strings(), context: input.context.clone(), version: Some(input.version), @@ -46,7 +44,7 @@ pub fn token_block_to_proto_block(input: &Block) -> schema::Block { } pub fn proto_block_to_token_block( - input: &schema::Block, + input: &biscuit_proto::Block, external_key: Option, ) -> Result { let version = input.version.unwrap_or(0); @@ -77,7 +75,9 @@ pub fn proto_block_to_token_block( "deserialization error: check kinds are only supported on datalog v3.1+ blocks" .to_string(), )); - } else if version < DATALOG_3_3 && c.kind == Some(schema::check::Kind::Reject as i32) { + } else if version < DATALOG_3_3 + && c.kind == Some(biscuit_proto::check::Kind::Reject as i32) + { return Err(error::Format::DeserializationError( "deserialization error: reject if is only supported in datalog v3.3+" .to_string(), @@ -126,8 +126,8 @@ pub fn proto_block_to_token_block( }) } -pub fn token_block_to_proto_snapshot_block(input: &Block) -> schema::SnapshotBlock { - schema::SnapshotBlock { +pub fn token_block_to_proto_snapshot_block(input: &Block) -> biscuit_proto::SnapshotBlock { + biscuit_proto::SnapshotBlock { context: input.context.clone(), version: Some(input.version), facts: input.facts.iter().map(token_fact_to_proto_fact).collect(), @@ -147,7 +147,7 @@ pub fn token_block_to_proto_snapshot_block(input: &Block) -> schema::SnapshotBlo } pub fn proto_snapshot_block_to_token_block( - input: &schema::SnapshotBlock, + input: &biscuit_proto::SnapshotBlock, ) -> Result { let version = input.version.unwrap_or(0); if !(MIN_SCHEMA_VERSION..=MAX_SCHEMA_VERSION).contains(&version) { @@ -206,7 +206,9 @@ pub fn proto_snapshot_block_to_token_block( scopes, }) } -pub fn authorizer_to_proto_authorizer(input: &AuthorizerPolicies) -> schema::AuthorizerPolicies { +pub fn authorizer_to_proto_authorizer( + input: &AuthorizerPolicies, +) -> biscuit_proto::AuthorizerPolicies { let mut symbols = SymbolTable::default(); let facts = input @@ -236,7 +238,7 @@ pub fn authorizer_to_proto_authorizer(input: &AuthorizerPolicies) -> schema::Aut .map(|p| policy_to_proto_policy(p, &mut symbols)) .collect(); - schema::AuthorizerPolicies { + biscuit_proto::AuthorizerPolicies { symbols: symbols.strings(), version: Some(input.version), facts, @@ -247,7 +249,7 @@ pub fn authorizer_to_proto_authorizer(input: &AuthorizerPolicies) -> schema::Aut } pub fn proto_authorizer_to_authorizer( - input: &schema::AuthorizerPolicies, + input: &biscuit_proto::AuthorizerPolicies, ) -> Result { let version = input.version.unwrap_or(0); if !(MIN_SCHEMA_VERSION..=MAX_SCHEMA_VERSION).contains(&version) { @@ -299,22 +301,22 @@ pub fn proto_authorizer_to_authorizer( }) } -pub fn token_fact_to_proto_fact(input: &Fact) -> schema::Fact { - schema::Fact { +pub fn token_fact_to_proto_fact(input: &Fact) -> biscuit_proto::Fact { + biscuit_proto::Fact { predicate: token_predicate_to_proto_predicate(&input.predicate), } } -pub fn proto_fact_to_token_fact(input: &schema::Fact) -> Result { +pub fn proto_fact_to_token_fact(input: &biscuit_proto::Fact) -> Result { Ok(Fact { predicate: proto_predicate_to_token_predicate(&input.predicate)?, }) } -pub fn token_check_to_proto_check(input: &Check) -> schema::Check { - use schema::check::Kind; +pub fn token_check_to_proto_check(input: &Check) -> biscuit_proto::Check { + use biscuit_proto::check::Kind; - schema::Check { + biscuit_proto::Check { queries: input.queries.iter().map(token_rule_to_proto_rule).collect(), kind: match input.kind { crate::token::builder::CheckKind::One => None, @@ -325,7 +327,7 @@ pub fn token_check_to_proto_check(input: &Check) -> schema::Check { } pub fn proto_check_to_token_check( - input: &schema::Check, + input: &biscuit_proto::Check, version: u32, ) -> Result { let mut queries = vec![]; @@ -351,8 +353,8 @@ pub fn proto_check_to_token_check( pub fn policy_to_proto_policy( input: &crate::token::builder::Policy, symbols: &mut SymbolTable, -) -> schema::Policy { - schema::Policy { +) -> biscuit_proto::Policy { + biscuit_proto::Policy { queries: input .queries .iter() @@ -360,18 +362,18 @@ pub fn policy_to_proto_policy( .map(|r| token_rule_to_proto_rule(&r)) .collect(), kind: match input.kind { - crate::token::builder::PolicyKind::Allow => schema::policy::Kind::Allow as i32, - crate::token::builder::PolicyKind::Deny => schema::policy::Kind::Deny as i32, + crate::token::builder::PolicyKind::Allow => biscuit_proto::policy::Kind::Allow as i32, + crate::token::builder::PolicyKind::Deny => biscuit_proto::policy::Kind::Deny as i32, }, } } pub fn proto_policy_to_policy( - input: &schema::Policy, + input: &biscuit_proto::Policy, symbols: &SymbolTable, version: u32, ) -> Result { - use schema::policy::Kind; + use biscuit_proto::policy::Kind; let mut queries = vec![]; for q in input.queries.iter() { @@ -396,8 +398,8 @@ pub fn proto_policy_to_policy( Ok(crate::token::builder::Policy { queries, kind }) } -pub fn token_rule_to_proto_rule(input: &Rule) -> schema::Rule { - schema::Rule { +pub fn token_rule_to_proto_rule(input: &Rule) -> biscuit_proto::Rule { + biscuit_proto::Rule { head: token_predicate_to_proto_predicate(&input.head), body: input .body @@ -418,7 +420,7 @@ pub fn token_rule_to_proto_rule(input: &Rule) -> schema::Rule { } pub fn proto_rule_to_token_rule( - input: &schema::Rule, + input: &biscuit_proto::Rule, version: u32, ) -> Result<(Rule, Vec), error::Format> { let mut body = vec![]; @@ -453,15 +455,15 @@ pub fn proto_rule_to_token_rule( )) } -pub fn token_predicate_to_proto_predicate(input: &Predicate) -> schema::Predicate { - schema::Predicate { +pub fn token_predicate_to_proto_predicate(input: &Predicate) -> biscuit_proto::Predicate { + biscuit_proto::Predicate { name: input.name, terms: input.terms.iter().map(token_term_to_proto_id).collect(), } } pub fn proto_predicate_to_token_predicate( - input: &schema::Predicate, + input: &biscuit_proto::Predicate, ) -> Result { let mut terms = vec![]; @@ -475,55 +477,55 @@ pub fn proto_predicate_to_token_predicate( }) } -pub fn token_term_to_proto_id(input: &Term) -> schema::Term { - use schema::term::Content; +pub fn token_term_to_proto_id(input: &Term) -> biscuit_proto::Term { + use biscuit_proto::term::Content; match input { - Term::Variable(v) => schema::Term { + Term::Variable(v) => biscuit_proto::Term { content: Some(Content::Variable(*v)), }, - Term::Integer(i) => schema::Term { + Term::Integer(i) => biscuit_proto::Term { content: Some(Content::Integer(*i)), }, - Term::Str(s) => schema::Term { + Term::Str(s) => biscuit_proto::Term { content: Some(Content::String(*s)), }, - Term::Date(d) => schema::Term { + Term::Date(d) => biscuit_proto::Term { content: Some(Content::Date(*d)), }, - Term::Bytes(s) => schema::Term { + Term::Bytes(s) => biscuit_proto::Term { content: Some(Content::Bytes(s.clone())), }, - Term::Bool(b) => schema::Term { + Term::Bool(b) => biscuit_proto::Term { content: Some(Content::Bool(*b)), }, - Term::Set(s) => schema::Term { - content: Some(Content::Set(schema::TermSet { + Term::Set(s) => biscuit_proto::Term { + content: Some(Content::Set(biscuit_proto::TermSet { set: s.iter().map(token_term_to_proto_id).collect(), })), }, - Term::Null => schema::Term { + Term::Null => biscuit_proto::Term { content: Some(Content::Null(Empty {})), }, - Term::Array(a) => schema::Term { - content: Some(Content::Array(schema::Array { + Term::Array(a) => biscuit_proto::Term { + content: Some(Content::Array(biscuit_proto::Array { array: a.iter().map(token_term_to_proto_id).collect(), })), }, - Term::Map(m) => schema::Term { - content: Some(Content::Map(schema::Map { + Term::Map(m) => biscuit_proto::Term { + content: Some(Content::Map(biscuit_proto::Map { entries: m .iter() .map(|(key, term)| { let key = match key { - MapKey::Integer(i) => schema::MapKey { - content: Some(schema::map_key::Content::Integer(*i)), + MapKey::Integer(i) => biscuit_proto::MapKey { + content: Some(biscuit_proto::map_key::Content::Integer(*i)), }, - MapKey::Str(s) => schema::MapKey { - content: Some(schema::map_key::Content::String(*s)), + MapKey::Str(s) => biscuit_proto::MapKey { + content: Some(biscuit_proto::map_key::Content::String(*s)), }, }; - schema::MapEntry { + biscuit_proto::MapEntry { key, value: token_term_to_proto_id(term), } @@ -534,8 +536,8 @@ pub fn token_term_to_proto_id(input: &Term) -> schema::Term { } } -pub fn proto_id_to_token_term(input: &schema::Term) -> Result { - use schema::term::Content; +pub fn proto_id_to_token_term(input: &biscuit_proto::Term) -> Result { + use biscuit_proto::term::Content; match &input.content { None => Err(error::Format::DeserializationError( @@ -609,8 +611,8 @@ pub fn proto_id_to_token_term(input: &schema::Term) -> Result MapKey::Integer(i), - Some(schema::map_key::Content::String(s)) => MapKey::Str(s), + Some(biscuit_proto::map_key::Content::Integer(i)) => MapKey::Integer(i), + Some(biscuit_proto::map_key::Content::String(s)) => MapKey::Str(s), None => { return Err(error::Format::DeserializationError( "deserialization error: ID content enum is empty".to_string(), @@ -626,13 +628,13 @@ pub fn proto_id_to_token_term(input: &schema::Term) -> Result schema::Op { +fn token_op_to_proto_op(op: &Op) -> biscuit_proto::Op { let content = match op { - Op::Value(i) => schema::op::Content::Value(token_term_to_proto_id(i)), + Op::Value(i) => biscuit_proto::op::Content::Value(token_term_to_proto_id(i)), Op::Unary(u) => { - use schema::op_unary::Kind; + use biscuit_proto::op_unary::Kind; - schema::op::Content::Unary(schema::OpUnary { + biscuit_proto::op::Content::Unary(biscuit_proto::OpUnary { kind: match u { Unary::Negate => Kind::Negate, Unary::Parens => Kind::Parens, @@ -647,9 +649,9 @@ fn token_op_to_proto_op(op: &Op) -> schema::Op { }) } Op::Binary(b) => { - use schema::op_binary::Kind; + use biscuit_proto::op_binary::Kind; - schema::op::Content::Binary(schema::OpBinary { + biscuit_proto::op::Content::Binary(biscuit_proto::OpBinary { kind: match b { Binary::LessThan => Kind::LessThan, Binary::GreaterThan => Kind::GreaterThan, @@ -688,25 +690,25 @@ fn token_op_to_proto_op(op: &Op) -> schema::Op { }, }) } - Op::Closure(params, ops) => schema::op::Content::Closure(schema::OpClosure { + Op::Closure(params, ops) => biscuit_proto::op::Content::Closure(biscuit_proto::OpClosure { params: params.clone(), ops: ops.iter().map(token_op_to_proto_op).collect(), }), }; - schema::Op { + biscuit_proto::Op { content: Some(content), } } -pub fn token_expression_to_proto_expression(input: &Expression) -> schema::Expression { - schema::Expression { +pub fn token_expression_to_proto_expression(input: &Expression) -> biscuit_proto::Expression { + biscuit_proto::Expression { ops: input.ops.iter().map(token_op_to_proto_op).collect(), } } -fn proto_op_to_token_op(op: &schema::Op) -> Result { - use schema::{op, op_binary, op_unary}; +fn proto_op_to_token_op(op: &biscuit_proto::Op) -> Result { + use biscuit_proto::{op, op_binary, op_unary}; Ok(match op.content.as_ref() { Some(op::Content::Value(id)) => Op::Value(proto_id_to_token_term(id)?), Some(op::Content::Unary(u)) => { @@ -805,7 +807,7 @@ fn proto_op_to_token_op(op: &schema::Op) -> Result { } pub fn proto_expression_to_token_expression( - input: &schema::Expression, + input: &biscuit_proto::Expression, ) -> Result { let mut ops = Vec::new(); @@ -816,28 +818,29 @@ pub fn proto_expression_to_token_expression( Ok(Expression { ops }) } -pub fn token_scope_to_proto_scope(input: &Scope) -> schema::Scope { - schema::Scope { +pub fn token_scope_to_proto_scope(input: &Scope) -> biscuit_proto::Scope { + use biscuit_proto::scope; + biscuit_proto::Scope { content: Some(match input { crate::token::Scope::Authority => { - schema::scope::Content::ScopeType(schema::scope::ScopeType::Authority as i32) + scope::Content::ScopeType(scope::ScopeType::Authority as i32) } crate::token::Scope::Previous => { - schema::scope::Content::ScopeType(schema::scope::ScopeType::Previous as i32) + scope::Content::ScopeType(scope::ScopeType::Previous as i32) } - crate::token::Scope::PublicKey(i) => schema::scope::Content::PublicKey(*i as i64), + crate::token::Scope::PublicKey(i) => scope::Content::PublicKey(*i as i64), }), } } -pub fn proto_scope_to_token_scope(input: &schema::Scope) -> Result { +pub fn proto_scope_to_token_scope(input: &biscuit_proto::Scope) -> Result { //FIXME: check that the referenced public key index exists in the public key table match input.content.as_ref() { Some(content) => match content { - schema::scope::Content::ScopeType(i) => { - if *i == schema::scope::ScopeType::Authority as i32 { + biscuit_proto::scope::Content::ScopeType(i) => { + if *i == biscuit_proto::scope::ScopeType::Authority as i32 { Ok(Scope::Authority) - } else if *i == schema::scope::ScopeType::Previous as i32 { + } else if *i == biscuit_proto::scope::ScopeType::Previous as i32 { Ok(Scope::Previous) } else { Err(error::Format::DeserializationError(format!( @@ -845,7 +848,7 @@ pub fn proto_scope_to_token_scope(input: &schema::Scope) -> Result Ok(Scope::PublicKey(*i as u64)), + biscuit_proto::scope::Content::PublicKey(i) => Ok(Scope::PublicKey(*i as u64)), }, None => Err(error::Format::DeserializationError( "deserialization error: expected `content` field in Scope".to_string(), diff --git a/biscuit-auth/src/format/mod.rs b/biscuit-auth/src/format/mod.rs index 4ff3c70a..368b1580 100644 --- a/biscuit-auth/src/format/mod.rs +++ b/biscuit-auth/src/format/mod.rs @@ -20,12 +20,7 @@ use crate::datalog::SymbolTable; use crate::token::RootKeyProvider; use crate::token::DATALOG_3_3; -/// Structures generated from the Protobuf schema -pub mod schema; /*{ - include!(concat!(env!("OUT_DIR"), "/biscuit.format.schema.rs")); - }*/ - -pub mod convert; +pub(crate) mod convert; use self::convert::*; @@ -80,7 +75,7 @@ impl SerializedBiscuit { slice: &[u8], verification_mode: ThirdPartyVerificationMode, ) -> Result { - let data = schema::Biscuit::decode(slice).map_err(|e| { + let data = biscuit_proto::Biscuit::decode(slice).map_err(|e| { error::Format::DeserializationError(format!("deserialization error: {e:?}")) })?; @@ -145,16 +140,10 @@ impl SerializedBiscuit { "could not find proof".to_string(), )) } - Some(schema::proof::Content::NextSecret(v)) => { - let next_key_algorithm = match next_key_algorithm { - schema::public_key::Algorithm::Ed25519 => crate::builder::Algorithm::Ed25519, - schema::public_key::Algorithm::Secp256r1 => { - crate::builder::Algorithm::Secp256r1 - } - }; + Some(biscuit_proto::proof::Content::NextSecret(v)) => { TokenNext::Secret(PrivateKey::from_bytes(&v, next_key_algorithm)?) } - Some(schema::proof::Content::FinalSignature(v)) => { + Some(biscuit_proto::proof::Content::FinalSignature(v)) => { let signature = Signature::from_vec(v); TokenNext::Seal(signature) @@ -174,10 +163,10 @@ impl SerializedBiscuit { pub(crate) fn extract_blocks( &self, symbols: &mut SymbolTable, - ) -> Result<(schema::Block, Vec), error::Token> { + ) -> Result<(biscuit_proto::Block, Vec), error::Token> { let mut block_external_keys = Vec::new(); - let authority = schema::Block::decode(&self.authority.data[..]).map_err(|e| { + let authority = biscuit_proto::Block::decode(&self.authority.data[..]).map_err(|e| { error::Token::Format(error::Format::BlockDeserializationError(format!( "error deserializing authority block: {e:?}" ))) @@ -197,7 +186,7 @@ impl SerializedBiscuit { let mut blocks = vec![]; for block in self.blocks.iter() { - let deser = schema::Block::decode(&block.data[..]).map_err(|e| { + let deser = biscuit_proto::Block::decode(&block.data[..]).map_err(|e| { error::Token::Format(error::Format::BlockDeserializationError(format!( "error deserializing block: {e:?}" ))) @@ -222,8 +211,8 @@ impl SerializedBiscuit { } /// serializes the token - pub fn to_proto(&self) -> schema::Biscuit { - let authority = schema::SignedBlock { + pub(crate) fn to_proto(&self) -> biscuit_proto::Biscuit { + let authority = biscuit_proto::SignedBlock { block: self.authority.data.clone(), next_key: self.authority.next_key.to_proto(), signature: self.authority.signature.to_bytes().to_vec(), @@ -237,12 +226,12 @@ impl SerializedBiscuit { let mut blocks = Vec::new(); for block in &self.blocks { - let b = schema::SignedBlock { + let b = biscuit_proto::SignedBlock { block: block.data.clone(), next_key: block.next_key.to_proto(), signature: block.signature.to_bytes().to_vec(), external_signature: block.external_signature.as_ref().map(|external_signature| { - schema::ExternalSignature { + biscuit_proto::ExternalSignature { signature: external_signature.signature.to_bytes().to_vec(), public_key: external_signature.public_key.to_proto(), } @@ -257,16 +246,18 @@ impl SerializedBiscuit { blocks.push(b); } - schema::Biscuit { + biscuit_proto::Biscuit { root_key_id: self.root_key_id, authority, blocks, - proof: schema::Proof { + proof: biscuit_proto::Proof { content: match &self.proof { - TokenNext::Seal(signature) => Some(schema::proof::Content::FinalSignature( - signature.to_bytes().to_vec(), - )), - TokenNext::Secret(private) => Some(schema::proof::Content::NextSecret( + TokenNext::Seal(signature) => { + Some(biscuit_proto::proof::Content::FinalSignature( + signature.to_bytes().to_vec(), + )) + } + TokenNext::Secret(private) => Some(biscuit_proto::proof::Content::NextSecret( private.to_bytes().to_vec(), )), }, @@ -580,8 +571,6 @@ where #[cfg(test)] mod tests { - use std::io::Read; - use crate::{ builder::Algorithm, crypto::{ExternalSignature, Signature}, @@ -590,32 +579,6 @@ mod tests { KeyPair, }; - #[test] - fn proto() { - // somehow when building under cargo-tarpaulin, OUT_DIR is not set - let out_dir = match std::env::var("OUT_DIR") { - Ok(dir) => dir, - Err(_) => return, - }; - prost_build::compile_protos(&["src/format/schema.proto"], &["src/"]).unwrap(); - let mut file = std::fs::File::open(format!("{out_dir}/biscuit.format.schema.rs")).unwrap(); - let mut contents = String::new(); - file.read_to_string(&mut contents).unwrap(); - - let commited_schema = include_str!("schema.rs"); - - if contents != commited_schema { - println!( - "{}", - colored_diff::PrettyDifference { - expected: &contents, - actual: commited_schema - } - ); - panic!(); - } - } - #[test] fn test_block_signature_version() { assert_eq!( diff --git a/biscuit-auth/src/token/authorizer.rs b/biscuit-auth/src/token/authorizer.rs index 31a3b0ca..ea8e4290 100644 --- a/biscuit-auth/src/token/authorizer.rs +++ b/biscuit-auth/src/token/authorizer.rs @@ -87,7 +87,7 @@ impl Authorizer { } } - /// creates an `Authorizer` from a serialized [crate::format::schema::AuthorizerPolicies] + /// creates an `Authorizer` from a serialized authorizer pub fn from(data: &[u8]) -> Result { AuthorizerPolicies::deserialize(data)?.try_into() } @@ -640,12 +640,12 @@ impl Authorizer { } } - /// prints the content of the authorizer + /// Prints the content of the authorizer. pub fn print_world(&self) -> String { self.to_string() } - /// returns all of the data loaded in the authorizer + /// Returns all of the data loaded in the authorizer. pub fn dump(&self) -> (Vec, Vec, Vec, Vec) { let mut checks = self.authorizer_block_builder.checks.clone(); if let Some(blocks) = &self.blocks { @@ -678,6 +678,79 @@ impl Authorizer { (facts, rules, checks, self.policies.clone()) } + /// Returns all facts loaded in the authorizer, grouped by origin. + pub fn dump_facts_with_origins(&self) -> Vec<(Vec>, Vec)> { + self.world + .facts + .inner + .iter() + .filter_map(|(origin, facts)| { + if facts.is_empty() { + return None; + } + let origin_set: Vec> = origin + .inner + .iter() + .map(|o| if *o == usize::MAX { None } else { Some(*o) }) + .collect(); + let converted: Vec = facts + .iter() + .map(|f| Fact::convert_from(f, &self.symbols).unwrap()) + .collect(); + Some((origin_set, converted)) + }) + .collect() + } + + /// Returns all rules loaded in the authorizer, grouped by origin block index + pub fn dump_rules_with_origins(&self) -> Vec<(Option, Vec)> { + let mut rules = Vec::new(); + if let Some(blocks) = &self.blocks { + for (i, block) in blocks.iter().enumerate() { + let block_rules: Vec = block + .rules + .iter() + .map(|r| Rule::convert_from(r, &self.symbols).unwrap()) + .collect(); + if !block_rules.is_empty() { + rules.push((Some(i), block_rules)); + } + } + } + let authorizer_rules = self.authorizer_block_builder.rules.clone(); + if !authorizer_rules.is_empty() { + rules.push((None, authorizer_rules)); + } + rules + } + + /// Returns all checks loaded in the authorizer, grouped by origin block index + pub fn dump_checks_with_origins(&self) -> Vec<(Option, Vec)> { + let mut checks = Vec::new(); + if let Some(blocks) = &self.blocks { + for (i, block) in blocks.iter().enumerate() { + let block_checks: Vec = block + .checks + .iter() + .map(|c| Check::convert_from(c, &self.symbols).unwrap()) + .collect(); + if !block_checks.is_empty() { + checks.push((Some(i), block_checks)); + } + } + } + let authorizer_checks = self.authorizer_block_builder.checks.clone(); + if !authorizer_checks.is_empty() { + checks.push((None, authorizer_checks)); + } + checks + } + + /// Returns all policies loaded in the authorizer. + pub fn dump_policies(&self) -> Vec { + self.policies.clone() + } + pub fn dump_code(&self) -> String { let (facts, rules, checks, policies) = self.dump(); let mut f = String::new(); @@ -897,7 +970,7 @@ impl AuthorizerPolicies { } pub fn deserialize(data: &[u8]) -> Result { - let data = crate::format::schema::AuthorizerPolicies::decode(data).map_err(|e| { + let data = biscuit_proto::AuthorizerPolicies::decode(data).map_err(|e| { error::Format::DeserializationError(format!("deserialization error: {e:?}")) })?; diff --git a/biscuit-auth/src/token/authorizer/snapshot.rs b/biscuit-auth/src/token/authorizer/snapshot.rs index d7c269a2..40ab29ef 100644 --- a/biscuit-auth/src/token/authorizer/snapshot.rs +++ b/biscuit-auth/src/token/authorizer/snapshot.rs @@ -2,6 +2,7 @@ * Copyright (c) 2019 Geoffroy Couprie and Contributors to the Eclipse Foundation. * SPDX-License-Identifier: Apache-2.0 */ +use biscuit_proto::GeneratedFacts; use prost::Message; use std::{collections::HashMap, time::Duration}; @@ -9,21 +10,20 @@ use crate::{ builder::{load_and_translate_block, BlockBuilder, Convert, Policy}, datalog::{Origin, RunLimits, TrustedOrigins}, error, - format::{ - convert::{ - policy_to_proto_policy, proto_fact_to_token_fact, proto_policy_to_policy, - proto_snapshot_block_to_token_block, token_block_to_proto_snapshot_block, - token_fact_to_proto_fact, - }, - schema::{self, GeneratedFacts}, + format::convert::{ + policy_to_proto_policy, proto_fact_to_token_fact, proto_policy_to_policy, + proto_snapshot_block_to_token_block, token_block_to_proto_snapshot_block, + token_fact_to_proto_fact, }, token::{default_symbol_table, MAX_SCHEMA_VERSION, MIN_SCHEMA_VERSION}, PublicKey, }; impl super::Authorizer { - pub fn from_snapshot(input: schema::AuthorizerSnapshot) -> Result { - let schema::AuthorizerSnapshot { + pub(crate) fn from_snapshot( + input: biscuit_proto::AuthorizerSnapshot, + ) -> Result { + let biscuit_proto::AuthorizerSnapshot { limits, execution_time, world, @@ -173,7 +173,7 @@ impl super::Authorizer { } pub fn from_raw_snapshot(input: &[u8]) -> Result { - let snapshot = schema::AuthorizerSnapshot::decode(input).map_err(|e| { + let snapshot = biscuit_proto::AuthorizerSnapshot::decode(input).map_err(|e| { error::Format::DeserializationError(format!("deserialization error: {e:?}")) })?; Self::from_snapshot(snapshot) @@ -184,7 +184,7 @@ impl super::Authorizer { Self::from_raw_snapshot(&bytes) } - pub fn snapshot(&self) -> Result { + pub(crate) fn snapshot(&self) -> Result { let mut symbols = default_symbol_table(); let authorizer_policies = self @@ -232,7 +232,7 @@ impl super::Authorizer { }) .collect::, error::Format>>()?; - let world = schema::AuthorizerWorld { + let world = biscuit_proto::AuthorizerWorld { version: Some(MAX_SCHEMA_VERSION), symbols: symbols.strings(), public_keys: symbols @@ -248,10 +248,10 @@ impl super::Authorizer { iterations: self.world.iterations, }; - Ok(schema::AuthorizerSnapshot { + Ok(biscuit_proto::AuthorizerSnapshot { world, execution_time: self.execution_time.unwrap_or_default().as_nanos() as u64, - limits: schema::RunLimits { + limits: biscuit_proto::RunLimits { max_facts: self.limits.max_facts, max_iterations: self.limits.max_iterations, max_time: self.limits.max_time.as_nanos() as u64, @@ -274,18 +274,20 @@ impl super::Authorizer { } } -pub(crate) fn authorizer_origin_to_proto_origin(origin: &Origin) -> Vec { +pub(crate) fn authorizer_origin_to_proto_origin(origin: &Origin) -> Vec { origin .inner .iter() .map(|o| { if *o == usize::MAX { - schema::Origin { - content: Some(schema::origin::Content::Authorizer(schema::Empty {})), + biscuit_proto::Origin { + content: Some(biscuit_proto::origin::Content::Authorizer( + biscuit_proto::Empty {}, + )), } } else { - schema::Origin { - content: Some(schema::origin::Content::Origin(*o as u32)), + biscuit_proto::Origin { + content: Some(biscuit_proto::origin::Content::Origin(*o as u32)), } } }) @@ -293,16 +295,16 @@ pub(crate) fn authorizer_origin_to_proto_origin(origin: &Origin) -> Vec Result { let mut new_origin = Origin::default(); for origin in origins { match origin.content { - Some(schema::origin::Content::Authorizer(schema::Empty {})) => { + Some(biscuit_proto::origin::Content::Authorizer(biscuit_proto::Empty {})) => { new_origin.insert(usize::MAX) } - Some(schema::origin::Content::Origin(o)) => new_origin.insert(o as usize), + Some(biscuit_proto::origin::Content::Origin(o)) => new_origin.insert(o as usize), _ => { return Err(error::Format::DeserializationError( "invalid origin".to_string(), diff --git a/biscuit-auth/src/token/builder/algorithm.rs b/biscuit-auth/src/token/builder/algorithm.rs index 3d5d956a..b0c84070 100644 --- a/biscuit-auth/src/token/builder/algorithm.rs +++ b/biscuit-auth/src/token/builder/algorithm.rs @@ -76,20 +76,20 @@ impl From for biscuit_parser::builder::Algorithm { } } -impl From for Algorithm { - fn from(value: crate::format::schema::public_key::Algorithm) -> Algorithm { +impl From for Algorithm { + fn from(value: biscuit_proto::public_key::Algorithm) -> Algorithm { match value { - crate::format::schema::public_key::Algorithm::Ed25519 => Algorithm::Ed25519, - crate::format::schema::public_key::Algorithm::Secp256r1 => Algorithm::Secp256r1, + biscuit_proto::public_key::Algorithm::Ed25519 => Algorithm::Ed25519, + biscuit_proto::public_key::Algorithm::Secp256r1 => Algorithm::Secp256r1, } } } -impl From for crate::format::schema::public_key::Algorithm { - fn from(value: Algorithm) -> crate::format::schema::public_key::Algorithm { +impl From for biscuit_proto::public_key::Algorithm { + fn from(value: Algorithm) -> biscuit_proto::public_key::Algorithm { match value { - Algorithm::Ed25519 => crate::format::schema::public_key::Algorithm::Ed25519, - Algorithm::Secp256r1 => crate::format::schema::public_key::Algorithm::Secp256r1, + Algorithm::Ed25519 => biscuit_proto::public_key::Algorithm::Ed25519, + Algorithm::Secp256r1 => biscuit_proto::public_key::Algorithm::Secp256r1, } } } diff --git a/biscuit-auth/src/token/builder/authorizer.rs b/biscuit-auth/src/token/builder/authorizer.rs index 14d7b72f..85e6891d 100644 --- a/biscuit-auth/src/token/builder/authorizer.rs +++ b/biscuit-auth/src/token/builder/authorizer.rs @@ -17,12 +17,9 @@ use crate::{ builder_ext::{AuthorizerExt, BuilderExt}, datalog::{ExternFunc, Origin, RunLimits, SymbolTable, TrustedOrigins, World}, error, - format::{ - convert::{ - policy_to_proto_policy, proto_policy_to_policy, proto_snapshot_block_to_token_block, - token_block_to_proto_snapshot_block, - }, - schema, + format::convert::{ + policy_to_proto_policy, proto_policy_to_policy, proto_snapshot_block_to_token_block, + token_block_to_proto_snapshot_block, }, token::{self, default_symbol_table, Block, MAX_SCHEMA_VERSION, MIN_SCHEMA_VERSION}, Authorizer, AuthorizerLimits, Biscuit, PublicKey, @@ -547,8 +544,10 @@ impl AuthorizerExt for AuthorizerBuilder { } impl AuthorizerBuilder { - pub fn from_snapshot(input: schema::AuthorizerSnapshot) -> Result { - let schema::AuthorizerSnapshot { + pub(crate) fn from_snapshot( + input: biscuit_proto::AuthorizerSnapshot, + ) -> Result { + let biscuit_proto::AuthorizerSnapshot { limits, execution_time, world, @@ -628,7 +627,7 @@ impl AuthorizerBuilder { } pub fn from_raw_snapshot(input: &[u8]) -> Result { - let snapshot = schema::AuthorizerSnapshot::decode(input).map_err(|e| { + let snapshot = biscuit_proto::AuthorizerSnapshot::decode(input).map_err(|e| { error::Format::DeserializationError(format!("deserialization error: {e:?}")) })?; Self::from_snapshot(snapshot) @@ -639,7 +638,7 @@ impl AuthorizerBuilder { Self::from_raw_snapshot(&bytes) } - pub fn snapshot(&self) -> Result { + pub(crate) fn snapshot(&self) -> Result { let mut symbols = default_symbol_table(); let authorizer_policies = self @@ -658,7 +657,7 @@ impl AuthorizerBuilder { let generated_facts = vec![]; - let world = schema::AuthorizerWorld { + let world = biscuit_proto::AuthorizerWorld { version: Some(MAX_SCHEMA_VERSION), symbols: symbols.strings(), public_keys: symbols @@ -674,10 +673,10 @@ impl AuthorizerBuilder { iterations: 0, }; - Ok(schema::AuthorizerSnapshot { + Ok(biscuit_proto::AuthorizerSnapshot { world, execution_time: 0u64, - limits: schema::RunLimits { + limits: biscuit_proto::RunLimits { max_facts: self.limits.max_facts, max_iterations: self.limits.max_iterations, max_time: self.limits.max_time.as_nanos() as u64, diff --git a/biscuit-auth/src/token/mod.rs b/biscuit-auth/src/token/mod.rs index 218804c9..5b765e5e 100644 --- a/biscuit-auth/src/token/mod.rs +++ b/biscuit-auth/src/token/mod.rs @@ -6,6 +6,7 @@ use std::fmt::Display; use std::iter::once; +use biscuit_proto::ThirdPartyBlockContents; use builder::{BiscuitBuilder, BlockBuilder}; use prost::Message; use rand_core::{CryptoRng, RngCore}; @@ -17,7 +18,6 @@ use super::error; use super::format::SerializedBiscuit; use crate::crypto::{self}; use crate::format::convert::proto_block_to_token_block; -use crate::format::schema::{self, ThirdPartyBlockContents}; use crate::format::{ThirdPartyVerificationMode, THIRD_PARTY_SIGNATURE_VERSION}; use authorizer::Authorizer; @@ -83,8 +83,8 @@ pub fn default_symbol_table() -> SymbolTable { #[derive(Clone, Debug)] pub struct Biscuit { pub(crate) root_key_id: Option, - pub(crate) authority: schema::Block, - pub(crate) blocks: Vec, + pub(crate) authority: biscuit_proto::Block, + pub(crate) blocks: Vec, pub(crate) symbols: SymbolTable, pub(crate) container: SerializedBiscuit, } @@ -289,11 +289,12 @@ impl Biscuit { symbols.public_keys.extend(&authority.public_keys)?; - let authority = schema::Block::decode(&container.authority.data[..]).map_err(|e| { - error::Token::Format(error::Format::BlockDeserializationError(format!( - "error deserializing block: {e:?}" - ))) - })?; + let authority = + biscuit_proto::Block::decode(&container.authority.data[..]).map_err(|e| { + error::Token::Format(error::Format::BlockDeserializationError(format!( + "error deserializing block: {e:?}" + ))) + })?; Ok(Biscuit { root_key_id, @@ -379,7 +380,7 @@ impl Biscuit { symbols.extend(&block.symbols)?; symbols.public_keys.extend(&block.public_keys)?; - let deser = schema::Block::decode( + let deser = biscuit_proto::Block::decode( &container .blocks .last() @@ -464,7 +465,7 @@ impl Biscuit { ThirdPartyVerificationMode::PreviousSignatureHashing, )?; - let block = schema::Block::decode(&payload[..]).map_err(|e| { + let block = biscuit_proto::Block::decode(&payload[..]).map_err(|e| { error::Token::Format(error::Format::DeserializationError(format!( "deserialization error: {e:?}" ))) diff --git a/biscuit-auth/src/token/third_party.rs b/biscuit-auth/src/token/third_party.rs index 7150c96a..6e67d545 100644 --- a/biscuit-auth/src/token/third_party.rs +++ b/biscuit-auth/src/token/third_party.rs @@ -11,7 +11,7 @@ use crate::{ crypto::generate_external_signature_payload_v1, datalog::SymbolTable, error, - format::{convert::token_block_to_proto_block, schema, SerializedBiscuit}, + format::{convert::token_block_to_proto_block, SerializedBiscuit}, KeyPair, PrivateKey, }; @@ -44,7 +44,7 @@ impl ThirdPartyRequest { pub fn serialize(&self) -> Result, error::Token> { let previous_signature = self.previous_signature.clone(); - let request = schema::ThirdPartyBlockRequest { + let request = biscuit_proto::ThirdPartyBlockRequest { legacy_previous_key: None, legacy_public_keys: Vec::new(), previous_signature, @@ -63,7 +63,7 @@ impl ThirdPartyRequest { } pub fn deserialize(slice: &[u8]) -> Result { - let data = schema::ThirdPartyBlockRequest::decode(slice).map_err(|e| { + let data = biscuit_proto::ThirdPartyBlockRequest::decode(slice).map_err(|e| { error::Format::DeserializationError(format!("deserialization error: {e:?}")) })?; @@ -119,9 +119,9 @@ impl ThirdPartyRequest { let signature = keypair.sign(&signed_payload)?; let public_key = keypair.public(); - let content = schema::ThirdPartyBlockContents { + let content = biscuit_proto::ThirdPartyBlockContents { payload, - external_signature: schema::ExternalSignature { + external_signature: biscuit_proto::ExternalSignature { signature: signature.to_bytes().to_vec(), public_key: public_key.to_proto(), }, @@ -136,7 +136,7 @@ impl ThirdPartyRequest { /// this must be integrated with the token that created the [`ThirdPartyRequest`] /// using [`Biscuit::append_third_party`](crate::Biscuit::append_third_party) #[derive(Clone, Debug)] -pub struct ThirdPartyBlock(pub(crate) schema::ThirdPartyBlockContents); +pub struct ThirdPartyBlock(pub(crate) biscuit_proto::ThirdPartyBlockContents); impl ThirdPartyBlock { pub fn serialize(&self) -> Result, error::Token> { diff --git a/biscuit-auth/src/token/unverified.rs b/biscuit-auth/src/token/unverified.rs index 9eea9c53..44ef15ec 100644 --- a/biscuit-auth/src/token/unverified.rs +++ b/biscuit-auth/src/token/unverified.rs @@ -2,6 +2,7 @@ * Copyright (c) 2019 Geoffroy Couprie and Contributors to the Eclipse Foundation. * SPDX-License-Identifier: Apache-2.0 */ +use biscuit_proto::public_key::Algorithm; use prost::Message; use super::{default_symbol_table, Biscuit, Block}; @@ -10,11 +11,7 @@ use crate::{ crypto::{self, PublicKey, Signature}, datalog::SymbolTable, error, - format::{ - convert::proto_block_to_token_block, - schema::{self, public_key::Algorithm}, - SerializedBiscuit, - }, + format::{convert::proto_block_to_token_block, SerializedBiscuit}, token::{ThirdPartyBlockContents, ThirdPartyRequest}, KeyPair, RootKeyProvider, }; @@ -28,8 +25,8 @@ use crate::{ /// and then used for authorization #[derive(Clone, Debug)] pub struct UnverifiedBiscuit { - pub(crate) authority: schema::Block, - pub(crate) blocks: Vec, + pub(crate) authority: biscuit_proto::Block, + pub(crate) blocks: Vec, pub(crate) symbols: SymbolTable, container: SerializedBiscuit, } @@ -173,7 +170,7 @@ impl UnverifiedBiscuit { symbols.extend(&block.symbols)?; symbols.public_keys.extend(&block.public_keys)?; - let deser = schema::Block::decode( + let deser = biscuit_proto::Block::decode( &container .blocks .last() @@ -313,7 +310,7 @@ impl UnverifiedBiscuit { let ThirdPartyBlockContents { payload, external_signature, - } = schema::ThirdPartyBlockContents::decode(slice).map_err(|e| { + } = biscuit_proto::ThirdPartyBlockContents::decode(slice).map_err(|e| { error::Format::DeserializationError(format!("deserialization error: {e:?}")) })?; @@ -334,7 +331,7 @@ impl UnverifiedBiscuit { let signature = Signature::from_vec(external_signature.signature); - let block = schema::Block::decode(&payload[..]).map_err(|e| { + let block = biscuit_proto::Block::decode(&payload[..]).map_err(|e| { error::Token::Format(error::Format::DeserializationError(format!( "deserialization error: {e:?}" ))) diff --git a/biscuit-capi/src/lib.rs b/biscuit-capi/src/lib.rs index d175aa3a..e239dc14 100644 --- a/biscuit-capi/src/lib.rs +++ b/biscuit-capi/src/lib.rs @@ -374,10 +374,8 @@ pub unsafe extern "C" fn key_pair_deserialize( let input_slice = std::slice::from_raw_parts_mut(buffer_ptr, 32); let algorithm = match algorithm { - SignatureAlgorithm::Ed25519 => biscuit_auth::format::schema::public_key::Algorithm::Ed25519, - SignatureAlgorithm::Secp256r1 => { - biscuit_auth::format::schema::public_key::Algorithm::Secp256r1 - } + SignatureAlgorithm::Ed25519 => biscuit_auth::builder::Algorithm::Ed25519, + SignatureAlgorithm::Secp256r1 => biscuit_auth::builder::Algorithm::Secp256r1, }; match biscuit_auth::PrivateKey::from_bytes(input_slice, algorithm.into()).ok() { diff --git a/biscuit-proto/Cargo.toml b/biscuit-proto/Cargo.toml new file mode 100644 index 00000000..75623d5a --- /dev/null +++ b/biscuit-proto/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "biscuit-proto" +version = "0.1.0" +description = "Protobuf types for biscuits" +authors = ["Geoffroy Couprie "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://github.com/biscuit-auth/biscuit" +repository = "https://github.com/biscuit-auth/biscuit-rust" + +[dependencies] +prost = "0.10" + +[dev-dependencies] +prost-build = "0.10" +colored-diff = "0.2.3" diff --git a/biscuit-auth/src/format/schema.rs b/biscuit-proto/src/lib.rs similarity index 67% rename from biscuit-auth/src/format/schema.rs rename to biscuit-proto/src/lib.rs index 45dc20a7..c33a4d95 100644 --- a/biscuit-auth/src/format/schema.rs +++ b/biscuit-proto/src/lib.rs @@ -1,39 +1,39 @@ #[derive(Clone, PartialEq, ::prost::Message)] pub struct Biscuit { - #[prost(uint32, optional, tag="1")] + #[prost(uint32, optional, tag = "1")] pub root_key_id: ::core::option::Option, - #[prost(message, required, tag="2")] + #[prost(message, required, tag = "2")] pub authority: SignedBlock, - #[prost(message, repeated, tag="3")] + #[prost(message, repeated, tag = "3")] pub blocks: ::prost::alloc::vec::Vec, - #[prost(message, required, tag="4")] + #[prost(message, required, tag = "4")] pub proof: Proof, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct SignedBlock { - #[prost(bytes="vec", required, tag="1")] + #[prost(bytes = "vec", required, tag = "1")] pub block: ::prost::alloc::vec::Vec, - #[prost(message, required, tag="2")] + #[prost(message, required, tag = "2")] pub next_key: PublicKey, - #[prost(bytes="vec", required, tag="3")] + #[prost(bytes = "vec", required, tag = "3")] pub signature: ::prost::alloc::vec::Vec, - #[prost(message, optional, tag="4")] + #[prost(message, optional, tag = "4")] pub external_signature: ::core::option::Option, - #[prost(uint32, optional, tag="5")] + #[prost(uint32, optional, tag = "5")] pub version: ::core::option::Option, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct ExternalSignature { - #[prost(bytes="vec", required, tag="1")] + #[prost(bytes = "vec", required, tag = "1")] pub signature: ::prost::alloc::vec::Vec, - #[prost(message, required, tag="2")] + #[prost(message, required, tag = "2")] pub public_key: PublicKey, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct PublicKey { - #[prost(enumeration="public_key::Algorithm", required, tag="1")] + #[prost(enumeration = "public_key::Algorithm", required, tag = "1")] pub algorithm: i32, - #[prost(bytes="vec", required, tag="2")] + #[prost(bytes = "vec", required, tag = "2")] pub key: ::prost::alloc::vec::Vec, } /// Nested message and enum types in `PublicKey`. @@ -47,41 +47,41 @@ pub mod public_key { } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Proof { - #[prost(oneof="proof::Content", tags="1, 2")] + #[prost(oneof = "proof::Content", tags = "1, 2")] pub content: ::core::option::Option, } /// Nested message and enum types in `Proof`. pub mod proof { #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Content { - #[prost(bytes, tag="1")] + #[prost(bytes, tag = "1")] NextSecret(::prost::alloc::vec::Vec), - #[prost(bytes, tag="2")] + #[prost(bytes, tag = "2")] FinalSignature(::prost::alloc::vec::Vec), } } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Block { - #[prost(string, repeated, tag="1")] + #[prost(string, repeated, tag = "1")] pub symbols: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, - #[prost(string, optional, tag="2")] + #[prost(string, optional, tag = "2")] pub context: ::core::option::Option<::prost::alloc::string::String>, - #[prost(uint32, optional, tag="3")] + #[prost(uint32, optional, tag = "3")] pub version: ::core::option::Option, - #[prost(message, repeated, tag="4")] + #[prost(message, repeated, tag = "4")] pub facts: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="5")] + #[prost(message, repeated, tag = "5")] pub rules: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="6")] + #[prost(message, repeated, tag = "6")] pub checks: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="7")] + #[prost(message, repeated, tag = "7")] pub scope: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="8")] + #[prost(message, repeated, tag = "8")] pub public_keys: ::prost::alloc::vec::Vec, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Scope { - #[prost(oneof="scope::Content", tags="1, 2")] + #[prost(oneof = "scope::Content", tags = "1, 2")] pub content: ::core::option::Option, } /// Nested message and enum types in `Scope`. @@ -94,33 +94,33 @@ pub mod scope { } #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Content { - #[prost(enumeration="ScopeType", tag="1")] + #[prost(enumeration = "ScopeType", tag = "1")] ScopeType(i32), - #[prost(int64, tag="2")] + #[prost(int64, tag = "2")] PublicKey(i64), } } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Fact { - #[prost(message, required, tag="1")] + #[prost(message, required, tag = "1")] pub predicate: Predicate, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Rule { - #[prost(message, required, tag="1")] + #[prost(message, required, tag = "1")] pub head: Predicate, - #[prost(message, repeated, tag="2")] + #[prost(message, repeated, tag = "2")] pub body: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="3")] + #[prost(message, repeated, tag = "3")] pub expressions: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="4")] + #[prost(message, repeated, tag = "4")] pub scope: ::prost::alloc::vec::Vec, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Check { - #[prost(message, repeated, tag="1")] + #[prost(message, repeated, tag = "1")] pub queries: ::prost::alloc::vec::Vec, - #[prost(enumeration="check::Kind", optional, tag="2")] + #[prost(enumeration = "check::Kind", optional, tag = "2")] pub kind: ::core::option::Option, } /// Nested message and enum types in `Check`. @@ -135,108 +135,108 @@ pub mod check { } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Predicate { - #[prost(uint64, required, tag="1")] + #[prost(uint64, required, tag = "1")] pub name: u64, - #[prost(message, repeated, tag="2")] + #[prost(message, repeated, tag = "2")] pub terms: ::prost::alloc::vec::Vec, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Term { - #[prost(oneof="term::Content", tags="1, 2, 3, 4, 5, 6, 7, 8, 9, 10")] + #[prost(oneof = "term::Content", tags = "1, 2, 3, 4, 5, 6, 7, 8, 9, 10")] pub content: ::core::option::Option, } /// Nested message and enum types in `Term`. pub mod term { #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Content { - #[prost(uint32, tag="1")] + #[prost(uint32, tag = "1")] Variable(u32), - #[prost(int64, tag="2")] + #[prost(int64, tag = "2")] Integer(i64), - #[prost(uint64, tag="3")] + #[prost(uint64, tag = "3")] String(u64), - #[prost(uint64, tag="4")] + #[prost(uint64, tag = "4")] Date(u64), - #[prost(bytes, tag="5")] + #[prost(bytes, tag = "5")] Bytes(::prost::alloc::vec::Vec), - #[prost(bool, tag="6")] + #[prost(bool, tag = "6")] Bool(bool), - #[prost(message, tag="7")] + #[prost(message, tag = "7")] Set(super::TermSet), - #[prost(message, tag="8")] + #[prost(message, tag = "8")] Null(super::Empty), - #[prost(message, tag="9")] + #[prost(message, tag = "9")] Array(super::Array), - #[prost(message, tag="10")] + #[prost(message, tag = "10")] Map(super::Map), } } #[derive(Clone, PartialEq, ::prost::Message)] pub struct TermSet { - #[prost(message, repeated, tag="1")] + #[prost(message, repeated, tag = "1")] pub set: ::prost::alloc::vec::Vec, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Array { - #[prost(message, repeated, tag="1")] + #[prost(message, repeated, tag = "1")] pub array: ::prost::alloc::vec::Vec, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Map { - #[prost(message, repeated, tag="1")] + #[prost(message, repeated, tag = "1")] pub entries: ::prost::alloc::vec::Vec, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct MapEntry { - #[prost(message, required, tag="1")] + #[prost(message, required, tag = "1")] pub key: MapKey, - #[prost(message, required, tag="2")] + #[prost(message, required, tag = "2")] pub value: Term, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct MapKey { - #[prost(oneof="map_key::Content", tags="1, 2")] + #[prost(oneof = "map_key::Content", tags = "1, 2")] pub content: ::core::option::Option, } /// Nested message and enum types in `MapKey`. pub mod map_key { #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Content { - #[prost(int64, tag="1")] + #[prost(int64, tag = "1")] Integer(i64), - #[prost(uint64, tag="2")] + #[prost(uint64, tag = "2")] String(u64), } } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Expression { - #[prost(message, repeated, tag="1")] + #[prost(message, repeated, tag = "1")] pub ops: ::prost::alloc::vec::Vec, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Op { - #[prost(oneof="op::Content", tags="1, 2, 3, 4")] + #[prost(oneof = "op::Content", tags = "1, 2, 3, 4")] pub content: ::core::option::Option, } /// Nested message and enum types in `Op`. pub mod op { #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Content { - #[prost(message, tag="1")] + #[prost(message, tag = "1")] Value(super::Term), - #[prost(message, tag="2")] + #[prost(message, tag = "2")] Unary(super::OpUnary), - #[prost(message, tag="3")] + #[prost(message, tag = "3")] Binary(super::OpBinary), - #[prost(message, tag="4")] + #[prost(message, tag = "4")] Closure(super::OpClosure), } } #[derive(Clone, PartialEq, ::prost::Message)] pub struct OpUnary { - #[prost(enumeration="op_unary::Kind", required, tag="1")] + #[prost(enumeration = "op_unary::Kind", required, tag = "1")] pub kind: i32, - #[prost(uint64, optional, tag="2")] + #[prost(uint64, optional, tag = "2")] pub ffi_name: ::core::option::Option, } /// Nested message and enum types in `OpUnary`. @@ -253,9 +253,9 @@ pub mod op_unary { } #[derive(Clone, PartialEq, ::prost::Message)] pub struct OpBinary { - #[prost(enumeration="op_binary::Kind", required, tag="1")] + #[prost(enumeration = "op_binary::Kind", required, tag = "1")] pub kind: i32, - #[prost(uint64, optional, tag="2")] + #[prost(uint64, optional, tag = "2")] pub ffi_name: ::core::option::Option, } /// Nested message and enum types in `OpBinary`. @@ -297,16 +297,16 @@ pub mod op_binary { } #[derive(Clone, PartialEq, ::prost::Message)] pub struct OpClosure { - #[prost(uint32, repeated, packed="false", tag="1")] + #[prost(uint32, repeated, packed = "false", tag = "1")] pub params: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="2")] + #[prost(message, repeated, tag = "2")] pub ops: ::prost::alloc::vec::Vec, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Policy { - #[prost(message, repeated, tag="1")] + #[prost(message, repeated, tag = "1")] pub queries: ::prost::alloc::vec::Vec, - #[prost(enumeration="policy::Kind", required, tag="2")] + #[prost(enumeration = "policy::Kind", required, tag = "2")] pub kind: i32, } /// Nested message and enum types in `Policy`. @@ -320,111 +320,110 @@ pub mod policy { } #[derive(Clone, PartialEq, ::prost::Message)] pub struct AuthorizerPolicies { - #[prost(string, repeated, tag="1")] + #[prost(string, repeated, tag = "1")] pub symbols: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, - #[prost(uint32, optional, tag="2")] + #[prost(uint32, optional, tag = "2")] pub version: ::core::option::Option, - #[prost(message, repeated, tag="3")] + #[prost(message, repeated, tag = "3")] pub facts: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="4")] + #[prost(message, repeated, tag = "4")] pub rules: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="5")] + #[prost(message, repeated, tag = "5")] pub checks: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="6")] + #[prost(message, repeated, tag = "6")] pub policies: ::prost::alloc::vec::Vec, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct ThirdPartyBlockRequest { - #[prost(message, optional, tag="1")] + #[prost(message, optional, tag = "1")] pub legacy_previous_key: ::core::option::Option, - #[prost(message, repeated, tag="2")] + #[prost(message, repeated, tag = "2")] pub legacy_public_keys: ::prost::alloc::vec::Vec, - #[prost(bytes="vec", required, tag="3")] + #[prost(bytes = "vec", required, tag = "3")] pub previous_signature: ::prost::alloc::vec::Vec, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct ThirdPartyBlockContents { - #[prost(bytes="vec", required, tag="1")] + #[prost(bytes = "vec", required, tag = "1")] pub payload: ::prost::alloc::vec::Vec, - #[prost(message, required, tag="2")] + #[prost(message, required, tag = "2")] pub external_signature: ExternalSignature, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct AuthorizerSnapshot { - #[prost(message, required, tag="1")] + #[prost(message, required, tag = "1")] pub limits: RunLimits, - #[prost(uint64, required, tag="2")] + #[prost(uint64, required, tag = "2")] pub execution_time: u64, - #[prost(message, required, tag="3")] + #[prost(message, required, tag = "3")] pub world: AuthorizerWorld, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct RunLimits { - #[prost(uint64, required, tag="1")] + #[prost(uint64, required, tag = "1")] pub max_facts: u64, - #[prost(uint64, required, tag="2")] + #[prost(uint64, required, tag = "2")] pub max_iterations: u64, - #[prost(uint64, required, tag="3")] + #[prost(uint64, required, tag = "3")] pub max_time: u64, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct AuthorizerWorld { - #[prost(uint32, optional, tag="1")] + #[prost(uint32, optional, tag = "1")] pub version: ::core::option::Option, - #[prost(string, repeated, tag="2")] + #[prost(string, repeated, tag = "2")] pub symbols: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, - #[prost(message, repeated, tag="3")] + #[prost(message, repeated, tag = "3")] pub public_keys: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="4")] + #[prost(message, repeated, tag = "4")] pub blocks: ::prost::alloc::vec::Vec, - #[prost(message, required, tag="5")] + #[prost(message, required, tag = "5")] pub authorizer_block: SnapshotBlock, - #[prost(message, repeated, tag="6")] + #[prost(message, repeated, tag = "6")] pub authorizer_policies: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="7")] + #[prost(message, repeated, tag = "7")] pub generated_facts: ::prost::alloc::vec::Vec, - #[prost(uint64, required, tag="8")] + #[prost(uint64, required, tag = "8")] pub iterations: u64, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct Origin { - #[prost(oneof="origin::Content", tags="1, 2")] + #[prost(oneof = "origin::Content", tags = "1, 2")] pub content: ::core::option::Option, } /// Nested message and enum types in `Origin`. pub mod origin { #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Content { - #[prost(message, tag="1")] + #[prost(message, tag = "1")] Authorizer(super::Empty), - #[prost(uint32, tag="2")] + #[prost(uint32, tag = "2")] Origin(u32), } } #[derive(Clone, PartialEq, ::prost::Message)] -pub struct Empty { -} +pub struct Empty {} #[derive(Clone, PartialEq, ::prost::Message)] pub struct GeneratedFacts { - #[prost(message, repeated, tag="1")] + #[prost(message, repeated, tag = "1")] pub origins: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="2")] + #[prost(message, repeated, tag = "2")] pub facts: ::prost::alloc::vec::Vec, } #[derive(Clone, PartialEq, ::prost::Message)] pub struct SnapshotBlock { - #[prost(string, optional, tag="1")] + #[prost(string, optional, tag = "1")] pub context: ::core::option::Option<::prost::alloc::string::String>, - #[prost(uint32, optional, tag="2")] + #[prost(uint32, optional, tag = "2")] pub version: ::core::option::Option, - #[prost(message, repeated, tag="3")] + #[prost(message, repeated, tag = "3")] pub facts: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="4")] + #[prost(message, repeated, tag = "4")] pub rules: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="5")] + #[prost(message, repeated, tag = "5")] pub checks: ::prost::alloc::vec::Vec, - #[prost(message, repeated, tag="6")] + #[prost(message, repeated, tag = "6")] pub scope: ::prost::alloc::vec::Vec, - #[prost(message, optional, tag="7")] + #[prost(message, optional, tag = "7")] pub external_key: ::core::option::Option, } diff --git a/biscuit-auth/src/format/schema.proto b/biscuit-proto/src/schema.proto similarity index 100% rename from biscuit-auth/src/format/schema.proto rename to biscuit-proto/src/schema.proto diff --git a/biscuit-proto/tests/schema_up_to_date.rs b/biscuit-proto/tests/schema_up_to_date.rs new file mode 100644 index 00000000..c9d830b5 --- /dev/null +++ b/biscuit-proto/tests/schema_up_to_date.rs @@ -0,0 +1,28 @@ +use std::io::Read; + +#[test] +fn schema_up_to_date() { + let out_dir = match std::env::var("OUT_DIR") { + Ok(dir) => dir, + Err(_) => return, + }; + prost_build::compile_protos(&["src/schema.proto"], &["src/"]).unwrap(); + let mut generated = String::new(); + std::fs::File::open(format!("{out_dir}/biscuit.format.schema.rs")) + .unwrap() + .read_to_string(&mut generated) + .unwrap(); + + let committed = include_str!("../src/lib.rs"); + + if generated != committed { + println!( + "{}", + colored_diff::PrettyDifference { + expected: &generated, + actual: committed, + } + ); + panic!("biscuit-proto/src/lib.rs is out of date with biscuit-proto/src/schema.proto"); + } +}