From ef41326511d4e6eabaea4b7c0c27d5f03109b8c1 Mon Sep 17 00:00:00 2001 From: Atte Niemi <4998544+hur@users.noreply.github.com> Date: Fri, 25 Oct 2024 12:35:36 +0100 Subject: [PATCH 1/2] Fixes rule creation bug in IoaRuleGroup._update_create_delete --- caracara/modules/custom_ioa/custom_ioa.py | 2 +- tests/unit_tests/test_custom_ioas.py | 138 ++++++++++++++++++++++ 2 files changed, 139 insertions(+), 1 deletion(-) diff --git a/caracara/modules/custom_ioa/custom_ioa.py b/caracara/modules/custom_ioa/custom_ioa.py index 42860c2..d8cc8ae 100644 --- a/caracara/modules/custom_ioa/custom_ioa.py +++ b/caracara/modules/custom_ioa/custom_ioa.py @@ -211,7 +211,7 @@ def _update_create_delete_rules(self, group: IoaRuleGroup, comment: str) -> IoaR new_group.rules = list( chain( (rule for rule in group.rules if rule.exists_in_cloud()), - (new_rule for rule in new_rules), + (new_rule for new_rule in new_rules), ) ) diff --git a/tests/unit_tests/test_custom_ioas.py b/tests/unit_tests/test_custom_ioas.py index b94361a..1eece2b 100644 --- a/tests/unit_tests/test_custom_ioas.py +++ b/tests/unit_tests/test_custom_ioas.py @@ -708,3 +708,141 @@ def mock_delete_rule(rule_group_id, ids, comment): ) # Assert new group is as expected assert new_group.version == group.version + 4 + + +def test_update_rule_group_with_new_rules(client: Client, custom_ioa_api: falconpy.CustomIOA, simple_rule_type: RuleType): + """""" + raw_group = { # Acts as a store for the API + "customer_id": "test_customer", + "id": "test_group_01", + "name": "test rule group", + "description": "test rule group desc", + "platform": "windows", + "enabled": False, + "deleted": False, + "rule_ids": ["test_rule_01", "test_rule_02"], + "rules": [ + { + "customer_id": "test_customer", + "instance_id": "test_rule_01", + "name": "test rule 1", + "description": "test rule 1 desc", + "pattern_id": "41000", + "pattern_severity": "critical", + "disposition_id": list(simple_rule_type.disposition_map.keys())[0], + "action_label": list(simple_rule_type.disposition_map.values())[0], + "ruletype_id": simple_rule_type.id_, + "ruletype_name": simple_rule_type.name, + "field_values": [], + "enabled": True, + "deleted": False, + "instance_version": 1, + "version_ids": [1], + "magic_cookie": 1, + "committed_on": "2022-01-01T12:00:00.000000000Z", + "created_on": "2022-01-01T12:00:00.000000000Z", + "created_by": "caracara@test.com", + "modified_on": "2022-01-01T12:00:00.000000000Z", + "modified_by": "caracara@test.com", + "comment": "test rule 1 comment", + }, + { + "customer_id": "test_customer", + "instance_id": "test_rule_02", + "name": "test rule 2", + "description": "test rule 2 desc", + "pattern_id": "41000", + "pattern_severity": "critical", + "disposition_id": list(simple_rule_type.disposition_map.keys())[0], + "action_label": list(simple_rule_type.disposition_map.values())[0], + "ruletype_id": simple_rule_type.id_, + "ruletype_name": simple_rule_type.name, + "field_values": [], + "enabled": True, + "deleted": False, + "instance_version": 1, + "version_ids": [1], + "magic_cookie": 1, + "committed_on": "2022-01-01T12:00:00.000000000Z", + "created_on": "2022-01-01T12:00:00.000000000Z", + "created_by": "caracara@test.com", + "modified_on": "2022-01-01T12:00:00.000000000Z", + "modified_by": "caracara@test.com", + "comment": "test rule 2 comment", + }, + ], + "version": 1, + "committed_on": "2022-01-01T12:00:00.000000000Z", + "created_on": "2022-01-01T12:00:00.000000000Z", + "created_by": "caracara@test.com", + "modified_on": "2022-01-01T12:00:00.000000000Z", + "modified_by": "caracara@test.com", + "comment": "test rule group comment", + } + group = IoaRuleGroup.from_data_dict( # Acts as an already queried group + raw_group, rule_type_map={simple_rule_type.id_: simple_rule_type} + ) + + rule = CustomIoaRule( + name="test rule 3", + description="test rule 3 desc", + severity="critical", + rule_type=simple_rule_type, + ) + rule.set_action("Test Action") + group.add_rule(rule) + + def mock_create_rule(body): + assert raw_group["id"] == body["rulegroup_id"] + raw_group["version"] += 1 + new_rule = { + "customer_id": "test_customer", + "instance_id": "test_rule_03", + "name": body["name"], + "description": body["description"], + "pattern_id": "41000", + "pattern_severity": body["pattern_severity"], + "disposition_id": body["disposition_id"], + "action_label": list(simple_rule_type.disposition_map.values())[0], + "ruletype_id": body["ruletype_id"], + "ruletype_name": simple_rule_type.name, + "field_values": body["field_values"], + "enabled": False, + "deleted": False, + "instance_version": 1, + "version_ids": [1], + "magic_cookie": 1, + "committed_on": "2022-01-01T12:00:00.000000000Z", + "created_on": "2022-01-01T12:00:00.000000000Z", + "created_by": "caracara@test.com", + "modified_on": "2022-01-01T12:00:00.000000000Z", + "modified_by": "caracara@test.com", + "comment": body["comment"], + } + + raw_group["rules"].append(new_rule) + return {"body": {"resources": [new_rule]}} + custom_ioa_api.create_rule.side_effect = mock_create_rule + + custom_ioa_api.query_rule_types.side_effect = create_mock_query_resources( + resources=[simple_rule_type.id_] + ) + custom_ioa_api.get_rule_types.side_effect = create_mock_get_rule_types( + rule_types=[simple_rule_type] + ) + + new_group = client.custom_ioas.update_rule_group(group, comment="test update comment") + + custom_ioa_api.create_rule.assert_called_once_with( + body={ + "name": "test rule 3", + "description": "test rule 3 desc", + "pattern_severity": "critical", + "disposition_id": list(simple_rule_type.disposition_map.keys())[0], + "field_values": [], + "ruletype_id": simple_rule_type.id_, + "rulegroup_id": "test_group_01", + "comment": "test update comment", + } + ) + assert len([rule for rule in new_group.rules if rule.exists_in_cloud()]) == len(group.rules) \ No newline at end of file From f3a80abee144dcad5b8669d0bebdf957de6ec69b Mon Sep 17 00:00:00 2001 From: Atte Niemi <4998544+hur@users.noreply.github.com> Date: Fri, 25 Oct 2024 12:43:26 +0100 Subject: [PATCH 2/2] Linting --- tests/unit_tests/test_custom_ioas.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/unit_tests/test_custom_ioas.py b/tests/unit_tests/test_custom_ioas.py index 1eece2b..33a936b 100644 --- a/tests/unit_tests/test_custom_ioas.py +++ b/tests/unit_tests/test_custom_ioas.py @@ -710,8 +710,10 @@ def mock_delete_rule(rule_group_id, ids, comment): assert new_group.version == group.version + 4 -def test_update_rule_group_with_new_rules(client: Client, custom_ioa_api: falconpy.CustomIOA, simple_rule_type: RuleType): - """""" +def test_update_rule_group_with_new_rules( + client: Client, custom_ioa_api: falconpy.CustomIOA, simple_rule_type: RuleType +): + """Tests `CustomIoaApiModule.update_rule_groups` when the group a rule to create.""" raw_group = { # Acts as a store for the API "customer_id": "test_customer", "id": "test_group_01", @@ -822,6 +824,7 @@ def mock_create_rule(body): raw_group["rules"].append(new_rule) return {"body": {"resources": [new_rule]}} + custom_ioa_api.create_rule.side_effect = mock_create_rule custom_ioa_api.query_rule_types.side_effect = create_mock_query_resources( @@ -832,7 +835,7 @@ def mock_create_rule(body): ) new_group = client.custom_ioas.update_rule_group(group, comment="test update comment") - + custom_ioa_api.create_rule.assert_called_once_with( body={ "name": "test rule 3", @@ -845,4 +848,4 @@ def mock_create_rule(body): "comment": "test update comment", } ) - assert len([rule for rule in new_group.rules if rule.exists_in_cloud()]) == len(group.rules) \ No newline at end of file + assert len([rule for rule in new_group.rules if rule.exists_in_cloud()]) == len(group.rules)