Skip to content

Commit

Permalink
Yay, test018 passes...all the tests pass!
Browse files Browse the repository at this point in the history
  • Loading branch information
malcolmstill committed Mar 28, 2024
1 parent a5a06c0 commit 26028a7
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
20 changes: 20 additions & 0 deletions biscuit-datalog/src/rule.zig
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,26 @@ pub const Rule = struct {
}
}

/// Checks there a no unbound variables in the head (i.e. every head variable must appear in the )
pub fn validateVariables(rule: Rule) bool {
blk: for (rule.head.terms.items) |head_term| {
const head_variable = if (head_term == .variable) head_term.variable else continue;

for (rule.body.items) |body_predicate| {
for (body_predicate.terms.items) |body_term| {
const body_variable = if (head_term == .variable) body_term.variable else continue;

if (head_variable == body_variable) continue :blk;
}
}

// We haven't found this loop's head variable anywhere in the body (i.e. the variable is unbound)
return false;
}

return true;
}

pub fn format(rule: Rule, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
try writer.print("{any} <- ", .{rule.head});
for (rule.body.items, 0..) |*predicate, i| {
Expand Down
15 changes: 14 additions & 1 deletion biscuit-samples/src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub fn validate(alloc: mem.Allocator, token: []const u8, public_key: std.crypto.
}
},
.failed_authorizer_check => return error.NotImplemented,
.unbound_variable => continue,
}
}
},
Expand All @@ -105,6 +106,7 @@ pub fn validate(alloc: mem.Allocator, token: []const u8, public_key: std.crypto.
check_accounted_for = true;
}
},
.unbound_variable => continue,
}
}
},
Expand All @@ -117,7 +119,18 @@ pub fn validate(alloc: mem.Allocator, token: []const u8, public_key: std.crypto.
},
else => return err,
},
.InvalidBlockRule => runValidation(alloc, token, public_key, authorizer_code, &errors) catch |err| switch (err) {
.InvalidBlockRule => |_| runValidation(alloc, token, public_key, authorizer_code, &errors) catch |err| switch (err) {
error.AuthorizationFailed => {
for (errors.items) |found_failed_check| {
switch (found_failed_check) {
.no_matching_policy => continue,
.denied_by_policy => continue,
.failed_block_check => continue,
.failed_authorizer_check => return error.NotImplemented,
.unbound_variable => return,
}
}
},
else => return err,
},
},
Expand Down
10 changes: 10 additions & 0 deletions biscuit/src/authorizer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ pub const Authorizer = struct {
// Map from biscuit symbol space to authorizer symbol space
const rule = try authority_rule.convert(&biscuit.symbols, &authorizer.symbols);

if (!rule.validateVariables()) {
try errors.append(.unbound_variable);
}

// A authority block's rule trusts
const rule_trusted_origins = try TrustedOrigins.fromScopes(
authorizer.allocator,
Expand Down Expand Up @@ -208,6 +212,10 @@ pub const Authorizer = struct {
const rule = try block_rule.convert(&biscuit.symbols, &authorizer.symbols);
std.debug.print("block rule {any} CONVERTED to rule = {any}\n", .{ block_rule, rule });

if (!rule.validateVariables()) {
try errors.append(.unbound_variable);
}

const block_rule_trusted_origins = try TrustedOrigins.fromScopes(
authorizer.allocator,
rule.scopes.items,
Expand Down Expand Up @@ -374,11 +382,13 @@ const AuthorizerErrorKind = enum(u8) {
denied_by_policy,
failed_authorizer_check,
failed_block_check,
unbound_variable,
};

pub const AuthorizerError = union(AuthorizerErrorKind) {
no_matching_policy: void,
denied_by_policy: struct { deny_policy_id: usize },
failed_authorizer_check: struct { check_id: usize },
failed_block_check: struct { block_id: usize, check_id: usize },
unbound_variable: void,
};

0 comments on commit 26028a7

Please sign in to comment.