From 85c8e555c0ed177acc1de529a499a7f2d3b03b43 Mon Sep 17 00:00:00 2001 From: Vincent Gramer Date: Mon, 4 Jan 2021 14:03:05 +0100 Subject: [PATCH] Fix grammar: allow import between rules and complex expression in else statement (#80) * fix grammar: allow import between rules and allow "complex" expression in else statement also merge 'else keyword' and 'else keyword 2' tests into 'else keyword' Signed-off-by: Vincent Gramer --- src/main/grammar/Rego.bnf | 5 +-- .../ideaplugin/lang/RegoParsingTestCase.kt | 4 +- .../lang/parser/fixtures/else_keyword.rego | 43 ++++++++++++++++++- .../lang/parser/fixtures/else_keyword_2.rego | 8 ---- .../lang/parser/fixtures/imports.rego | 1 + .../fixtures/imports_between_rules.rego | 18 ++++++++ 6 files changed, 66 insertions(+), 13 deletions(-) delete mode 100644 src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/else_keyword_2.rego create mode 100644 src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/imports_between_rules.rego diff --git a/src/main/grammar/Rego.bnf b/src/main/grammar/Rego.bnf index eadacbc..091586f 100644 --- a/src/main/grammar/Rego.bnf +++ b/src/main/grammar/Rego.bnf @@ -63,14 +63,13 @@ COMMENT = 'regexp:[ \t]*#[^\r\n]*' ] } -module ::= package import* policy +module ::= package (import| rule)* package ::= "package" ref import ::= "import" ref ( "as" var )? -policy ::= rule* rule ::= "default"? rule-head rule-body* rule-head ::= var ( "(" rule-args? ")" )? ("[" term "]" )? ( ( ":=" | "=" ) expr2 )? rule-args ::= term ( "," term )* -rule-body ::= ( else ( "=" term )? )? "{" query "}" +rule-body ::= ( else ( "=" expr2 )? )? "{" query "}" query ::=( literal |';' )+ literal ::= ( some-decl | expr | "not" expr ) with-modifier* with-modifier ::= "with" term "as" term diff --git a/src/test/kotlin/org/openpolicyagent/ideaplugin/lang/RegoParsingTestCase.kt b/src/test/kotlin/org/openpolicyagent/ideaplugin/lang/RegoParsingTestCase.kt index 935b037..da5c583 100644 --- a/src/test/kotlin/org/openpolicyagent/ideaplugin/lang/RegoParsingTestCase.kt +++ b/src/test/kotlin/org/openpolicyagent/ideaplugin/lang/RegoParsingTestCase.kt @@ -40,8 +40,10 @@ class RegoParsingTestCase: RegoParsingTestCaseBase() { fun `test composite keys`() = doTestNoError() fun `test composite values`() = doTestNoError() - fun `test else keyword 2`() = doTestNoError() + fun `test imports`() = doTestNoError() + fun `test imports between rules`() = doTestNoError() + fun `test negations`() = doTestNoError() fun `test package with simple rule`() = doTestNoError() fun `test references`() = doTestNoError() diff --git a/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/else_keyword.rego b/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/else_keyword.rego index 563544b..9cc47b0 100644 --- a/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/else_keyword.rego +++ b/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/else_keyword.rego @@ -1,4 +1,45 @@ package main +a := [] # In order to handle manifest with one or many resources, we turns the input into an array, if it's not an array already. -as_array(x) = [x] {not is_array(x)} else = x {true} \ No newline at end of file +as_array(x) = [x] {not is_array(x)} else = x {true} + + +authorize = "allow" { + input.user == "superuser" # allow 'superuser' to perform any operation. +} else = "deny" { + input.path[0] == "admin" # disallow 'admin' operations... + input.source_network == "external" # from external networks. +} + + +check_function_call_for_else(x) = x { + x % 2 == 0 +}else = abs(x) { + true +} + +check_infix_op_for_else(x) = x { + x % 2 == 0 +} else = x *2 - 1 { + true +} + + +check_array_comprehension_for_else(x) = x { + x % 2 == 0 +} else = [y | some y; a[y] == x] { + true +} + +check_set_comprehension_for_else(x) = x { + x % 2 == 0 +} else = {y | some y; a[y]} { + true +} + +check_object_comprehension_for_else(x) = x { + x % 2 == 0 +} else = {y : "true" | some y; a[y] } { + true +} \ No newline at end of file diff --git a/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/else_keyword_2.rego b/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/else_keyword_2.rego deleted file mode 100644 index e9a4176..0000000 --- a/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/else_keyword_2.rego +++ /dev/null @@ -1,8 +0,0 @@ -package test - -authorize = "allow" { - input.user == "superuser" # allow 'superuser' to perform any operation. -} else = "deny" { - input.path[0] == "admin" # disallow 'admin' operations... - input.source_network == "external" # from external networks. -} # ... more rules diff --git a/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/imports.rego b/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/imports.rego index db86bb1..841f9e9 100644 --- a/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/imports.rego +++ b/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/imports.rego @@ -1,6 +1,7 @@ package test import data.policy +import data.security.policy as p default allow = false allow { diff --git a/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/imports_between_rules.rego b/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/imports_between_rules.rego new file mode 100644 index 0000000..cd3b050 --- /dev/null +++ b/src/test/resources/org/openpolicyagent/ideaplugin/lang/parser/fixtures/imports_between_rules.rego @@ -0,0 +1,18 @@ +package test + +import data.policy +import data.security.policy as p + +default allow = false +allow { + true +} + +import data.domain +import data.otherdomain as od + +rule_1 { + 1 == 1 +} + +import data.something \ No newline at end of file