XDRSyncScript Deprecated
Deprecated. No available replacement. Syncs a single incident between Demisto and XDR. This script always uses the xdr-get-incident-extra-data command and outputs to the context the entire incident JSON. When the incident is updated in XDR, the Demisto incident will be updated accordingly and the default playbook will rerun. When an incident is updated in Demisto, the script will execute the xdr-update-incident command and update the incident in XDR.
python · Cortex XDR by Palo Alto Networks
Details
| ID | XDRSyncScript |
|---|---|
| Language | python |
| From Version | 6.0.0 |
| Docker Image | demisto/python3:3.9.7.24076 |
| Tags | xdr |
from CommonServerPython import * import copy import json import XDRSyncScript as xdr_script from XDRSyncScript import ASSIGNED_USER_MAIL_XDR_FIELD, MODIFICATION_TIME_XDR_FIELD, MANUAL_SEVERITY_XDR_FIELD, \ SEVERITY_XDR_FIELD INCIDENT_IN_DEMISTO = { "sourceInstance": "Palo Alto Networks Cortext XDR IR_instance_1", "occurred": "2019-05-30T14:32:22.398+03:00", "closeReason": "", "modified": "2019-06-02T11:15:09.323251+03:00", "CustomFields": { "xdrincidentid": "697567", "xdrurl": "http://example.com/incident-view/697567", "xdrdescription": "WildFire Malware detected on host HostNameFFM8VIP9", "xdralertcount": 1, "xdrstatus": "new", "xdrassignedusermail": "", "xdrassigneduserprettyname": "", "xdrmodificationtime": "2019-06-02T11:15:09.323251+03:00", "xdralerts": [ { "category": "WildFirePostDetection", "action_pretty": "Detected (Reported)", "description": "Suspicious executable detected", "severity": "high", "host_ip": "8.8.8.8", "source": "Traps", "alert_id": "50820", "host_name": "HostNameFFM8VIP9", "detection_timestamp": 1559215835437, "action": "REPORTED", "user_name": "N/A", "name": "WildFire Malware" } ], "xdrfileartifacts": [ { "file_signature_status": "SIGNATURE_UNAVAILABLE", "is_process": None, "file_name": "LCTGSK7IML.docx", "file_wildfire_verdict": "UNKNOWN", "alert_count": 1, "is_malicious": None, "is_manual": None, "file_signature_vendor_name": None, "type": "HASH", "file_sha256": "384654fa409c7a500a4a843d33a005c9d670d4845d3a9e096efc8b00ad05a621" } ], "xdrnetworkartifacts": [] }, "severity": 1, "name": "#697567 - WildFire Malware detected on host HostNameFFM8VIP9", "created": "2019-06-02T11:13:54.674006+03:00", "sourceBrand": "Palo Alto Networks Cortext XDR IR", } OLD_INCIDENT_IN_DEMISTO = { "sourceInstance": "Palo Alto Networks Cortext XDR IR_instance_1", "occurred": "2019-05-30T14:32:22.398+03:00", "closeReason": "", "modified": "2019-06-02T11:15:09.323251+03:00", "CustomFields": { "xdrincidentid": "697567", "xdrurl": "http://example.com/incident-view/697567", "xdrdescription": "WildFire Malware detected on host HostNameFFM8VIP9", "xdralertcount": 1, "xdrstatus": "new", "xdrassignedusermail": "", "xdrassigneduserprettyname": "", "xdralerts": [ { "category": "WildFirePostDetection", "action_pretty": "Detected (Reported)", "description": "Suspicious executable detected", "severity": "high", "host_ip": "8.8.8.8", "source": "Traps", "alert_id": "50820", "host_name": "HostNameFFM8VIP9", "detection_timestamp": 1559215835437, "action": "REPORTED", "user_name": "N/A", "name": "WildFire Malware" } ], "xdrfileartifacts": [ { "file_signature_status": "SIGNATURE_UNAVAILABLE", "is_process": None, "file_name": "LCTGSK7IML.docx", "file_wildfire_verdict": "UNKNOWN", "alert_count": 1, "is_malicious": None, "is_manual": None, "file_signature_vendor_name": None, "type": "HASH", "file_sha256": "384654fa409c7a500a4a843d33a005c9d670d4845d3a9e096efc8b00ad05a621" } ], "xdrnetworkartifacts": [] }, "labels": [ { "type": "modification_time", "value": 1559463309323, } ], "severity": 1, "name": "#697567 - WildFire Malware detected on host HostNameFFM8VIP9", "created": "2019-06-02T11:13:54.674006+03:00", "sourceBrand": "Palo Alto Networks Cortext XDR IR", } INCIDENT_FROM_XDR = { "host_count": 1, "manual_severity": None, "xdr_url": "http://example.com/incident-view/697567", "assigned_user_pretty_name": None, "alert_count": 1, "med_severity_alert_count": 0, "detection_time": None, "user_count": 1, "severity": "low", "alerts": [ { "category": "WildFirePostDetection", "action_pretty": "Detected (Reported)", "description": "Suspicious executable detected", "severity": "high", "host_ip": "8.8.8.8", "source": "Traps", "alert_id": "50820", "host_name": "HostNameFFM8VIP9", "detection_timestamp": 1559215835437, "action": "REPORTED", "user_name": "N/A", "name": "WildFire Malware" } ], "low_severity_alert_count": 0, "status": "new", "description": "WildFire Malware detected on host HostNameFFM8VIP9", "resolve_comment": None, "creation_time": 1559215942398, "modification_time": 1559215942398, "network_artifacts": [], "file_artifacts": [ { "file_signature_status": "SIGNATURE_UNAVAILABLE", "is_process": None, "file_name": "LCTGSK7IML.docx", "file_wildfire_verdict": "UNKNOWN", "alert_count": 1, "is_malicious": None, "is_manual": None, "file_signature_vendor_name": None, "type": "HASH", "file_sha256": "384654fa409c7a500a4a843d33a005c9d670d4845d3a9e096efc8b00ad05a621" } ], "manual_description": None, "incident_id": "697567", "notes": None, "assigned_user_mail": None, "high_severity_alert_count": 1 } INCIDENT_FROM_XDR_RAW_RESPONSE = { 'incident': INCIDENT_FROM_XDR } def test_compare_incident_in_demisto_vs_xdr_context___incident_not_modified(): """ Given - incident in xdr which already in context - incident in demisto When - nothing has changed Then - compare function returns is_modified=False """ incident_id = "100" fields_mapping = { "status": "xdrstatus", "severity": "severity" } incident_in_demisto = copy.deepcopy(INCIDENT_IN_DEMISTO) xdr_incident_in_context = copy.deepcopy(INCIDENT_FROM_XDR) xdr_incident_in_context['severity'] = 1 is_modified, update_args = xdr_script.compare_incident_in_demisto_vs_xdr_context(incident_in_demisto, xdr_incident_in_context, incident_id, fields_mapping) assert not is_modified def test_compare_incident_in_demisto_vs_xdr_context___status_was_modified(): """ Given - incident in xdr which already in context - incident in demisto When - xdrstatus field in demisto changed to closed Then - compare function returns is_modified=True update_args contains status """ incident_id = "100" fields_mapping = { "status": "xdrstatus", "severity": "severity" } incident_in_demisto = copy.deepcopy(INCIDENT_IN_DEMISTO) incident_in_demisto["CustomFields"]["xdrstatus"] = "closed" xdr_incident_in_context = copy.deepcopy(INCIDENT_FROM_XDR) xdr_incident_in_context['severity'] = 1 is_modified, update_args = xdr_script.compare_incident_in_demisto_vs_xdr_context(incident_in_demisto, xdr_incident_in_context, incident_id, fields_mapping) assert is_modified assert { "incident_id": "100", "status": "closed" } == update_args def test_compare_incident_in_demisto_vs_xdr_context___severity_was_modified(): """ Given - incident in xdr which already in context - incident in demisto When - severity field in demisto changed to 3 (high) Then - compare function returns is_modified=True update_args contains manual_severity """ incident_id = "100" fields_mapping = { "status": "xdrstatus", "severity": "severity" } incident_in_demisto = copy.deepcopy(INCIDENT_IN_DEMISTO) incident_in_demisto["severity"] = 3 xdr_incident_in_context = copy.deepcopy(INCIDENT_FROM_XDR) is_modified, update_args = xdr_script.compare_incident_in_demisto_vs_xdr_context(incident_in_demisto, xdr_incident_in_context, incident_id, fields_mapping) assert is_modified assert { "incident_id": "100", "manual_severity": "high" } == update_args def test_compare_incident_in_demisto_vs_xdr_context___status_and_severity_was_modified(): """ Given - incident in xdr which already in context - incident in demisto When - severity field in demisto changed - xdrstatus field in demisto changed Then - compare function returns is_modified=True update_args contains manual_severity and status """ incident_id = "100" fields_mapping = { "status": "xdrstatus", "severity": "severity" } incident_in_demisto = copy.deepcopy(INCIDENT_IN_DEMISTO) incident_in_demisto["severity"] = 3 incident_in_demisto["CustomFields"]["xdrstatus"] = "closed" xdr_incident_in_context = copy.deepcopy(INCIDENT_FROM_XDR) is_modified, update_args = xdr_script.compare_incident_in_demisto_vs_xdr_context(incident_in_demisto, xdr_incident_in_context, incident_id, fields_mapping) assert is_modified assert { "incident_id": "100", "manual_severity": "high", "status": "closed" } == update_args def test_compare_incident_latest_xdr_incident_with_older_xdr_in_context____when_nothing_changed(): """ Given - incident from xdr - latest - incident from xdr - older - fields_mapping: status: xdrstatus, severity: xdrseverity, manual_severity: severity When - nothing changed Then - ensure compare returns is_modified=False """ fields_mapping = { "status": "xdrstatus", "severity": "severity" } incident_in_xdr_latest = copy.deepcopy(INCIDENT_FROM_XDR) incident_from_xdr_in_context = copy.deepcopy(INCIDENT_FROM_XDR) incident_from_xdr_in_context['severity'] = 1 is_modified, update_args = xdr_script.compare_incident_in_xdr_vs_previous_xdr_in_context( incident_in_xdr_latest, incident_from_xdr_in_context, fields_mapping) assert not is_modified def test_compare_incident_latest_xdr_incident_with_older_xdr_in_context____when_status_changed(): """ Given - incident from xdr - latest - incident from xdr - older - fields_mapping: status: xdrstatus, severity: xdrseverity, manual_severity: severity When - status changed from new to under_investigation Then - ensure compare returns is_modified=True - ensure compare returns update_args contains xdrstatus=under_investigation """ fields_mapping = { "status": "xdrstatus", "severity": "severity", } incident_in_xdr_latest = copy.deepcopy(INCIDENT_FROM_XDR) incident_in_xdr_latest["status"] = "under_investigation" incident_in_xdr_latest["modification_time"] += 100 incident_from_xdr_in_context = copy.deepcopy(INCIDENT_FROM_XDR) incident_from_xdr_in_context['severity'] = 1 is_modified, update_args = xdr_script.compare_incident_in_xdr_vs_previous_xdr_in_context( incident_in_xdr_latest, incident_from_xdr_in_context, fields_mapping) assert is_modified assert { "xdrstatus": "under_investigation", } == update_args def test_compare_incident_latest_xdr_incident_with_older_xdr_in_context____when_manual_severity_changed(): """ Given - incident from xdr - latest - incident from xdr - older - fields_mapping: status: xdrstatus, severity: xdrseverity, manual_severity: severity When - manual_severity changed from None to medium Then - ensure compare returns is_modified=True - ensure compare returns update_args contains severity=medium """ fields_mapping = { "status": "xdrstatus", "manual_severity": "severity" } incident_in_xdr_latest = copy.deepcopy(INCIDENT_FROM_XDR) incident_in_xdr_latest["manual_severity"] = "medium" incident_in_xdr_latest["modification_time"] += 100 incident_from_xdr_in_context = copy.deepcopy(INCIDENT_FROM_XDR) incident_from_xdr_in_context['severity'] = 1 is_modified, update_args = xdr_script.compare_incident_in_xdr_vs_previous_xdr_in_context( incident_in_xdr_latest, incident_from_xdr_in_context, fields_mapping) assert is_modified assert { "severity": "medium", } == update_args def test_compare_incident_latest_xdr_incident_with_older_xdr_in_context____when_status_and_severity_changed(): """ Given - incident from xdr - latest - incident from xdr - older - fields_mapping: status: xdrstatus, severity: xdrseverity, manual_severity: severity When - manual_severity changed from None to medium - status changed from new to under_investigation - Then - ensure compare returns is_modified=True - ensure compare returns update_args contains severity=medium """ fields_mapping = { "status": "xdrstatus", "severity": "xdrseverity", "manual_severity": "severity" } incident_in_xdr_latest = copy.deepcopy(INCIDENT_FROM_XDR) incident_in_xdr_latest["manual_severity"] = "medium" incident_in_xdr_latest["status"] = "under_investigation" incident_in_xdr_latest["modification_time"] += 100 incident_from_xdr_in_context = copy.deepcopy(INCIDENT_FROM_XDR) incident_from_xdr_in_context['severity'] = 1 is_modified, update_args = xdr_script.compare_incident_in_xdr_vs_previous_xdr_in_context( incident_in_xdr_latest, incident_from_xdr_in_context, fields_mapping) assert is_modified assert { "severity": "medium", "xdrstatus": "under_investigation" } == update_args def test_args_to_str_1(): xdr_incident = copy.deepcopy(INCIDENT_FROM_XDR) args = { "incident_id": "11", "assigned_user_mail": "xdrassigneduser", "status": "xdrstatus", "severity": "xdrseverity", "playbook_to_run": "XDR Demo", "first": "true" } actual = xdr_script.args_to_str(args, xdr_incident) expected = 'incident_id=`11` assigned_user_mail=`xdrassigneduser` status=`xdrstatus` severity=`xdrseverity` ' \ 'playbook_to_run=`XDR Demo` first=`false` xdr_incident_from_previous_run=`{}` '\ .format(json.dumps(xdr_incident)) assert expected == actual def test_args_to_str_2(): xdr_incident = copy.deepcopy(INCIDENT_FROM_XDR) args = { "incident_id": "11", "assigned_user_mail": "xdrassigneduser", "status": "xdrstatus", "severity": "xdrseverity", "playbook_to_run": "XDR Demo", "first": "false", "xdr_incident_from_previous_run": "some previous value" } actual = xdr_script.args_to_str(args, xdr_incident) expected = 'incident_id=`11` assigned_user_mail=`xdrassigneduser` status=`xdrstatus` severity=`xdrseverity` ' \ 'playbook_to_run=`XDR Demo` first=`false` xdr_incident_from_previous_run=`{}` '\ .format(json.dumps(xdr_incident)) assert expected == actual def test_compare_incident_in_demisto_when_the_severity_is_unknown(): """ Given - incident in demisto - incident from xdr - older - fields_mapping: severity: severity When - severity in demisto is unknown Then - ensure severity is not updated in XDR """ incident_id = "100" fields_mapping = { "severity": "severity" } incident_in_demisto = copy.deepcopy(INCIDENT_IN_DEMISTO) incident_in_demisto["severity"] = 0 xdr_incident_in_context = copy.deepcopy(INCIDENT_FROM_XDR) is_modified, update_args = xdr_script.compare_incident_in_demisto_vs_xdr_context(incident_in_demisto, xdr_incident_in_context, incident_id, fields_mapping) assert is_modified is False assert {} == update_args def test_fix_bug_19669(mocker, capfd): """ bug fix https://github.com/demisto/etc/issues/19669 The script was throwing `local variable 'latest_incident_in_xdr' referenced before assignment` Given - xdr script When - script executed and xdr_incident_sync raised an exception Then - the xdr_script should not fail on syntax error: `local variable 'latest_incident_in_xdr' referenced before assignment` - the script should return error entry with message `Raised exception` """ import XDRSyncScript as xdr_script import demistomock as demisto import sys mocker.patch.object(xdr_script, 'xdr_incident_sync', side_effect=Exception('Raised exception')) mocker.patch.object(demisto, 'results') # mocking exit we make sure that return_error don't stop the test - bad practice but have no choise for now mocker.patch.object(sys, 'exit') mocker.patch.object(demisto, 'executeCommand', return_value=[{ 'Contents': { 'id': '1000' }, 'Type': entryTypes['note'], 'Format': formats['json'] }]) args = { 'interval': '1' } with capfd.disabled(): # this line should prevent the test failing on writing to demisto.error => print => stdout xdr_script.main(args) assert demisto.results.call_count == 1 # call_args is tuple (args list, kwargs). we only need the first one results = demisto.results.call_args[0] assert len(results) == 1 assert results[0]['Type'] == entryTypes['error'] assert results[0]['Contents'] == 'Raised exception' def create_test_incident(no_assignee=False, severity=None): xdr_incident = copy.deepcopy(INCIDENT_FROM_XDR) demisto_incident = copy.deepcopy(INCIDENT_IN_DEMISTO) if no_assignee: xdr_incident['assigned_user_pretty_name'] = None xdr_incident[ASSIGNED_USER_MAIL_XDR_FIELD] = None demisto_incident['xdrassignedusermail'] = '' demisto_incident['xdrassigneduserprettyname'] = '' if severity: xdr_incident[SEVERITY_XDR_FIELD] = severity # 3=high, 2=medium, 1=low demisto_incident['severity'] = { 'high': 3, 'medium': 2, 'low': 1 }[severity] xdr_incident_from_previous_run = copy.deepcopy(xdr_incident) if 'alerts' in xdr_incident_from_previous_run: del xdr_incident_from_previous_run['alerts'] if 'file_artifacts' in xdr_incident_from_previous_run: del xdr_incident_from_previous_run['file_artifacts'] if 'network_artifacts' in xdr_incident_from_previous_run: del xdr_incident_from_previous_run['network_artifacts'] return demisto_incident, xdr_incident_from_previous_run, xdr_incident def get_execute_command_call(mocked_execute_command, script_name): """ Returns: is_called - True means script was called via demisto.executeCommand script_args - The arguments that demisto.executeCommand was called with """ if mocked_execute_command.call_count == 0: return False, None for call_args in mocked_execute_command.call_args_list: if call_args[0][0] == script_name: return True, call_args[0][1] return False, None def test_incident_was_modified_in_xdr(mocker): """ - incident in demisto - incident in xdr - incident assignee in xdr is updated by the user to be foo@test.com - XDRSyncScript executed - ensure incident assignee in demisto is updated to be foo@test.com - ensure current playbook was re-executed - ensure XDRSyncScript is scheduled to be executed in the next internal with xdr_incident_from_previous_run has assignee foo@test.com """ import XDRSyncScript as xdr_script import demistomock as demisto # - incident in demisto # - incident in xdr demisto_incident, xdr_incident_from_previous_run, xdr_incident_latest = create_test_incident(no_assignee=True) # - incident assignee in xdr is updated by the user to be foo@test.com xdr_incident_latest[ASSIGNED_USER_MAIL_XDR_FIELD] = 'foo@test.com' xdr_incident_latest[MODIFICATION_TIME_XDR_FIELD] = xdr_incident_from_previous_run[MODIFICATION_TIME_XDR_FIELD] + 100 mocker.patch.object(demisto, 'incidents', return_value=[demisto_incident]) mocker.patch.object(demisto, 'results') mocker.patch.object(demisto, 'executeCommand', return_value=[{ 'Contents': { 'incident': xdr_incident_latest, 'alerts': { 'data': xdr_incident_latest['alerts'] }, 'file_artifacts': { 'data': xdr_incident_latest['file_artifacts'] }, 'network_artifacts': { 'data': xdr_incident_latest['network_artifacts'] } }, 'HumanReadable': 'nla', 'Type': entryTypes['note'], 'Format': formats['json'] }]) args = { 'interval': '1', 'verbose': 'true', 'first': 'false', ASSIGNED_USER_MAIL_XDR_FIELD: 'xdrassignedusermail', 'xdr_alerts': 'xdralerts', 'xdr_file_artifacts': 'xdrfileartifacts', 'xdr_network_artifacts': 'xdrnetworkartifacts', 'xdr_incident_from_previous_run': json.dumps(xdr_incident_from_previous_run) } xdr_script.main(args) # - ensure incident assignee in demisto is updated to be foo@test.com is_called, set_incident_args = get_execute_command_call(demisto.executeCommand, 'setIncident') assert is_called is True assert set_incident_args['xdrassignedusermail'] == 'foo@test.com' # - ensure current playbook was re-executed is_playbook_executed, _ = get_execute_command_call(demisto.executeCommand, 'setPlaybook') assert is_playbook_executed is True # - ensure XDRSyncScript is scheduled to be executed in the next internal with # xdr_incident_from_previous_run has assignee foo@test.com is_called, scheduled_command_args = get_execute_command_call(demisto.executeCommand, 'ScheduleCommand') assert is_called is True scheduled_command = scheduled_command_args['command'] assert '"assigned_user_mail": "foo@test.com"' in scheduled_command def test_incident_was_modified_in_demisto(mocker): """ - incident in demisto and in XDR with low severity - incident severity in Demisto is updated by the user to be "high" - XDRSyncScript executed - ensure incident severity in XDR is updated to be high - ensure playbook is NOT executed - ensure XDRSyncScript is scheduled to be executed in the next internal with xdr_incident_from_previous_run has severity=high """ import XDRSyncScript as xdr_script import demistomock as demisto # - incident in demisto # - incident in xdr demisto_incident, xdr_incident_from_previous_run, xdr_incident_latest = create_test_incident(severity='low') # - incident severity in Demisto is updated by the user to be "high" demisto_incident['severity'] = 3 # - XDRSyncScript executed mocker.patch.object(demisto, 'incidents', return_value=[demisto_incident]) mocker.patch.object(demisto, 'results') mocker.patch.object(demisto, 'executeCommand', return_value=[{ 'Contents': { 'incident': xdr_incident_latest, 'alerts': { 'data': xdr_incident_latest['alerts'] }, 'file_artifacts': { 'data': xdr_incident_latest['file_artifacts'] }, 'network_artifacts': { 'data': xdr_incident_latest['network_artifacts'] } }, 'HumanReadable': 'nla', 'Type': entryTypes['note'], 'Format': formats['json'] }]) args = { 'interval': '1', 'verbose': 'true', 'first': 'false', SEVERITY_XDR_FIELD: 'severity', 'xdr_alerts': 'xdralerts', 'xdr_file_artifacts': 'xdrfileartifacts', 'xdr_network_artifacts': 'xdrnetworkartifacts', 'xdr_incident_from_previous_run': json.dumps(xdr_incident_from_previous_run) } xdr_script.main(args) # - ensure incident severity in XDR is updated to be high is_called, xdr_update_args = get_execute_command_call(demisto.executeCommand, 'xdr-update-incident') assert is_called is True assert xdr_update_args[MANUAL_SEVERITY_XDR_FIELD] == 'high' # - ensure playbook is NOT executed is_playbook_executed, _ = get_execute_command_call(demisto.executeCommand, 'setPlaybook') assert not is_playbook_executed # - ensure XDRSyncScript is scheduled to be executed in the next internal with # xdr_incident_from_previous_run has severity=high is_called, scheduled_command_args = get_execute_command_call(demisto.executeCommand, 'ScheduleCommand') assert is_called is True EXPECTED_INCIDENT = { 'incident_id': '697567', 'manual_severity': None, 'assigned_user_mail': None, 'high_severity_alert_count': None, 'host_count': None, 'xdr_url': 'http://example.com/incident-view/697567', 'assigned_user_pretty_name': '', 'alert_count': 1, 'med_severity_alert_count': None, 'user_count': None, 'severity': 1, 'low_severity_alert_count': None, 'status': 'new', 'description': 'WildFire Malware detected on host HostNameFFM8VIP9', 'resolve_comment': None, 'notes': None, 'modification_time': 1559463309323 } def test_create_incident_from_saved_data_without_extra_data(): """ Given - incident in demisto - fields_mapping: status: xdrstatus, severity: xdrseverity, manual_severity: severity - include_extra_data = False When - creating an incident object from the context incident Then - ensure date fields are parsed correctly - ensure all relevant fields are present """ fields_mapping = { "alert_count": "xdralertcount", "assigned_user_mail": "xdrassigneduseremail", "assigned_user_pretty_name": "xdrassigneduserprettyname", "description": "xdrdescription", "high_severity_alert_count": "xdrhighseverityalertcount", "host_count": "xdrhostcount", "incident_id": "10", "low_severity_alert_count": "xdrlowseverityalertcount", "manual_severity": "xdrmanualseverity", "med_severity_alert_count": "xdrmediumseverityalertcount", "modification_time": "xdrmodificationtime", "notes": "xdrnotes", "resolve_comment": "xdrresolvecomment", "severity": "severity", "status": "xdrstatus", "user_count": "xdrusercount", "xdr_url": "xdrurl" } incident_from_context = copy.deepcopy(INCIDENT_IN_DEMISTO) created_incident = xdr_script.create_incident_from_saved_data(incident_from_context, fields_mapping) assert created_incident == EXPECTED_INCIDENT EXPECTED_INCIDENT_EXTRA_DATA = { "xdralerts": [ { "category": "WildFirePostDetection", "action_pretty": "Detected (Reported)", "description": "Suspicious executable detected", "severity": "high", "host_ip": "8.8.8.8", "source": "Traps", "alert_id": "50820", "host_name": "HostNameFFM8VIP9", "detection_timestamp": 1559215835437, "action": "REPORTED", "user_name": "N/A", "name": "WildFire Malware" } ], "xdrfileartifacts": [ { "file_signature_status": "SIGNATURE_UNAVAILABLE", "is_process": None, "file_name": "LCTGSK7IML.docx", "file_wildfire_verdict": "UNKNOWN", "alert_count": 1, "is_malicious": None, "is_manual": None, "file_signature_vendor_name": None, "type": "HASH", "file_sha256": "384654fa409c7a500a4a843d33a005c9d670d4845d3a9e096efc8b00ad05a621" } ], "xdrnetworkartifacts": [] } def test_create_incident_from_saved_data_with_extra_data(): """ Given - incident in demisto - fields_mapping: status: xdrstatus, severity: xdrseverity, manual_severity: severity - include_extra_data = True When - creating an incident object from the context incident Then - ensure date fields are parsed correctly - ensure all relevant fields are present """ fields_mapping = { "status": "xdrstatus", "severity": "severity" } incident_from_context = copy.deepcopy(INCIDENT_IN_DEMISTO) created_incident = xdr_script.create_incident_from_saved_data(incident_from_context, fields_mapping, True) assert created_incident == EXPECTED_INCIDENT_EXTRA_DATA def test_create_incident_from_saved_data_without_extra_data_old_incident(): """ Given - an old incident in demisto (which means that 'xdrmodificationtime' is not mapped but present in 'labels') - fields_mapping: { "alert_count": "xdralertcount", "assigned_user_mail": "xdrassigneduseremail", "assigned_user_pretty_name": "xdrassigneduserprettyname", "description": "xdrdescription", "high_severity_alert_count": "xdrhighseverityalertcount", "host_count": "xdrhostcount", "incident_id": "10", "low_severity_alert_count": "xdrlowseverityalertcount", "manual_severity": "xdrmanualseverity", "med_severity_alert_count": "xdrmediumseverityalertcount", "modification_time": "xdrmodificationtime", "notes": "xdrnotes", "resolve_comment": "xdrresolvecomment", "severity": "severity", "status": "xdrstatus", "user_count": "xdrusercount", "xdr_url": "xdrurl" } - include_extra_data = False When - creating an incident object from the context incident Then - ensure date fields are parsed correctly - ensure all relevant fields are present """ fields_mapping = { "alert_count": "xdralertcount", "assigned_user_mail": "xdrassigneduseremail", "assigned_user_pretty_name": "xdrassigneduserprettyname", "description": "xdrdescription", "high_severity_alert_count": "xdrhighseverityalertcount", "host_count": "xdrhostcount", "incident_id": "10", "low_severity_alert_count": "xdrlowseverityalertcount", "manual_severity": "xdrmanualseverity", "med_severity_alert_count": "xdrmediumseverityalertcount", "modification_time": "xdrmodificationtime", "notes": "xdrnotes", "resolve_comment": "xdrresolvecomment", "severity": "severity", "status": "xdrstatus", "user_count": "xdrusercount", "xdr_url": "xdrurl" } incident_from_context = copy.deepcopy(OLD_INCIDENT_IN_DEMISTO) created_incident = xdr_script.create_incident_from_saved_data(incident_from_context, fields_mapping) assert created_incident == EXPECTED_INCIDENT def test_create_incident_from_saved_data_old_incident_no_modification_time(): """ Given - an old incident in demisto (which means that 'xdrmodificationtime' is not mapped and not in 'labels') - fields_mapping: { "alert_count": "xdralertcount", "assigned_user_mail": "xdrassigneduseremail", "assigned_user_pretty_name": "xdrassigneduserprettyname", "description": "xdrdescription", "high_severity_alert_count": "xdrhighseverityalertcount", "host_count": "xdrhostcount", "incident_id": "10", "low_severity_alert_count": "xdrlowseverityalertcount", "manual_severity": "xdrmanualseverity", "med_severity_alert_count": "xdrmediumseverityalertcount", "modification_time": "xdrmodificationtime", "notes": "xdrnotes", "resolve_comment": "xdrresolvecomment", "severity": "severity", "status": "xdrstatus", "user_count": "xdrusercount", "xdr_url": "xdrurl" } - include_extra_data = False When - creating an incident object from the context incident Then - ensure date fields are parsed correctly - ensure all relevant fields are present """ fields_mapping = { "alert_count": "xdralertcount", "assigned_user_mail": "xdrassigneduseremail", "assigned_user_pretty_name": "xdrassigneduserprettyname", "description": "xdrdescription", "high_severity_alert_count": "xdrhighseverityalertcount", "host_count": "xdrhostcount", "incident_id": "10", "low_severity_alert_count": "xdrlowseverityalertcount", "manual_severity": "xdrmanualseverity", "med_severity_alert_count": "xdrmediumseverityalertcount", "modification_time": "xdrmodificationtime", "notes": "xdrnotes", "resolve_comment": "xdrresolvecomment", "severity": "severity", "status": "xdrstatus", "user_count": "xdrusercount", "xdr_url": "xdrurl" } EXPECTED_INCIDENT['modification_time'] = 0 incident_from_context = copy.deepcopy(OLD_INCIDENT_IN_DEMISTO) incident_from_context["labels"] = [] created_incident = xdr_script.create_incident_from_saved_data(incident_from_context, fields_mapping) assert created_incident['modification_time'] == 0 assert created_incident == EXPECTED_INCIDENT