From cbdfe90527d7420107f65edc23641494c548bf84 Mon Sep 17 00:00:00 2001 From: Juliya Smith Date: Tue, 8 Sep 2020 16:05:13 +0000 Subject: [PATCH 1/7] Handle lowercase pdf --- Packs/Code42/Integrations/Code42/Code42.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Packs/Code42/Integrations/Code42/Code42.py b/Packs/Code42/Integrations/Code42/Code42.py index 3a6d3e61e369..c2636b4a724e 100644 --- a/Packs/Code42/Integrations/Code42/Code42.py +++ b/Packs/Code42/Integrations/Code42/Code42.py @@ -94,6 +94,7 @@ "Executable": FileCategory.EXECUTABLE, "Document": FileCategory.DOCUMENT, "Image": FileCategory.IMAGE, + "Pdf": FileCategory.PDF, "PDF": FileCategory.PDF, "Presentation": FileCategory.PRESENTATION, "Script": FileCategory.SCRIPT, From 319ed71c3b6e14b2deeb909b01d767467a47b364 Mon Sep 17 00:00:00 2001 From: Juliya Smith Date: Tue, 8 Sep 2020 16:14:21 +0000 Subject: [PATCH 2/7] Handle all cases better --- Packs/Code42/Integrations/Code42/Code42.py | 42 ++++++++++--------- .../Code42/Integrations/Code42/Code42_test.py | 8 +++- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/Packs/Code42/Integrations/Code42/Code42.py b/Packs/Code42/Integrations/Code42/Code42.py index c2636b4a724e..6c16c8868078 100644 --- a/Packs/Code42/Integrations/Code42/Code42.py +++ b/Packs/Code42/Integrations/Code42/Code42.py @@ -88,22 +88,6 @@ "osHostName": "Hostname", } -CODE42_FILE_CATEGORY_MAPPER = { - "SourceCode": FileCategory.SOURCE_CODE, - "Audio": FileCategory.AUDIO, - "Executable": FileCategory.EXECUTABLE, - "Document": FileCategory.DOCUMENT, - "Image": FileCategory.IMAGE, - "Pdf": FileCategory.PDF, - "PDF": FileCategory.PDF, - "Presentation": FileCategory.PRESENTATION, - "Script": FileCategory.SCRIPT, - "Spreadsheet": FileCategory.SPREADSHEET, - "Video": FileCategory.VIDEO, - "VirtualDiskImage": FileCategory.VIRTUAL_DISK_IMAGE, - "Archive": FileCategory.ZIP, -} - SECURITY_EVENT_HEADERS = [ "EventType", "FileName", @@ -541,8 +525,28 @@ def _create_exposure_filter(exposure_arg): return ExposureType.is_in(exposure_arg) -def _get_file_category_value(key): - return CODE42_FILE_CATEGORY_MAPPER.get(key, "UNCATEGORIZED") +def get_file_category_value(key): + # Meant to handle all possible cases + # Key conversion examples: + # SourceCode -> sourcecode + # SOURCE_CODE -> sourcecode + # Pdf -> pdf + key = key.lower().replace("-", "") + category_map = { + "sourcecode": FileCategory.SOURCE_CODE, + "audio": FileCategory.AUDIO, + "executable": FileCategory.EXECUTABLE, + "document": FileCategory.DOCUMENT, + "image": FileCategory.IMAGE, + "pdf": FileCategory.PDF, + "presentation": FileCategory.PRESENTATION, + "script": FileCategory.SCRIPT, + "spreadsheet": FileCategory.SPREADSHEET, + "video": FileCategory.VIDEO, + "virtualdiskimage": FileCategory.VIRTUAL_DISK_IMAGE, + "archive": FileCategory.ZIP, + } + return category_map.get(key, "UNCATEGORIZED") class ObservationToSecurityQueryMapper(object): @@ -643,7 +647,7 @@ def _create_file_category_filters(self): observed_file_categories = self._observation_data.get("fileCategories") if observed_file_categories: categories = [ - _get_file_category_value(c.get("category")) + get_file_category_value(c.get("category")) for c in observed_file_categories if c.get("isSignificant") and c.get("category") ] diff --git a/Packs/Code42/Integrations/Code42/Code42_test.py b/Packs/Code42/Integrations/Code42/Code42_test.py index 2b820b5c6aa1..eaa5ea640a5b 100644 --- a/Packs/Code42/Integrations/Code42/Code42_test.py +++ b/Packs/Code42/Integrations/Code42/Code42_test.py @@ -3,6 +3,7 @@ from requests import Response from py42.sdk import SDKClient from py42.response import Py42Response +from py42.sdk.queries.alerts.filters import Severity from Code42 import ( Code42Client, Code42LegalHoldMatterNotFoundError, @@ -1992,8 +1993,8 @@ def test_fetch_incidents_handles_multi_severity(code42_fetch_incidents_mock): integration_context=None, ) call_args = str(code42_fetch_incidents_mock.alerts.search.call_args[0][0]) - assert "HIGH" in call_args - assert "LOW" in call_args + assert Severity.HIGH in call_args + assert Severity.LOW in call_args def test_fetch_when_include_files_includes_files(code42_fetch_incidents_mock): @@ -2091,6 +2092,9 @@ def test_fetch_incidents_fetch_limit(code42_fetch_incidents_mock): assert not remaining_incidents +def test_fetch_incidents_when_given_ + + @pytest.mark.parametrize( "query", [MOCK_SECURITY_DATA_SEARCH_QUERY_EXPOSURE_TYPE_ALL, From 41f84680c4db1a492b5ac1885453c06c5e8f777c Mon Sep 17 00:00:00 2001 From: Juliya Smith Date: Tue, 8 Sep 2020 16:30:23 +0000 Subject: [PATCH 3/7] Handle all the cases --- Packs/Code42/Integrations/Code42/Code42.py | 2 +- .../Code42/Integrations/Code42/Code42_test.py | 77 +++++++++++++++++-- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/Packs/Code42/Integrations/Code42/Code42.py b/Packs/Code42/Integrations/Code42/Code42.py index 6c16c8868078..9c28d04531f0 100644 --- a/Packs/Code42/Integrations/Code42/Code42.py +++ b/Packs/Code42/Integrations/Code42/Code42.py @@ -531,7 +531,7 @@ def get_file_category_value(key): # SourceCode -> sourcecode # SOURCE_CODE -> sourcecode # Pdf -> pdf - key = key.lower().replace("-", "") + key = key.lower().replace("-", "").replace("_", "") category_map = { "sourcecode": FileCategory.SOURCE_CODE, "audio": FileCategory.AUDIO, diff --git a/Packs/Code42/Integrations/Code42/Code42_test.py b/Packs/Code42/Integrations/Code42/Code42_test.py index eaa5ea640a5b..52310f698bd4 100644 --- a/Packs/Code42/Integrations/Code42/Code42_test.py +++ b/Packs/Code42/Integrations/Code42/Code42_test.py @@ -1,5 +1,6 @@ import json import pytest +from py42.sdk.queries.fileevents.filters import FileCategory from requests import Response from py42.sdk import SDKClient from py42.response import Py42Response @@ -8,6 +9,7 @@ Code42Client, Code42LegalHoldMatterNotFoundError, Code42InvalidLegalHoldMembershipError, + get_file_category_value, build_query_payload, map_observation_to_security_query, map_to_code42_event_context, @@ -477,6 +479,13 @@ "fileCount": 3, "totalFileSize": 533846, "isSignificant": true + }, + { + "type$": "OBSERVED_FILE_CATEGORY", + "category": "Pdf", + "fileCount": 3, + "totalFileSize": 533846, + "isSignificant": true } ], "files": [ @@ -724,9 +733,12 @@ "filters": [{"operator": "IS", "term": "exposure", "value": "ApplicationRead"}], }, { - "filterClause": "AND", - "filters": [{"operator": "IS", "term": "fileCategory", "value": "SOURCE_CODE"}], - }, + "filterClause": "OR", + "filters": [ + {"operator": "IS", "term": "fileCategory", "value": "PDF"}, + {"operator": "IS", "term": "fileCategory", "value": "SOURCE_CODE"} + ] + } ], "pgNum": 1, "pgSize": 10000, @@ -1348,6 +1360,48 @@ def assert_detection_list_outputs_match_response_items(outputs_list, response_it """TESTS""" +def test_get_file_category_value_handles_screaming_snake_case(): + actual = get_file_category_value("SOURCE_CODE") + expected = FileCategory.SOURCE_CODE + assert actual == expected + + +def test_get_file_category_value_handles_capitalized_case(): + actual = get_file_category_value("Pdf") + expected = FileCategory.PDF + assert actual == expected + + +def test_get_file_category_value_handles_lower_case(): + actual = get_file_category_value("pdf") + expected = FileCategory.PDF + assert actual == expected + + +def test_get_file_category_value_handles_upper_case(): + actual = get_file_category_value("PDF") + expected = FileCategory.PDF + assert actual == expected + + +def test_get_file_category_value_handles_pascal_case(): + actual = get_file_category_value("SourceCode") + expected = FileCategory.SOURCE_CODE + assert actual == expected + + +def test_get_file_category_value_handles_hungarian_case(): + actual = get_file_category_value("sourceCode") + expected = FileCategory.SOURCE_CODE + assert actual == expected + + +def test_get_file_category_value_handles_hyphenated_case(): + actual = get_file_category_value("source-code") + expected = FileCategory.SOURCE_CODE + assert actual == expected + + def test_client_lazily_inits_sdk(mocker, code42_sdk_mock): sdk_factory_mock = mocker.patch("py42.sdk.from_local_account") response_json_mock = """{"total": 1, "users": [{"username": "Test"}]}""" @@ -2091,8 +2145,21 @@ def test_fetch_incidents_fetch_limit(code42_fetch_incidents_mock): assert next_run["last_fetch"] assert not remaining_incidents - -def test_fetch_incidents_when_given_ +# TODO +# def test_fetch_incidents_when_given_pdf_works_as_expected(code42_fetch_incidents_mock): +# client = create_client(code42_fetch_incidents_mock) +# asdf +# next_run, incidents, remaining_incidents = fetch_incidents( +# client=client, +# last_run={"last_fetch": None}, +# first_fetch_time=MOCK_FETCH_TIME, +# event_severity_filter=None, +# fetch_limit=10, +# include_files=True, +# integration_context=None, +# ) +# assert len(incidents) == 3 +# assert next_run["last_fetch"] @pytest.mark.parametrize( From 51538d2d907a657f8ddb1cb2386655ba14b353b2 Mon Sep 17 00:00:00 2001 From: Juliya Smith Date: Tue, 8 Sep 2020 16:32:50 +0000 Subject: [PATCH 4/7] Remove commented out code --- Packs/Code42/Integrations/Code42/Code42_test.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/Packs/Code42/Integrations/Code42/Code42_test.py b/Packs/Code42/Integrations/Code42/Code42_test.py index 52310f698bd4..e6fa3333addc 100644 --- a/Packs/Code42/Integrations/Code42/Code42_test.py +++ b/Packs/Code42/Integrations/Code42/Code42_test.py @@ -2145,22 +2145,6 @@ def test_fetch_incidents_fetch_limit(code42_fetch_incidents_mock): assert next_run["last_fetch"] assert not remaining_incidents -# TODO -# def test_fetch_incidents_when_given_pdf_works_as_expected(code42_fetch_incidents_mock): -# client = create_client(code42_fetch_incidents_mock) -# asdf -# next_run, incidents, remaining_incidents = fetch_incidents( -# client=client, -# last_run={"last_fetch": None}, -# first_fetch_time=MOCK_FETCH_TIME, -# event_severity_filter=None, -# fetch_limit=10, -# include_files=True, -# integration_context=None, -# ) -# assert len(incidents) == 3 -# assert next_run["last_fetch"] - @pytest.mark.parametrize( "query", From d59b5f06221b175260718dc98974dbc537e92e64 Mon Sep 17 00:00:00 2001 From: Juliya Smith Date: Tue, 8 Sep 2020 16:33:00 +0000 Subject: [PATCH 5/7] Lessen coment --- Packs/Code42/Integrations/Code42/Code42.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Packs/Code42/Integrations/Code42/Code42.py b/Packs/Code42/Integrations/Code42/Code42.py index 9c28d04531f0..f069d0675ac5 100644 --- a/Packs/Code42/Integrations/Code42/Code42.py +++ b/Packs/Code42/Integrations/Code42/Code42.py @@ -527,10 +527,6 @@ def _create_exposure_filter(exposure_arg): def get_file_category_value(key): # Meant to handle all possible cases - # Key conversion examples: - # SourceCode -> sourcecode - # SOURCE_CODE -> sourcecode - # Pdf -> pdf key = key.lower().replace("-", "").replace("_", "") category_map = { "sourcecode": FileCategory.SOURCE_CODE, From be1b8f80ee3345dedcaaeafd3c16244aca596523 Mon Sep 17 00:00:00 2001 From: Juliya Smith Date: Tue, 8 Sep 2020 16:39:09 +0000 Subject: [PATCH 6/7] Update release notes --- Packs/Code42/ReleaseNotes/2_0_4.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Packs/Code42/ReleaseNotes/2_0_4.md b/Packs/Code42/ReleaseNotes/2_0_4.md index ff0726b13117..409e59d80c14 100644 --- a/Packs/Code42/ReleaseNotes/2_0_4.md +++ b/Packs/Code42/ReleaseNotes/2_0_4.md @@ -1,8 +1,10 @@ #### Integrations ##### Code42 +- Fix bug where capitalized Alert file-observation file categories would not map to file event query values. - Upgrade py42 dependency and internal code improvements. + #### Playbooks ##### Code42 File Download - Add missing Else case to the Code42 Download File playbook. From dc824fef70c5fc8bb9bbd936cae70043c01019d3 Mon Sep 17 00:00:00 2001 From: Juliya Smith Date: Tue, 8 Sep 2020 16:40:45 +0000 Subject: [PATCH 7/7] Rm extra space in release notes --- Packs/Code42/ReleaseNotes/2_0_4.md | 1 - 1 file changed, 1 deletion(-) diff --git a/Packs/Code42/ReleaseNotes/2_0_4.md b/Packs/Code42/ReleaseNotes/2_0_4.md index 409e59d80c14..162127ac56d9 100644 --- a/Packs/Code42/ReleaseNotes/2_0_4.md +++ b/Packs/Code42/ReleaseNotes/2_0_4.md @@ -4,7 +4,6 @@ - Fix bug where capitalized Alert file-observation file categories would not map to file event query values. - Upgrade py42 dependency and internal code improvements. - #### Playbooks ##### Code42 File Download - Add missing Else case to the Code42 Download File playbook.