Skip to content

Commit

Permalink
BST-5922: Fix imported default ignored (#29)
Browse files Browse the repository at this point in the history
Like regular rules, default rule can be imported and the latest imported
one should take precedence over the others. In the previous version, any
import default would just get ignored.
  • Loading branch information
ledo01 authored Jun 8, 2023
1 parent d75556f commit 9dcb675
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 1 deletion.
3 changes: 2 additions & 1 deletion boostsec/registry_validator/upload_rules_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,9 @@ def _get_rules_and_default(
default_rule = None
if imports := rules_db_yaml.get("import"):
for ns in imports:
import_rules, _ = _get_rules_and_default(ns, config)
import_rules, imported_default = _get_rules_and_default(ns, config)
rules.update(import_rules)
default_rule = imported_default or default_rule

if module_rules := rules_db_yaml.get("rules"):
rules.update(module_rules)
Expand Down
164 changes: 164 additions & 0 deletions tests/unit/scanner/test_upload_rules_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
VALID_RULES_DB_STRING,
VALID_RULES_DB_STRING_WITH_DEFAULT,
VALID_RULES_DB_STRING_WITH_IMPORTS,
VALID_RULES_DB_STRING_WITH_ONLY_IMPORT,
VALID_RULES_DB_STRING_WITH_PLACEHOLDER,
)

Expand Down Expand Up @@ -394,6 +395,169 @@ def has_auth_token(request: Any) -> bool:
}


def test_upload_rules_db_with_imported_default(
registry_config: RegistryConfig, requests_mock: Mocker
) -> None:
"""Should include any imported default rule."""
url = "https://my_endpoint/"
test_token = "my-random-key" # noqa: S105

def has_auth_token(request: Any) -> bool:
assert request.headers["Authorization"] == f"ApiKey {test_token}"
return True

requests_mock.post(
urljoin(url, "/rules-management/graphql"),
additional_matcher=has_auth_token,
json={
"data": {"setRules": {"__typename": "RuleSuccessSchema"}},
},
)

_create_rules_realm(
registry_config.rules_realm_path,
VALID_RULES_DB_STRING_WITH_DEFAULT,
"namespace/module-a",
)

namespace = "namespace-example"
module_path = _create_module_and_rules(
registry_config.scanners_path, VALID_RULES_DB_STRING_WITH_ONLY_IMPORT, namespace
)

upload_rules_db(
module_path.parent,
url,
test_token,
registry_config,
)

assert requests_mock.call_count == 1
assert requests_mock.last_request is not None
req_json = requests_mock.last_request.json()
assert req_json == {
"query": "mutation setRules($rules: RuleInputSchemas!) {\n setRules(namespacedRules: $rules) {\n __typename\n ... on RuleSuccessSchema {\n successMessage\n }\n ... on RuleErrorSchema {\n errorMessage\n }\n }\n}", # noqa: E501
"variables": {
"rules": {
"namespace": "namespace-example",
"defaultRule": "my-rule-2",
"ruleInputs": [
{
"categories": ["ALL", "category-1"],
"description": "Lorem Ipsum",
"driver": "Example Scanner",
"group": "Test group 1",
"name": "my-rule-1",
"prettyName": "My rule 1",
"ref": "http://my.link.com",
},
{
"categories": ["ALL", "category-2"],
"description": "Lorem Ipsum",
"driver": "Example Scanner",
"group": "Test group 2",
"name": "my-rule-2",
"prettyName": "My rule 2",
"ref": "http://my.link.com",
},
],
}
},
}


def test_upload_rules_db_imported_default_precedence(
registry_config: RegistryConfig, requests_mock: Mocker
) -> None:
"""Module default should take precedence over any imported one."""
url = "https://my_endpoint/"
test_token = "my-random-key" # noqa: S105

def has_auth_token(request: Any) -> bool:
assert request.headers["Authorization"] == f"ApiKey {test_token}"
return True

requests_mock.post(
urljoin(url, "/rules-management/graphql"),
additional_matcher=has_auth_token,
json={
"data": {"setRules": {"__typename": "RuleSuccessSchema"}},
},
)

_create_rules_realm(
registry_config.rules_realm_path,
VALID_RULES_DB_STRING_WITH_DEFAULT,
"namespace/module-a",
)

namespace = "namespace-example"
rules = VALID_RULES_DB_STRING_WITH_ONLY_IMPORT
rules += """
default:
my-default:
categories:
- ALL
description: Lorem Ipsum
group: Test default
name: my-default
pretty_name: My Default
ref: "http://my.link.com"
"""
module_path = _create_module_and_rules(
registry_config.scanners_path, rules, namespace
)

upload_rules_db(
module_path.parent,
url,
test_token,
registry_config,
)

assert requests_mock.call_count == 1
assert requests_mock.last_request is not None
req_json = requests_mock.last_request.json()
assert req_json == {
"query": "mutation setRules($rules: RuleInputSchemas!) {\n setRules(namespacedRules: $rules) {\n __typename\n ... on RuleSuccessSchema {\n successMessage\n }\n ... on RuleErrorSchema {\n errorMessage\n }\n }\n}", # noqa: E501
"variables": {
"rules": {
"namespace": "namespace-example",
"defaultRule": "my-default",
"ruleInputs": [
{
"categories": ["ALL", "category-1"],
"description": "Lorem Ipsum",
"driver": "Example Scanner",
"group": "Test group 1",
"name": "my-rule-1",
"prettyName": "My rule 1",
"ref": "http://my.link.com",
},
{
"categories": ["ALL", "category-2"],
"description": "Lorem Ipsum",
"driver": "Example Scanner",
"group": "Test group 2",
"name": "my-rule-2",
"prettyName": "My rule 2",
"ref": "http://my.link.com",
},
{
"categories": ["ALL"],
"description": "Lorem Ipsum",
"driver": "Example Scanner",
"group": "Test default",
"name": "my-default",
"prettyName": "My Default",
"ref": "http://my.link.com",
},
],
}
},
}


def test_upload_rules_db_permission_denied(
capfd: pytest.CaptureFixture[str],
registry_config: RegistryConfig,
Expand Down

0 comments on commit 9dcb675

Please sign in to comment.