Skip to content

Commit d4f3673

Browse files
authored
Merge pull request #136 from preuss-adam/apreuss/builder-rule-validation
Ensure Biscuit Builder Runs Rule Validation
2 parents 3ef87dd + b10557a commit d4f3673

3 files changed

Lines changed: 70 additions & 1 deletion

File tree

src/main/java/org/eclipse/biscuit/token/builder/Block.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import org.eclipse.biscuit.datalog.SchemaVersion;
2727
import org.eclipse.biscuit.datalog.SymbolTable;
2828
import org.eclipse.biscuit.error.Error;
29+
import org.eclipse.biscuit.error.LogicError;
30+
import org.eclipse.biscuit.error.Result;
2931
import org.eclipse.biscuit.token.builder.parser.Parser;
3032

3133
public final class Block {
@@ -56,6 +58,18 @@ public Block addFact(String s) throws Error.Parser {
5658
return addFact(res.getOk()._2);
5759
}
5860

61+
public Result<Block, Error.FailedLogic> addRule(Rule rule, boolean validate) {
62+
if (validate) {
63+
var valid = rule.validateVariables();
64+
if (valid.isErr()) {
65+
return Result.err(
66+
new Error.FailedLogic(new LogicError.InvalidBlockRule(0, valid.getErr())));
67+
}
68+
}
69+
this.rules.add(rule);
70+
return Result.ok(this);
71+
}
72+
5973
public Block addRule(Rule rule) {
6074
this.rules.add(rule);
6175
return this;

src/main/java/org/eclipse/biscuit/token/builder/Check.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,14 @@ public Check(org.eclipse.biscuit.datalog.Check.Kind kind, List<Rule> queries) {
2424
public Check(org.eclipse.biscuit.datalog.Check.Kind kind, Rule query) {
2525
this.kind = kind;
2626

27+
// Checks are queries that match facts, not rules that generate facts.
28+
// Replace the rule's head with a placeholder predicate since checks only use the body,
29+
// expressions, and scopes.
30+
Rule q =
31+
new Rule(
32+
new Predicate("query", new ArrayList<>()), query.body, query.expressions, query.scopes);
2733
ArrayList<Rule> r = new ArrayList<>();
28-
r.add(query);
34+
r.add(q);
2935
queries = r;
3036
}
3137

src/test/java/org/eclipse/biscuit/builder/BuilderTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,23 @@
1414
import java.nio.charset.StandardCharsets;
1515
import java.security.SecureRandom;
1616
import java.time.Instant;
17+
import java.util.ArrayList;
1718
import java.util.Arrays;
1819
import java.util.Date;
1920
import java.util.HashSet;
21+
import java.util.List;
2022
import java.util.Set;
2123
import org.eclipse.biscuit.crypto.KeyPair;
2224
import org.eclipse.biscuit.datalog.SymbolTable;
2325
import org.eclipse.biscuit.error.Error;
2426
import org.eclipse.biscuit.token.Biscuit;
2527
import org.eclipse.biscuit.token.builder.Block;
28+
import org.eclipse.biscuit.token.builder.Check;
2629
import org.eclipse.biscuit.token.builder.Expression;
30+
import org.eclipse.biscuit.token.builder.Rule;
2731
import org.eclipse.biscuit.token.builder.Term;
2832
import org.eclipse.biscuit.token.builder.Utils;
33+
import org.eclipse.biscuit.token.builder.parser.Parser;
2934
import org.junit.jupiter.api.Test;
3035

3136
public class BuilderTest {
@@ -143,4 +148,48 @@ public void testArrayValueIsCopy() {
143148
System.identityHashCode(term.getValue()),
144149
"different objects");
145150
}
151+
152+
@Test
153+
public void testCheckOnlyIncludesQuery() {
154+
// Built `not_before` check:
155+
var head = Utils.pred("nbf", List.of(Utils.var("0"), Utils.var("1")));
156+
var body =
157+
List.of(
158+
Utils.pred("time", List.of(Utils.var("0"))),
159+
Utils.pred("nbf", List.of(Utils.var("1"))));
160+
List<Expression> expressions =
161+
List.of(
162+
new Expression.Binary(
163+
Expression.Op.LessOrEqual,
164+
new Expression.Value(Utils.var("1")),
165+
new Expression.Value(Utils.var("0"))));
166+
List<org.eclipse.biscuit.token.builder.Scope> scopes = new ArrayList<>();
167+
var nbfRule = new Rule(head, body, expressions, scopes);
168+
Check builtCheck = Utils.check(nbfRule);
169+
170+
// Parsed `not_before` check:
171+
var res = Parser.check("check if time($0), nbf($1), $1 <= $0");
172+
173+
assertEquals(builtCheck, res.getOk()._2);
174+
}
175+
176+
@Test
177+
public void testInvalidRuleFails() {
178+
// Head must not include variables that are not in the body
179+
var head = Utils.pred("nbf", List.of(Utils.var("x")));
180+
var body =
181+
List.of(
182+
Utils.pred("time", List.of(Utils.var("0"))),
183+
Utils.pred("nbf", List.of(Utils.var("1"))));
184+
List<Expression> expressions =
185+
List.of(
186+
new Expression.Binary(
187+
Expression.Op.LessOrEqual,
188+
new Expression.Value(Utils.var("1")),
189+
new Expression.Value(Utils.var("0"))));
190+
List<org.eclipse.biscuit.token.builder.Scope> scopes = new ArrayList<>();
191+
var nbfRule = new Rule(head, body, expressions, scopes);
192+
Block authorityBuilder = new Block();
193+
assertTrue(authorityBuilder.addRule(nbfRule, true).isErr());
194+
}
146195
}

0 commit comments

Comments
 (0)