Skip to content

Commit

Permalink
Merge branch 'v5' into fipscuit
Browse files Browse the repository at this point in the history
  • Loading branch information
Geal committed Nov 3, 2024
2 parents d58d352 + e59f41d commit 56fa6c3
Show file tree
Hide file tree
Showing 29 changed files with 1,891 additions and 263 deletions.
2 changes: 2 additions & 0 deletions biscuit-auth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ uuid = { version = "1", optional = true }
biscuit-parser = { version = "0.1.2", path = "../biscuit-parser" }
biscuit-quote = { version = "0.2.2", optional = true, path = "../biscuit-quote" }
chrono = { version = "0.4.26", optional = true, default-features = false, features = ["serde"] }
serde_json = "1.0.117"
ecdsa = { version = "0.16.9", features = ["signing", "verifying", "pem", "alloc", "pkcs8", "serde"] }
p256 = "0.11.1"
pkcs8 = "0.9.0"
elliptic-curve = { version = "0.13.8", features = ["pkcs8"] }


[dev-dependencies]
bencher = "0.1.5"
rand = "0.8"
Expand Down
146 changes: 127 additions & 19 deletions biscuit-auth/examples/testcases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,11 @@ fn run(target: String, root_key: Option<String>, test: bool, json: bool) {

add_test_result(&mut results, closures(&target, &root, test));

add_test_result(&mut results, secp256r1(&target, &root, test));
add_test_result(&mut results, type_of(&target, &root, test));

add_test_result(&mut results, array_map(&target, &root, test));

add_test_result(&mut results, secp256r1(&target, &root, test));
if json {
let s = serde_json::to_string_pretty(&TestCases {
root_private_key: hex::encode(root.private().to_bytes()),
Expand Down Expand Up @@ -1333,22 +1336,22 @@ fn expressions(target: &str, root: &KeyPair, test: bool) -> TestResult {
check if hex:12ab === hex:12ab;
// set contains
check if [1, 2].contains(2);
check if [2020-12-04T09:46:41+00:00, 2019-12-04T09:46:41+00:00].contains(2020-12-04T09:46:41+00:00);
check if [true, false, true].contains(true);
check if ["abc", "def"].contains("abc");
check if [hex:12ab, hex:34de].contains(hex:34de);
check if [1, 2].contains([2]);
check if {1, 2}.contains(2);
check if { 2020-12-04T09:46:41+00:00, 2019-12-04T09:46:41+00:00}.contains(2020-12-04T09:46:41+00:00);
check if {true, false, true}.contains(true);
check if {"abc", "def"}.contains("abc");
check if {hex:12ab, hex:34de}.contains(hex:34de);
check if {1, 2}.contains({2});
// set strict equal
check if [1, 2] === [1, 2];
check if {1, 2} === {1, 2};
// set intersection
check if [1, 2].intersection([2, 3]) === [2];
check if {1, 2}.intersection({2, 3}) === {2};
// set union
check if [1, 2].union([2, 3]) === [1, 2, 3];
check if {1, 2}.union({2, 3}) === {1, 2, 3};
// chained method calls
check if [1, 2, 3].intersection([1, 2]).contains(1);
check if {1, 2, 3}.intersection({1, 2}).contains(1);
// chained method calls with unary method
check if [1, 2, 3].intersection([1, 2]).length() === 2;
check if {1, 2, 3}.intersection({1, 2}).length() === 2;
"#)
.build_with_rng(&root, SymbolTable::default(), &mut rng)
.unwrap();
Expand Down Expand Up @@ -2110,15 +2113,15 @@ fn closures(target: &str, root: &KeyPair, test: bool) -> TestResult {
// boolean or laziness
check if true || "x".intersection("x");
// all
check if [1,2,3].all($p -> $p > 0);
check if {1,2,3}.all($p -> $p > 0);
// all
check if ![1,2,3].all($p -> $p == 2);
check if !{1,2,3}.all($p -> $p == 2);
// any
check if [1,2,3].any($p -> $p > 2);
check if {1,2,3}.any($p -> $p > 2);
// any
check if ![1,2,3].any($p -> $p > 3);
check if !{1,2,3}.any($p -> $p > 3);
// nested closures
check if [1,2,3].any($p -> $p > 1 && [3,4,5].any($q -> $p == $q));
check if {1,2,3}.any($p -> $p > 1 && {3,4,5}.any($q -> $p == $q));
"#
)
.build_with_rng(&root, SymbolTable::default(), &mut rng)
Expand Down Expand Up @@ -2150,10 +2153,116 @@ fn closures(target: &str, root: &KeyPair, test: bool) -> TestResult {
}
}

fn type_of(target: &str, root: &KeyPair, test: bool) -> TestResult {
let mut rng: StdRng = SeedableRng::seed_from_u64(1234);
let title = "test .type()".to_string();
let filename = "test033_typeof".to_string();
let token;

let biscuit = biscuit!(
r#"
check if 1.type() == "integer";
integer(1);
check if integer($t), $t.type() == "integer";
check if "test".type() == "string";
string("test");
check if string($t), $t.type() == "string";
check if (2023-12-28T00:00:00Z).type() == "date";
date(2023-12-28T00:00:00Z);
check if date($t), $t.type() == "date";
check if hex:aa.type() == "bytes";
bytes(hex:aa);
check if bytes($t), $t.type() == "bytes";
check if true.type() == "bool";
bool(true);
check if bool($t), $t.type() == "bool";
check if {true, false}.type() == "set";
set({true, false});
check if set($t), $t.type() == "set";
check if null.type() == "null";
null(null);
check if null($t), $t.type() == "null";
"#
)
.build_with_rng(&root, SymbolTable::default(), &mut rng)
.unwrap();

token = print_blocks(&biscuit);

let data = write_or_load_testcase(target, &filename, root, &biscuit, test);

let mut validations = BTreeMap::new();
validations.insert(
"".to_string(),
validate_token(root, &data[..], "allow if true"),
);

TestResult {
title,
filename,
token,
validations,
}
}

fn array_map(target: &str, root: &KeyPair, test: bool) -> TestResult {
let mut rng: StdRng = SeedableRng::seed_from_u64(1234);
let title = "test array and map operations (v5 blocks)".to_string();
let filename = "test034_array_map".to_string();
let token;

let biscuit = biscuit!(
r#"
// array
check if [1, 2, 1].length() == 3;
check if ["a", "b"] != [1, 2, 3];
check if ["a", "b"] == ["a", "b"];
check if ["a", "b", "c"].contains("c");
check if [1, 2, 3].starts_with([1, 2]);
check if [4, 5, 6 ].ends_with([6]);
check if [1,2, "a"].get(2) == "a";
check if [1, 2].get(3) == null;
check if [1,2,3].all($p -> $p > 0);
check if [1,2,3].any($p -> $p > 2);
// map
check if { "a": 1 , "b": 2, "c": 3, "d": 4}.length() == 4;
check if { 1: "a" , 2: "b"} != { "a": 1 , "b": 2};
check if { 1: "a" , 2: "b"} == { 2: "b", 1: "a" };
check if { "a": 1 , "b": 2, "c": 3, "d": 4}.contains("d");
check if { "a": 1 , "b": 2, 1: "A" }.get("a") == 1;
check if { "a": 1 , "b": 2, 1: "A" }.get(1) == "A";
check if { "a": 1 , "b": 2, 1: "A" }.get("c") == null;
check if { "a": 1 , "b": 2, 1: "A" }.get(2) == null;
check if { "a": 1 , "b": 2 }.all($kv -> $kv.get(0) != "c" && $kv.get(1) < 3 );
check if { "a": 1 , "b": 2, 1: "A" }.any($kv -> $kv.get(0) == 1 && $kv.get(1) == "A" );
// nesting
check if { "user": { "id": 1, "roles": ["admin"] } }.get("user").get("roles").contains("admin");
"#
)
.build_with_rng(&root, SymbolTable::default(), &mut rng)
.unwrap();
token = print_blocks(&biscuit);

let data = write_or_load_testcase(target, &filename, root, &biscuit, test);

let mut validations = BTreeMap::new();
validations.insert(
"".to_string(),
validate_token(root, &data[..], "allow if true"),
);

TestResult {
title,
filename,
token,
validations,
}
}

fn secp256r1(target: &str, root: &KeyPair, test: bool) -> TestResult {
let mut rng: StdRng = SeedableRng::seed_from_u64(1234);
let title = "ECDSA secp256r1 signatures".to_string();
let filename = "test033_secp256r1".to_string();
let filename = "test035_secp256r1".to_string();
let token;

let keypair2 = KeyPair::new_with_rng(Algorithm::Secp256r1, &mut rng);
Expand Down Expand Up @@ -2204,7 +2313,6 @@ fn secp256r1(target: &str, root: &KeyPair, test: bool) -> TestResult {
validations,
}
}

fn print_blocks(token: &Biscuit) -> Vec<BlockContent> {
let mut v = Vec::new();

Expand Down
Loading

0 comments on commit 56fa6c3

Please sign in to comment.