Skip to content
Merged
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
37 changes: 19 additions & 18 deletions Packs/Code42/Integrations/Code42/Code42.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,21 +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,
"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",
Expand Down Expand Up @@ -540,8 +525,24 @@ 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 = key.lower().replace("-", "").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):
Expand Down Expand Up @@ -642,7 +643,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")
]
Expand Down
65 changes: 60 additions & 5 deletions Packs/Code42/Integrations/Code42/Code42_test.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
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
from py42.sdk.queries.alerts.filters import Severity
from Code42 import (
Code42Client,
Code42LegalHoldMatterNotFoundError,
Code42InvalidLegalHoldMembershipError,
get_file_category_value,
build_query_payload,
map_observation_to_security_query,
map_to_code42_event_context,
Expand Down Expand Up @@ -476,6 +479,13 @@
"fileCount": 3,
"totalFileSize": 533846,
"isSignificant": true
},
{
"type$": "OBSERVED_FILE_CATEGORY",
"category": "Pdf",
"fileCount": 3,
"totalFileSize": 533846,
"isSignificant": true
}
],
"files": [
Expand Down Expand Up @@ -723,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,
Expand Down Expand Up @@ -1347,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"}]}"""
Expand Down Expand Up @@ -1992,8 +2047,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):
Expand Down
1 change: 1 addition & 0 deletions Packs/Code42/ReleaseNotes/2_0_4.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

#### 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
Expand Down