Skip to content

Commit

Permalink
remove #ambient and #authority symbols, and privileged rules
Browse files Browse the repository at this point in the history
replace test cases test7_invalid_block_fact_authority,
test8_invalid_block_fact_ambient.bc and test10_authority_rules.bc
with test for scopes: test7_scoped_rules, test7_scoped_rules
and test10_verifier_scope
  • Loading branch information
Geal committed Sep 5, 2021
1 parent f750e2b commit 42b4bec
Show file tree
Hide file tree
Showing 9 changed files with 308 additions and 625 deletions.
382 changes: 185 additions & 197 deletions examples/testcases.rs

Large diffs are not rendered by default.

62 changes: 17 additions & 45 deletions src/datalog/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,8 +459,6 @@ pub fn match_preds(rule_pred: &Predicate, fact_pred: &Predicate) -> bool {
pub struct World {
pub facts: HashSet<Fact>,
pub rules: Vec<Rule>,
/// special rules that can generate authority or ambient facts
pub privileged_rules: Vec<Rule>,
}

impl World {
Expand All @@ -476,42 +474,20 @@ impl World {
self.rules.push(rule);
}

pub fn add_privileged_rule(&mut self, rule: Rule) {
self.privileged_rules.push(rule);
pub fn run(&mut self) -> Result<(), crate::error::RunLimit> {
self.run_with_limits(RunLimits::default())
}

pub fn run(&mut self, restricted_symbols: &[u64]) -> Result<(), crate::error::RunLimit> {
self.run_with_limits(RunLimits::default(), restricted_symbols)
}

pub fn run_with_limits(
&mut self,
limits: RunLimits,
restricted_symbols: &[u64],
) -> Result<(), crate::error::RunLimit> {
pub fn run_with_limits(&mut self, limits: RunLimits) -> Result<(), crate::error::RunLimit> {
let start = Instant::now();
let time_limit = start + limits.max_time;
let mut index = 0;

loop {
let mut new_facts: Vec<Fact> = Vec::new();
for rule in self.privileged_rules.iter() {
new_facts.extend(rule.apply(&self.facts));
//println!("new_facts after applying {:?}:\n{:#?}", rule, new_facts);
}

for rule in self.rules.iter() {
new_facts.extend(rule.apply(&self.facts).filter_map(|fact| {
match fact.predicate.ids.get(0) {
Some(ID::Symbol(sym)) => {
if restricted_symbols.contains(&sym) {
return None;
}
}
_ => {}
};
Some(fact)
}));
new_facts.extend(rule.apply(&self.facts));
//println!("new_facts after applying {:?}:\n{:#?}", rule, new_facts);
}

Expand Down Expand Up @@ -655,7 +631,7 @@ mod tests {
println!("adding r2: {}", syms.print_rule(&r2));
w.add_rule(r2);

w.run(&[]).unwrap();
w.run().unwrap();

println!("parents:");
let res = w.query(pred(
Expand All @@ -678,7 +654,7 @@ mod tests {
))
);
w.add_fact(fact(parent, &[&c, &e]));
w.run(&[]).unwrap();
w.run().unwrap();
let mut res = w.query(pred(
grandparent,
&[var(&mut syms, "grandparent"), var(&mut syms, "grandchild")],
Expand Down Expand Up @@ -1105,17 +1081,13 @@ mod tests {
let check1 = syms.insert("check1");
let check2 = syms.insert("check2");

w.add_fact(fact(resource, &[&ambient, &file2]));
w.add_fact(fact(operation, &[&ambient, &write]));
w.add_fact(fact(right, &[&authority, &file1, &read]));
w.add_fact(fact(right, &[&authority, &file2, &read]));
w.add_fact(fact(right, &[&authority, &file1, &write]));
w.add_fact(fact(resource, &[&file2]));
w.add_fact(fact(operation, &[&write]));
w.add_fact(fact(right, &[&file1, &read]));
w.add_fact(fact(right, &[&file2, &read]));
w.add_fact(fact(right, &[&file1, &write]));

let res = w.query_rule(rule(
check1,
&[&file1],
&[pred(resource, &[&ambient, &file1])],
));
let res = w.query_rule(rule(check1, &[&file1], &[pred(resource, &[&file1])]));

for fact in &res {
println!("\t{}", syms.print_fact(fact));
Expand All @@ -1127,9 +1099,9 @@ mod tests {
check2,
&[ID::Variable(0)],
&[
pred(resource, &[&ambient, &ID::Variable(0)]),
pred(operation, &[&ambient, &read]),
pred(right, &[&authority, &ID::Variable(0), &read]),
pred(resource, &[&ID::Variable(0)]),
pred(operation, &[&read]),
pred(right, &[&ID::Variable(0), &read]),
],
));

Expand Down Expand Up @@ -1200,7 +1172,7 @@ mod tests {
let any1 = var(&mut syms, "any1");
let any2 = var(&mut syms, "any2");

w.add_fact(fact(operation, &[&ambient, &write]));
w.add_fact(fact(operation, &[&write]));

let r1 = rule(
operation,
Expand All @@ -1222,7 +1194,7 @@ mod tests {
// in case it is generated though, verify that rule application
// will not match it
w.add_fact(fact(operation, &[&unbound, &read]));
let r2 = rule(check, &[&read], &[pred(operation, &[&ambient, &read])]);
let r2 = rule(check, &[&read], &[pred(operation, &[&read])]);
println!("world:\n{}\n", syms.print_world(&w));
println!("\ntesting r2: {}\n", syms.print_rule(&r2));
let res = w.query_rule(r2);
Expand Down
11 changes: 0 additions & 11 deletions src/format/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,6 @@ pub fn verifier_to_proto_verifier(input: &VerifierPolicies) -> schema::VerifierP
.iter()
.map(v2::token_rule_to_proto_rule)
.collect(),
privileged_rules: input
.privileged_rules
.iter()
.map(v2::token_rule_to_proto_rule)
.collect(),
checks: input
.checks
.iter()
Expand All @@ -120,7 +115,6 @@ pub fn proto_verifier_to_verifier(

let mut facts = vec![];
let mut rules = vec![];
let mut privileged_rules = vec![];
let mut checks = vec![];
let mut policies = vec![];

Expand All @@ -132,10 +126,6 @@ pub fn proto_verifier_to_verifier(
rules.push(v2::proto_rule_to_token_rule(rule)?);
}

for rule in input.privileged_rules.iter() {
privileged_rules.push(v2::proto_rule_to_token_rule(rule)?);
}

for check in input.checks.iter() {
checks.push(v2::proto_check_to_token_check(check)?);
}
Expand All @@ -149,7 +139,6 @@ pub fn proto_verifier_to_verifier(
symbols,
facts,
rules,
privileged_rules,
checks,
policies,
})
Expand Down
1 change: 0 additions & 1 deletion src/format/schema.proto
Original file line number Diff line number Diff line change
Expand Up @@ -203,5 +203,4 @@ message VerifierPolicies {
repeated RuleV2 rules = 4;
repeated CheckV2 checks = 5;
repeated Policy policies = 6;
repeated RuleV2 privileged_rules = 7;
}
2 changes: 0 additions & 2 deletions src/format/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,4 @@ pub struct VerifierPolicies {
pub checks: ::prost::alloc::vec::Vec<CheckV2>,
#[prost(message, repeated, tag="6")]
pub policies: ::prost::alloc::vec::Vec<Policy>,
#[prost(message, repeated, tag="7")]
pub privileged_rules: ::prost::alloc::vec::Vec<RuleV2>,
}
26 changes: 13 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
//!
//! // let's define some access rights
//! // every fact added to the authority block must have the authority fact
//! builder.add_authority_fact("right(#authority, \"/a/file1.txt\", #read)")?;
//! builder.add_authority_fact("right(#authority, \"/a/file1.txt\", #write)")?;
//! builder.add_authority_fact("right(#authority, \"/a/file2.txt\", #read)")?;
//! builder.add_authority_fact("right(#authority, \"/b/file3.txt\", #write)")?;
//! builder.add_authority_fact("right(\"/a/file1.txt\", #read)")?;
//! builder.add_authority_fact("right(\"/a/file1.txt\", #write)")?;
//! builder.add_authority_fact("right(\"/a/file2.txt\", #read)")?;
//! builder.add_authority_fact("right(\"/b/file3.txt\", #write)")?;
//!
//! // we can now create the token
//! let biscuit = builder.build()?;
Expand All @@ -55,8 +55,8 @@
//! biscuit.to_vec()?
//! };
//!
//! // this token is only 277 bytes, holding the authority data and the signature
//! assert_eq!(token1.len(), 277);
//! // this token is only 260 bytes, holding the authority data and the signature
//! assert_eq!(token1.len(), 260);
//!
//! // now let's add some restrictions to this token
//! // we want to limit access to `/a/file1.txt` and to read operations
Expand All @@ -76,9 +76,9 @@
//! // here we require the presence of a "resource" fact with the "ambient" tag
//! // (meaning it is provided by the verifier)
//! &[
//! pred("resource", &[s("ambient"), string("/a/file1.txt")]),
//! pred("resource", &[string("/a/file1.txt")]),
//! // we restrict to read operations
//! pred("operation", &[s("ambient"), s("read")]),
//! pred("operation", &[s("read")]),
//! ],
//! ));
//!
Expand All @@ -93,8 +93,8 @@
//! biscuit.to_vec()?
//! };
//!
//! // this new token fits in 439 bytes
//! assert_eq!(token2.len(), 439);
//! // this new token fits in 414 bytes
//! assert_eq!(token2.len(), 414);
//!
//! /************** VERIFICATION ****************/
//!
Expand All @@ -110,7 +110,7 @@
//! v1.add_resource("/a/file1.txt");
//! v1.add_operation("read");
//! // we will check that the token has the corresponding right
//! v1.add_check("check if right(#authority, \"/a/file1.txt\", #read)");
//! v1.add_check("check if right(\"/a/file1.txt\", #read)");
//!
//! // we choose if we want to allow or deny access
//! // we can define a serie of allow/deny policies in the same
Expand All @@ -123,15 +123,15 @@
//! let mut v2 = biscuit2.verify()?;
//! v2.add_resource("/a/file1.txt");
//! v2.add_operation("write");
//! v2.add_check("check if right(#authority, \"/a/file1.txt\", #write)");
//! v2.add_check("check if right(\"/a/file1.txt\", #write)");
//!
//! // the second verifier requested a read operation
//! assert!(v2.verify().is_err());
//!
//! let mut v3 = biscuit2.verify()?;
//! v3.add_resource("/a/file2.txt");
//! v3.add_operation("read");
//! v3.add_check("check if right(#authority, \"/a/file2.txt\", #read)");
//! v3.add_check("check if right(\"/a/file2.txt\", #read)");
//!
//! // the third verifier requests /a/file2.txt
//! assert!(v3.verify().is_err());
Expand Down
34 changes: 24 additions & 10 deletions src/token/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ impl BlockBuilder {
"check_right",
&[s(right)],
&[
pred("resource", &[s("ambient"), var("resource_name")]),
pred("operation", &[s("ambient"), s(right)]),
pred("right", &[s("authority"), var("resource_name"), s(right)]),
pred("resource", &[var("resource_name")]),
pred("operation", &[s(right)]),
pred("right", &[var("resource_name"), s(right)]),
],
);

Expand All @@ -103,7 +103,7 @@ impl BlockBuilder {
let check = rule(
"resource_check",
&[s("resource_check")],
&[pred("resource", &[s("ambient"), string(resource)])],
&[pred("resource", &[string(resource)])],
);

let _ = self.add_check(check);
Expand All @@ -113,7 +113,7 @@ impl BlockBuilder {
let check = rule(
"operation_check",
&[s("operation_check")],
&[pred("operation", &[s("ambient"), s(operation)])],
&[pred("operation", &[s(operation)])],
);

let _ = self.add_check(check);
Expand All @@ -123,7 +123,7 @@ impl BlockBuilder {
let check = constrained_rule(
"prefix",
&[var("resource")],
&[pred("resource", &[s("ambient"), var("resource")])],
&[pred("resource", &[var("resource")])],
&[Expression {
ops: vec![
Op::Value(var("resource")),
Expand All @@ -140,7 +140,7 @@ impl BlockBuilder {
let check = constrained_rule(
"suffix",
&[var("resource")],
&[pred("resource", &[s("ambient"), var("resource")])],
&[pred("resource", &[var("resource")])],
&[Expression {
ops: vec![
Op::Value(var("resource")),
Expand All @@ -157,7 +157,7 @@ impl BlockBuilder {
let check = constrained_rule(
"expiration",
&[var("date")],
&[pred("time", &[s("ambient"), var("date")])],
&[pred("time", &[var("date")])],
&[Expression {
ops: vec![
Op::Value(var("date")),
Expand Down Expand Up @@ -228,8 +228,7 @@ impl<'a> BiscuitBuilder<'a> {
}

pub fn add_right(&mut self, resource: &str, right: &str) {
let _ =
self.add_authority_fact(fact("right", &[s("authority"), string(resource), s(right)]));
let _ = self.add_authority_fact(fact("right", &[string(resource), s(right)]));
}

pub fn set_context(&mut self, context: String) {
Expand Down Expand Up @@ -921,6 +920,21 @@ macro_rules! tuple_try_from(
);
);

impl<A: TryFrom<Term, Error = error::Token>> TryFrom<Fact> for (A,) {
type Error = error::Token;
fn try_from(fact: Fact) -> Result<Self, Self::Error> {
let mut terms = fact.0.ids;
let mut it = terms.drain(..);

Ok((it
.next()
.ok_or(error::Token::ConversionError(
"not enough terms in fact".to_string(),
))
.and_then(A::try_from)?,))
}
}

macro_rules! tuple_try_from_impl(
($($ty: ident),+) => (
impl<$($ty: TryFrom<Term, Error = error::Token>),+> TryFrom<Fact> for ($($ty),+) {
Expand Down
Loading

0 comments on commit 42b4bec

Please sign in to comment.