Skip to content

Commit

Permalink
Merge branch 'v5' into map-array
Browse files Browse the repository at this point in the history
  • Loading branch information
Geal committed Jun 8, 2024
2 parents d0c2317 + 525c278 commit b5c9d3b
Show file tree
Hide file tree
Showing 18 changed files with 962 additions and 261 deletions.
98 changes: 67 additions & 31 deletions biscuit-auth/examples/testcases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ fn run(target: String, root_key: Option<String>, test: bool, json: bool) {

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

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

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

if json {
let s = serde_json::to_string_pretty(&TestCases {
Expand Down Expand Up @@ -1279,12 +1281,6 @@ fn expressions(target: &str, root: &KeyPair, test: bool) -> TestResult {
check if true;
//boolean false and negation
check if !false;
//boolean and
check if !false && true;
//boolean or
check if false || true;
//boolean parens
check if (true || false) && true;
// boolean strict equality
check if true === true;
check if false === false;
Expand Down Expand Up @@ -1895,12 +1891,9 @@ fn integer_wraparound(target: &str, root: &KeyPair, test: bool) -> TestResult {

let biscuit = biscuit!(
r#"
// integer overflows must abort evaluating the whole expression
// todo update this test when integer overflows abort
// the whole datalog evaluation
check if true || 10000000000 * 10000000000 != 0;
check if true || 9223372036854775807 + 1 != 0;
check if true || -9223372036854775808 - 1 != 0;
check if 10000000000 * 10000000000 != 0;
check if 9223372036854775807 + 1 != 0;
check if -9223372036854775808 - 1 != 0;
"#
)
.build_with_rng(&root, SymbolTable::default(), &mut rng)
Expand Down Expand Up @@ -2081,41 +2074,85 @@ fn heterogeneous_equal(target: &str, root: &KeyPair, test: bool) -> TestResult {
}
}

fn expressions_v5(target: &str, root: &KeyPair, test: bool) -> TestResult {
fn closures(target: &str, root: &KeyPair, test: bool) -> TestResult {
let mut rng: StdRng = SeedableRng::seed_from_u64(1234);
let title = "test expression syntax and all available operations (v5 blocks)".to_string();
let filename = "test032_expressions_v5".to_string();
let title = "test laziness and closures".to_string();
let filename = "test032_laziness_closures".to_string();
let token;

let biscuit = biscuit!(
r#"
//boolean and
// boolean and
check if !false && true;
//boolean or
// boolean or
check if false || true;
//boolean parens
// boolean parens
check if (true || false) && true;
// boolean and laziness
//check if !(false && "x".intersection("x"));
check if !(false && "x".intersection("x"));
// boolean or laziness
//check if true || "x".intersection("x");
//all
//check if [1,2,3].all($p -> $p > 0);
//all
//check if ![1,2,3].all($p -> $p == 2);
//any
//check if [1,2,3].any($p -> $p > 2);
//any
//check if ![1,2,3].any($p -> $p > 3);
check if true || "x".intersection("x");
// all
check if {1,2,3}.all($p -> $p > 0);
// all
check if !{1,2,3}.all($p -> $p == 2);
// any
check if {1,2,3}.any($p -> $p > 2);
// any
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)
.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"),
);
validations.insert(
"shadowing".to_string(),
validate_token(
root,
&data[..],
"allow if [true].any($p -> [true].all($p -> $p))",
),
);

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 = "test033_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,3].all($p -> $p > 0);
// all
check if ![1,2,3].all($p -> $p == 2);
// any
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};
Expand All @@ -2142,7 +2179,6 @@ fn expressions_v5(target: &str, root: &KeyPair, test: bool) -> TestResult {
validations,
}
}

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

Expand Down
143 changes: 122 additions & 21 deletions biscuit-auth/samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1221,9 +1221,6 @@ public keys: []
```
check if true;
check if !false;
check if !false && true;
check if false || true;
check if (true || false) && true;
check if true === true;
check if false === false;
check if 1 < 2;
Expand Down Expand Up @@ -1270,7 +1267,7 @@ allow if true;
```

revocation ids:
- `3d5b23b502b3dd920bfb68b9039164d1563bb8927210166fa5c17f41b76b31bb957bc2ed3318452958f658baa2d398fe4cf25c58a27e6c8bc42c9702c8aa1b0c`
- `a2640c5f1c1e86302e77422ccda6f7f02a21f63d88d1c34b5b01956227fa0228e49d76482be9d2f251a23c38c425a49ce957b001edd3c18504f37cbd9a341c0b`

authorizer world:
```
Expand All @@ -1284,15 +1281,13 @@ World {
),
checks: [
"check if !false",
"check if !false && true",
"check if \"aaabde\" === \"aaa\" + \"b\" + \"de\"",
"check if \"aaabde\".contains(\"abd\")",
"check if \"aaabde\".matches(\"a*c?.e\")",
"check if \"abcD12\" === \"abcD12\"",
"check if \"abcD12\".length() === 6",
"check if \"hello world\".starts_with(\"hello\") && \"hello world\".ends_with(\"world\")",
"check if \"é\".length() === 2",
"check if (true || false) && true",
"check if 1 + 2 * 3 - 4 / 2 === 5",
"check if 1 < 2",
"check if 1 <= 1",
Expand All @@ -1309,7 +1304,6 @@ World {
"check if 2020-12-04T09:46:41Z >= 2020-12-04T09:46:41Z",
"check if 3 === 3",
"check if false === false",
"check if false || true",
"check if hex:12ab === hex:12ab",
"check if true",
"check if true === true",
Expand Down Expand Up @@ -2263,9 +2257,9 @@ symbols: []
public keys: []

```
check if true || 10000000000 * 10000000000 != 0;
check if true || 9223372036854775807 + 1 != 0;
check if true || -9223372036854775808 - 1 != 0;
check if 10000000000 * 10000000000 != 0;
check if 9223372036854775807 + 1 != 0;
check if -9223372036854775808 - 1 != 0;
```

### validation
Expand All @@ -2276,7 +2270,7 @@ allow if true;
```

revocation ids:
- `a57be539aae237040fe6c2c28c4263516147c9f0d1d7ba88a385f1574f504c544164a2c747efd8b30eaab9d351c383cc1875642f173546d5f4b53b2220c87a0a`
- `365092619226161cf3973343f02c829fe05ab2b0d01f09555272348c9fcce041846be6159badd643aee108c9ce735ca8d12a009979c46b6e2c46e7999824c008`

authorizer world:
```
Expand All @@ -2289,9 +2283,9 @@ World {
0,
),
checks: [
"check if true || -9223372036854775808 - 1 != 0",
"check if true || 10000000000 * 10000000000 != 0",
"check if true || 9223372036854775807 + 1 != 0",
"check if -9223372036854775808 - 1 != 0",
"check if 10000000000 * 10000000000 != 0",
"check if 9223372036854775807 + 1 != 0",
],
},
]
Expand Down Expand Up @@ -2768,24 +2762,131 @@ result: `Err(FailedLogic(Unauthorized { policy: Allow(0), checks: [Block(FailedB

------------------------------

## test expression syntax and all available operations (v5 blocks): test032_expressions_v5.bc
## test laziness and closures: test032_laziness_closures.bc
### token

authority:
symbols: ["a", "b", "c", "d"]
symbols: ["x", "p", "q"]

public keys: []

```
check if !false && true;
check if false || true;
check if (true || false) && true;
check if !(false && "x".intersection("x"));
check if true || "x".intersection("x");
check if {1, 2, 3}.all($p -> $p > 0);
check if !{1, 2, 3}.all($p -> $p == 2);
check if {1, 2, 3}.any($p -> $p > 2);
check if !{1, 2, 3}.any($p -> $p > 3);
check if {1, 2, 3}.any($p -> $p > 1 && {3, 4, 5}.any($q -> $p == $q));
```

### validation

authorizer code:
```
allow if true;
```

revocation ids:
- `65e4da4fa213559d3b1097424504d2c9daeb28b4db51c49254852b6f57dc55e200f2f977b459f0c35e17c3c06394bfcaf5db7106e23bb2a623f48c4b84649a0b`

authorizer world:
```
World {
facts: []
rules: []
checks: [
Checks {
origin: Some(
0,
),
checks: [
"check if !(false && \"x\".intersection(\"x\"))",
"check if !false && true",
"check if !{1, 2, 3}.all($p -> $p == 2)",
"check if !{1, 2, 3}.any($p -> $p > 3)",
"check if (true || false) && true",
"check if false || true",
"check if true || \"x\".intersection(\"x\")",
"check if {1, 2, 3}.all($p -> $p > 0)",
"check if {1, 2, 3}.any($p -> $p > 1 && {3, 4, 5}.any($q -> $p == $q))",
"check if {1, 2, 3}.any($p -> $p > 2)",
],
},
]
policies: [
"allow if true",
]
}
```

result: `Ok(0)`
### validation for "shadowing"

authorizer code:
```
allow if [true].any($p -> [true].all($p -> $p));
```

revocation ids:
- `65e4da4fa213559d3b1097424504d2c9daeb28b4db51c49254852b6f57dc55e200f2f977b459f0c35e17c3c06394bfcaf5db7106e23bb2a623f48c4b84649a0b`

authorizer world:
```
World {
facts: []
rules: []
checks: [
Checks {
origin: Some(
0,
),
checks: [
"check if !(false && \"x\".intersection(\"x\"))",
"check if !false && true",
"check if !{1, 2, 3}.all($p -> $p == 2)",
"check if !{1, 2, 3}.any($p -> $p > 3)",
"check if (true || false) && true",
"check if false || true",
"check if true || \"x\".intersection(\"x\")",
"check if {1, 2, 3}.all($p -> $p > 0)",
"check if {1, 2, 3}.any($p -> $p > 1 && {3, 4, 5}.any($q -> $p == $q))",
"check if {1, 2, 3}.any($p -> $p > 2)",
],
},
]
policies: [
"allow if [true].any($p -> [true].all($p -> $p))",
]
}
```

result: `Err(Execution(InvalidType))`


------------------------------

## test array and map operations (v5 blocks): test033_array_map.bc
### token

authority:
symbols: ["a", "b", "c", "p", "d"]

public keys: []

```
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, 3].all($p -> $p > 0);
check if ![1, 2, 3].all($p -> $p == 2);
check if [1, 2, 3].any($p -> $p > 2);
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"} == {1: "a", 2: "b"};
Expand All @@ -2800,7 +2901,7 @@ allow if true;
```

revocation ids:
- `5fde54d0492a63711a6a6697c058f0320c3b0449ecb055809ce4dde176fb1da53016258abe3ed58221e4bbbf6e83a7a3c2524d701377f01bf1405bfce2a65702`
- `f027c1e0b86bd3d53bbfffead4e61d71e907b58e0b0ec339c0bc2bdcab21aea4fb4c45643934816608533bc818c9ed14dc31d058021cbe4cec8dde5e519f0e07`

authorizer world:
```
Expand All @@ -2813,15 +2914,15 @@ World {
0,
),
checks: [
"check if !false && true",
"check if (true || false) && true",
"check if ![1, 2, 3].all($p -> $p == 2)",
"check if [\"a\", \"b\", \"c\"].contains(\"c\")",
"check if [\"a\", \"b\"] != [1, 2, 3]",
"check if [\"a\", \"b\"] == [\"a\", \"b\"]",
"check if [1, 2, 1].length() == 3",
"check if [1, 2, 3].all($p -> $p > 0)",
"check if [1, 2, 3].any($p -> $p > 2)",
"check if [1, 2, 3].starts_with([1, 2])",
"check if [4, 5, 6].ends_with([6])",
"check if false || true",
"check if {\"a\": 1, \"b\": 2, \"c\": 3, \"d\": 4}.contains(\"d\")",
"check if {\"a\": 1, \"b\": 2, \"c\": 3, \"d\": 4}.length() == 4",
"check if {1: \"a\", 2: \"b\"} != {\"a\": 1, \"b\": 2}",
Expand All @@ -2835,5 +2936,5 @@ World {
}
```

result: `Err(FailedLogic(Unauthorized { policy: Allow(0), checks: [Block(FailedBlockCheck { block_id: 0, check_id: 5, rule: "check if [\"a\", \"b\"] == [\"a\", \"b\"]" }), Block(FailedBlockCheck { block_id: 0, check_id: 11, rule: "check if {1: \"a\", 2: \"b\"} == {1: \"a\", 2: \"b\"}" })] }))`
result: `Err(Execution(InvalidType))`

Loading

0 comments on commit b5c9d3b

Please sign in to comment.