Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more integration tests to auth_logic. This CL takes care of following items #846

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions src/ir/auth_logic/lowering_ast_datalog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,14 @@ datalog::Predicate PushOntoPredicate(absl::string_view modifier,
datalog::Predicate PushPrincipal(absl::string_view modifier,
const Principal& principal,
const datalog::Predicate& predicate) {
return PushOntoPredicate(modifier, {principal.name()}, predicate);
// do not modify predicate when dealing with binary operators
static const absl::flat_hash_set<std::string> comparison_operators = {
{"<"}, {">"}, {"="}, {"!="}, {"<="}, {">="}};

return (comparison_operators.find(predicate.name()) ==
comparison_operators.end())
? PushOntoPredicate(modifier, {principal.name()}, predicate)
: predicate;
}

datalog::Predicate AttributeToDLIR(const Attribute& attribute) {
Expand Down Expand Up @@ -397,6 +404,13 @@ LoweringToDatalogPass::RelationDeclarationToDLIR(
std::vector<datalog::RelationDeclaration> transformed_declarations =
LoweringToDatalogPass::TransformAttributeDeclarations(
relation_declarations);
// The transformed relation declarations are the same as the ones from the
// surface program plus another one for "canActAs". Declaration being added is
//.decl canActAs(p1 : Principal, p2 : Principal)
transformed_declarations.push_back(datalog::RelationDeclaration(
"canActAs", false,
{datalog::Argument("p1", datalog::ArgumentType::MakePrincipalType()),
datalog::Argument("p2", datalog::ArgumentType::MakePrincipalType())}));
// Produce a mapping from predicate names to predicate typings
// (where a predicate typing is the same as a predicate relation declaration)
common::containers::HashMap<std::string_view, datalog::RelationDeclaration>
Expand All @@ -407,13 +421,7 @@ LoweringToDatalogPass::RelationDeclarationToDLIR(
}
absl::c_move(LoweringToDatalogPass::GetCanSayDeclarations(type_environment),
std::back_inserter(transformed_declarations));
// The transformed relation declarations are the same as the ones from the
// surface program plus another one for "canActAs". Declaration being added is
//.decl canActAs(p1 : Principal, p2 : Principal)
transformed_declarations.push_back(datalog::RelationDeclaration(
"canActAs", false,
{datalog::Argument("p1", datalog::ArgumentType::MakePrincipalType()),
datalog::Argument("p2", datalog::ArgumentType::MakePrincipalType())}));

// The translated declarations are all extended with "says_" and a speaker
// argument
std::vector<datalog::RelationDeclaration>
Expand Down
9 changes: 7 additions & 2 deletions src/ir/auth_logic/souffle_emitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,16 @@ class SouffleEmitter {
absl::flat_hash_set<std::string> type_names;
for (const auto& declaration : program.relation_declarations()) {
for (const auto& argument : declaration.arguments()) {
if (argument.argument_type().kind() ==
datalog::ArgumentType::Kind::kNumber) {
type_names.insert(absl::StrCat(
".type ", argument.argument_type().name(), " <: number"));
continue;
}
if (!skip_declarations && argument.argument_type().kind() !=
datalog::ArgumentType::Kind::kCustom)
continue;

if (!skip_declarations &&
GetRelationsToNotDeclare().find(argument.argument_type().name()) !=
GetRelationsToNotDeclare().end())
Expand All @@ -186,8 +193,6 @@ class SouffleEmitter {
".type ", argument.argument_type().name(), " <: symbol"));
}
}
// TODO (#633) work around till we add number types in C++ version.
type_names.insert(absl::StrCat(".type Number", " <: symbol"));
std::vector<absl::string_view> sorted_type_names(type_names.begin(),
type_names.end());
std::sort(sorted_type_names.begin(), sorted_type_names.end());
Expand Down
4 changes: 0 additions & 4 deletions src/ir/auth_logic/souffle_emitter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ Program BuildRelationDeclarationProgram(SaysAssertion assertion) {
TEST(EmitterTestSuite, EmptyAuthLogicTest) {
std::string expected =
R"(.type DummyType <: symbol
.type Number <: symbol
.decl grounded_dummy(dummy_param : DummyType)
.decl says_canActAs(speaker : Principal, p1 : Principal, p2 : Principal)
grounded_dummy("dummy_var").
Expand All @@ -74,7 +73,6 @@ grounded_dummy("dummy_var").
TEST(EmitterTestSuite, SimpleTest) {
std::string expected =
R"(.type DummyType <: symbol
.type Number <: symbol
.decl grounded_dummy(dummy_param : DummyType)
.decl says_canActAs(speaker : Principal, p1 : Principal, p2 : Principal)
says_foo(TestPrincipal, bar, baz).
Expand All @@ -99,7 +97,6 @@ TEST(EmitterTestSuite, CanSayTest) {
std::string expected =
R"(.type DummyType <: symbol
.type FileName <: symbol
.type Number <: symbol
.decl grounded_dummy(dummy_param : DummyType)
.decl says_canActAs(speaker : Principal, p1 : Principal, p2 : Principal)
.decl says_canSay_grantAccess(speaker : Principal, delegatee1 : Principal, x0 : Principal, x1 : FileName)
Expand Down Expand Up @@ -128,7 +125,6 @@ TEST(EmitterTestSuite, FloatCanSayTest) {
std::string expected =
R"(.type DummyType <: symbol
.type FileName <: symbol
.type Number <: symbol
.decl grounded_dummy(dummy_param : DummyType)
.decl says_canActAs(speaker : Principal, p1 : Principal, p2 : Principal)
.decl says_canSay_canSay_grantAccess(speaker : Principal, delegatee2 : Principal, delegatee1 : Principal, x0 : Principal, x1 : FileName)
Expand Down
76 changes: 76 additions & 0 deletions src/ir/auth_logic/test_inputs/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#-----------------------------------------------------------------------------
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#----------------------------------------------------------------------------
package(
default_visibility = ["//src:__subpackages__"],
features = ["layering_check"],
licenses = ["notice"],
)

[sh_test(
name = "test_%s" % test_name,
srcs = ["test_authlogic.sh"],
args = [
"$(location //src/backends/policy_engine/souffle:raksha_policy_datalog_emitter)",
"$(location :%s.auth)" % test_name,
"$(location :%s.dl)" % test_name,
"1",
"$(location :%s.queries)" % test_name,
],
data = [
":%s.auth" % test_name,
":%s.dl" % test_name,
":%s.queries" % test_name,
"//src/backends/policy_engine/souffle:raksha_policy_datalog_emitter",
"//third_party/mcpp",
"//third_party/souffle:main",
],
env = {
"SOUFFLE_BIN": "$(rootpath //third_party/souffle:main)",
},
) for test_name in [
"canActAs",
"conditions",
"negation",
"multiverse_handling",
"delegation",
"comparisons_with_delegation",
"basic_num_comparisons",
]]

[sh_test(
name = "test_%s" % test_name,
srcs = ["test_authlogic.sh"],
args = [
"$(location //src/backends/policy_engine/souffle:raksha_policy_datalog_emitter)",
"$(location :%s.auth)" % test_name,
"$(location :%s.dl)" % test_name,
],
data = [
":%s.auth" % test_name,
":%s.dl" % test_name,
"//src/backends/policy_engine/souffle:raksha_policy_datalog_emitter",
"//third_party/souffle:main",
],
env = {
"SOUFFLE_BIN": "$(rootpath //third_party/souffle:main)",
},
) for test_name in [
"type_declarations",
"test_decl_skip",
"num_strings_in_names",
"hyphenIDs",
"dot_in_names",
]]
31 changes: 31 additions & 0 deletions src/ir/auth_logic/test_inputs/basic_num_comparisons.auth
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.decl someFact(n : Number)

"test_principal" says someFact(1) :- 3 < 5.
"test_principal" says someFact(2) :- 3 < 0.
"test_principal" says someFact(3) :- 5 > 0.
"test_principal" says someFact(4) :- 3 > 999.
"test_principal" says someFact(5) :- 4 = 4.
"test_principal" says someFact(6) :- 47 = 42.
"test_principal" says someFact(7) :- 47 != 42.
"test_principal" says someFact(8) :- 0 != 0.
"test_principal" says someFact(9) :- 3 <= 5.
"test_principal" says someFact(10) :- 3 <= 3.
"test_principal" says someFact(11) :- 3 <= 0.
"test_principal" says someFact(12) :- 3 >= 2.
"test_principal" says someFact(13) :- 3 >= 3.
"test_principal" says someFact(14) :- 3 >= 5.

q1 = query "test_principal" says someFact(1)?
q2 = query "test_principal" says someFact(2)?
q3 = query "test_principal" says someFact(3)?
q4 = query "test_principal" says someFact(4)?
q5 = query "test_principal" says someFact(5)?
q6 = query "test_principal" says someFact(6)?
q7 = query "test_principal" says someFact(7)?
q8 = query "test_principal" says someFact(8)?
q9 = query "test_principal" says someFact(9)?
q10 = query "test_principal" says someFact(10)?
q11 = query "test_principal" says someFact(11)?
q12 = query "test_principal" says someFact(12)?
q13 = query "test_principal" says someFact(13)?
q14 = query "test_principal" says someFact(14)?
84 changes: 84 additions & 0 deletions src/ir/auth_logic/test_inputs/basic_num_comparisons.dl
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
.type DummyType <: symbol
.type Number <: number
.type Principal <: symbol
.decl grounded_dummy(dummy_param : DummyType)
.decl q1(dummy_param : DummyType)
.decl q10(dummy_param : DummyType)
.decl q11(dummy_param : DummyType)
.decl q12(dummy_param : DummyType)
.decl q13(dummy_param : DummyType)
.decl q14(dummy_param : DummyType)
.decl q2(dummy_param : DummyType)
.decl q3(dummy_param : DummyType)
.decl q4(dummy_param : DummyType)
.decl q5(dummy_param : DummyType)
.decl q6(dummy_param : DummyType)
.decl q7(dummy_param : DummyType)
.decl q8(dummy_param : DummyType)
.decl q9(dummy_param : DummyType)
.decl says_canActAs(speaker : Principal, p1 : Principal, p2 : Principal)
.decl says_isNumber(speaker : Principal, x : Number)
.decl says_isPrincipal(speaker : Principal, x : Principal)
.decl says_someFact(speaker : Principal, n : Number)
says_isNumber("test_principal", 7).
says_isNumber("test_principal", 9).
says_isNumber("test_principal", 6).
says_isNumber("test_principal", 13).
says_isNumber("test_principal", 4).
says_isNumber("test_principal", 12).
says_isNumber("test_principal", 2).
says_isNumber("test_principal", 999).
says_isNumber("test_principal", 8).
says_isNumber("test_principal", 10).
says_isNumber("test_principal", 0).
says_isNumber("test_principal", 5).
says_isNumber("test_principal", 1).
says_isNumber("test_principal", 3).
says_isNumber("test_principal", 47).
says_isNumber("test_principal", 42).
says_isNumber("test_principal", 14).
says_isPrincipal("test_principal", "test_principal").
says_isNumber("test_principal", 11).
says_someFact("test_principal", 1) :- 3<5.
says_someFact("test_principal", 2) :- 3<0.
says_someFact("test_principal", 3) :- 5>0.
says_someFact("test_principal", 4) :- 3>999.
says_someFact("test_principal", 5) :- 4=4.
says_someFact("test_principal", 6) :- 47=42.
says_someFact("test_principal", 7) :- 47!=42.
says_someFact("test_principal", 8) :- 0!=0.
says_someFact("test_principal", 9) :- 3<=5.
says_someFact("test_principal", 10) :- 3<=3.
says_someFact("test_principal", 11) :- 3<=0.
says_someFact("test_principal", 12) :- 3>=2.
says_someFact("test_principal", 13) :- 3>=3.
says_someFact("test_principal", 14) :- 3>=5.
q1("dummy_var") :- says_someFact("test_principal", 1), grounded_dummy("dummy_var").
q2("dummy_var") :- says_someFact("test_principal", 2), grounded_dummy("dummy_var").
q3("dummy_var") :- says_someFact("test_principal", 3), grounded_dummy("dummy_var").
q4("dummy_var") :- says_someFact("test_principal", 4), grounded_dummy("dummy_var").
q5("dummy_var") :- says_someFact("test_principal", 5), grounded_dummy("dummy_var").
q6("dummy_var") :- says_someFact("test_principal", 6), grounded_dummy("dummy_var").
q7("dummy_var") :- says_someFact("test_principal", 7), grounded_dummy("dummy_var").
q8("dummy_var") :- says_someFact("test_principal", 8), grounded_dummy("dummy_var").
q9("dummy_var") :- says_someFact("test_principal", 9), grounded_dummy("dummy_var").
q10("dummy_var") :- says_someFact("test_principal", 10), grounded_dummy("dummy_var").
q11("dummy_var") :- says_someFact("test_principal", 11), grounded_dummy("dummy_var").
q12("dummy_var") :- says_someFact("test_principal", 12), grounded_dummy("dummy_var").
q13("dummy_var") :- says_someFact("test_principal", 13), grounded_dummy("dummy_var").
q14("dummy_var") :- says_someFact("test_principal", 14), grounded_dummy("dummy_var").
grounded_dummy("dummy_var").
.output q1
.output q2
.output q3
.output q4
.output q5
.output q6
.output q7
.output q8
.output q9
.output q10
.output q11
.output q12
.output q13
.output q14
14 changes: 14 additions & 0 deletions src/ir/auth_logic/test_inputs/basic_num_comparisons.queries
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
q1.csv, true
q10.csv, true
q11.csv, false
q12.csv, true
q13.csv, true
q14.csv, false
q2.csv, false
q3.csv, true
q4.csv, false
q5.csv, true
q6.csv, false
q7.csv, true
q8.csv, false
q9.csv, true
54 changes: 54 additions & 0 deletions src/ir/auth_logic/test_inputs/canActAs.auth
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
.decl attribute hasCertification(subject : Symbol)
.decl attribute hasAttribute(attr_name : Symbol)
.decl groundedPrin(p : Principal)

// soupExpert is a Principal that represents a role.
// prin1 specifies a policy for when another Principal can occupy
// this role.
"prin1" says "prin2" canActAs "soupExpert" :-
"prin2" hasCertification("soupsmithing").

// prin1 grants soupExperts the privilege to grant any other object
// the ability to occupy the "soup" role.
"prin1" says "prin2" canSay "chickenSoup" canActAs "soup" :-
"prin2" canActAs "soupExpert",
groundedPrin("chickenSoup"), groundedPrin("prin2").

// Note that, canSay does not act as a delegation on its own. It merely
// passes *properties* from one Principal to the other. So the following
// commented out line would not cause prin1 to delegate to Principals
// that act as soupExperts:
//
// "prin1" says "soupExpert" canSay "chickenSoup" canActAs "soup" :-
// grounded("chickenSoup").

// prin1 delegates to certificate authority to produce the needed
// credentials to act as a soup expert.
"prin1" says "nationalInstituteOfSoupChefs"
canSay "prin2" hasCertification("soupsmithing") :-
groundedPrin("prin2").

// prin1 specifies attributes of soup (that are applied
// to any Principal that occupies the soup role).
"prin1" says "soup" hasAttribute("liquid").
"prin1" says "soup" hasAttribute("aSubstantialMeal").

// prin2, a credentialed soup expert allows chickenSoup to be
// considered soup.
"nationalInstituteOfSoupChefs" says
"prin2" hasCertification("soupsmithing").
"prin2" says "chickenSoup" canActAs "soup".

// prin3 does not have the needed credential in soupsmithing,
// so this spurious claim is ignored by prin1
//"prin3" says "ketchup" canActAs "soup".

// This is boilerplate that we can't avoid:
"prin1" says groundedPrin("chickenSoup").
"prin1" says groundedPrin("ketchup").
"prin1" says groundedPrin("prin2").
"prin1" says groundedPrin("prin3").

q_chicken = query "prin1" says "chickenSoup" hasAttribute("aSubstantialMeal")?
q_ketchup = query "prin1" says "ketchup" hasAttribute("aSubstantialMeal")?

Loading