Skip to content

Commit

Permalink
Digital guardian Bug (#34920)
Browse files Browse the repository at this point in the history
* fixed parsing events from api

* fix

* added rn

* fix

* fix

* fixes

* fixes

* added rn

* updated do

* pre-commit edits

* Update Packs/DigitalGuardian/ReleaseNotes/1_1_5.md

Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>

* Update Packs/DigitalGuardian/ReleaseNotes/1_1_5.md

Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>

* fixes

* made a change for the unit test

* edit

* added fixes for unittests

* fixed do

---------

Co-authored-by: ShirleyDenkberg <62508050+ShirleyDenkberg@users.noreply.github.com>
  • Loading branch information
2 people authored and amshamah419 committed Jun 20, 2024
1 parent 190d1e4 commit 390b83b
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import json
import requests
import urllib3
from typing import Dict, Any, Union
from typing import Any

# Disable insecure warnings
urllib3.disable_warnings()
Expand Down Expand Up @@ -38,7 +38,7 @@ def request_api_token():
r = requests.post(url=AUTH_URL, headers=AUTH_HEADERS, data=payload, verify=VERIFY_CERT)
response_json = r.json()
if 200 <= r.status_code <= 299:
api_key = response_json['access_token']
api_key = response_json.get('access_token')
CLIENT_HEADERS['Authorization'] = 'Bearer ' + api_key
else:
return_error(f'Error in request_api_token [{r.status_code}] - {r.reason}')
Expand Down Expand Up @@ -70,7 +70,7 @@ def get_watchlist_id(watchlist_name: str) -> str:
list_id = None
if 200 <= r.status_code <= 299:
for item in json_text:
if item.get('display_name').lower() == watchlist_name.lower():
if item.get('display_name', '').lower() == watchlist_name.lower():
list_id = item.get('name')
else:
return_error(f'Error retrieving watchlist_id for {watchlist_name}, {r.status_code}: {r.text}')
Expand All @@ -91,8 +91,8 @@ def get_list_id(list_name: str, list_type: str) -> str:
list_id = None
if 200 <= r.status_code <= 299:
for jText in json_text:
if str(jText['name']).lower() == list_name.lower():
list_id = jText['id']
if str(jText.get('name', '')).lower() == list_name.lower():
list_id = jText.get('id')
else:
return_error(f'Error retrieving list_id for {list_name}, {r.status_code}: {r.text}')

Expand Down Expand Up @@ -125,8 +125,8 @@ def get_watchlist_entry_id(watchlist_name: str, watchlist_entry: str) -> str:
if r.status_code != requests.codes.ok:
return_error('Unable to retrieve watchlist entries')
for jText in json_text:
if str(jText['value_name']).lower() == watchlist_entry.lower():
watchlist_entry_id = jText['value_id']
if str(jText.get('value_name', '')).lower() == watchlist_entry.lower():
watchlist_entry_id = jText.get('value_id')

return str(watchlist_entry_id)

Expand Down Expand Up @@ -166,9 +166,9 @@ def check_componentlist_entry():
Sets DigitalGuardian.Componentlist.Found flag.
"""
componentlist_name = demisto.args().get('componentlist_name', None)
componentlist_entry = demisto.args().get('componentlist_entry', None)
if componentlist_name is None or componentlist_entry is None:
componentlist_name = demisto.args().get('componentlist_name', '')
componentlist_entry = demisto.args().get('componentlist_entry', '')
if not componentlist_name or not componentlist_entry:
return_error('Please provide both componentlist_name and componentlist_entry')

componentlist = None
Expand All @@ -180,8 +180,8 @@ def check_componentlist_entry():

if 200 <= r.status_code <= 299:
for jText in json_text:
if str(jText['content_value']).lower() == componentlist_entry.lower():
componentlist = jText['content_value']
if str(jText.get('content_value', '')).lower() == componentlist_entry.lower():
componentlist = jText.get('content_value')
else:
return_error(f'Unable to find componentlist named {componentlist_name}, {r.status_code}')

Expand Down Expand Up @@ -233,7 +233,7 @@ def add_entry_to_watchlist():
r = requests.post(url=full_url + watchlist_id + '/values/', data=watchlist_entry_json,
headers=CLIENT_HEADERS, verify=VERIFY_CERT)
if 200 <= r.status_code <= 299:
demisto.results('added watchlist entry ({}) to watchlist name ({})'.format(watchlist_entry, watchlist_name))
demisto.results(f'added watchlist entry ({watchlist_entry}) to watchlist name ({watchlist_name})')
else:
return_error(
'Failed to add watchlist entry({}) to watchlist name ({}). The response failed with status code {}. '
Expand Down Expand Up @@ -277,7 +277,7 @@ def rm_entry_from_watchlist():
headers=CLIENT_HEADERS, verify=VERIFY_CERT)
if 200 <= r.status_code <= 299:
demisto.results(
'removed watchlist entry ({}) from watchlist name ({})'.format(watchlist_entry, watchlist_name))
f'removed watchlist entry ({watchlist_entry}) from watchlist name ({watchlist_name})')
else:
return_error(
'Failed to remove watchlist entry({}) from watchlist name ({}). The response failed with status code {}. '
Expand All @@ -303,15 +303,16 @@ def get_items_request():
if r.status_code == 200:
header_field = []

for field in json_text['fields']:
header_field.append(field['name'])
for field in json_text.get('fields'):
header_field.append(field.get('name'))
exportdata = []
if json_text['total_hits'] == 0:
if json_text.get('total_hits') == 0:
DEBUG('found no data')
return None
else:
DEBUG('found data')

for data in json_text['data']:
for data in json_text.get('data'):
entry_line = {}
header_position = 0

Expand All @@ -321,11 +322,11 @@ def get_items_request():
exportdata.append(entry_line)

for items in exportdata:
if not (items['dg_alert.dg_detection_source']) == 'alert' and items['dg_tags']:
comm = items['dg_alarm_name'].find(',')
if items.get('dg_alert.dg_detection_source') != 'alert' and items.get('dg_tags'):
comm = items.get('dg_alarm_name', "").find(',')
if comm == -1:
comm = 100
name = '{alarm_name}-{id}'.format(alarm_name=items['dg_alarm_name'][0:comm], id=items['dg_guid'])
name = '{alarm_name}-{id}'.format(alarm_name=items.get('dg_alarm_name', "")[0:comm], id=items.get('dg_guid'))
DEBUG(name + " != " + oldname)
if name != oldname:
DEBUG("create_artifacts...")
Expand All @@ -338,6 +339,7 @@ def get_items_request():
return_error('DigitalGuardian ARC Export Failed '
'Please check authentication related parameters. ' + json.dumps(r.json(), indent=4,
sort_keys=True))
return None


def convert_to_demisto_severity(dg_severity: str) -> int:
Expand Down Expand Up @@ -458,27 +460,27 @@ def create_artifacts(alert):
DEBUG("before alert")
DEBUG(json.dumps(alert))
if CATEGORY in specific_alert_mapping:
temp_dict: Dict[Union[str, Any], Union[Union[str, int], Any]] = {}
cef: Dict[Union[str, Any], Union[Union[str, int], Any]] = {}
temp_dict: dict[str | Any, str | int | Any] = {}
cef: dict[str | Any, str | int | Any] = {}
cef_types = {}
cef['Vendor ID'] = 'DG'
cef['Vendor Product'] = 'Digital Guardian'
cef['severity'] = convert_to_demisto_severity(alert['dg_alarm_sev'])
cef['sensitivity'] = convert_to_demisto_sensitivity(alert['dg_class.dg_name'])
cef['severity'] = convert_to_demisto_severity(alert.get('dg_alarm_sev'))
cef['sensitivity'] = convert_to_demisto_sensitivity(alert.get('dg_class.dg_name'))

DEBUG("cef: " + json.dumps(cef))
for artifact_key, artifact_tuple in specific_alert_mapping.get(CATEGORY).items(): # type: ignore
if alert.get(artifact_tuple[0]):
cef[artifact_key] = alert[artifact_tuple[0]]
cef_types[artifact_key] = artifact_tuple[1]
if cef:
comm = alert['dg_alarm_name'].find(',')
comm = alert.get('dg_alarm_name', '').find(',')
if comm == -1:
comm = 100
name = '{alarm_name}-{id}'.format(alarm_name=alert['dg_alarm_name'][0:comm], id=alert['dg_guid'])
name = '{alarm_name}-{id}'.format(alarm_name=alert.get('dg_alarm_name')[0:comm], id=alert.get('dg_guid'))
temp_dict['name'] = name
temp_dict['severity'] = convert_to_demisto_severity(alert['dg_alarm_sev'])
temp_dict['type'] = alert['dg_tags']
temp_dict['severity'] = convert_to_demisto_severity(alert.get('dg_alarm_sev'))
temp_dict['type'] = alert.get('dg_tags')
temp_dict['occurred'] = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
temp_dict['rawJSON'] = json.dumps(cef)
artifacts_list.update(temp_dict)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ script:
required: true
description: Remove Componentlist Entry.
name: digitalguardian-remove-componentlist-entry
dockerimage: demisto/python3:3.10.14.92207
dockerimage: demisto/python3:3.10.14.98471
isfetch: true
runonce: false
script: '-'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,13 @@ def get_raw_events(client: Client, time_of_last_event: str) -> list:
time_of_last_event_str = temp_time.isoformat(sep=' ', timespec='milliseconds')
current_time = datetime_to_string(datetime.now())
events = client.get_events(time_of_last_event_str, current_time)
for field_names in events["fields"]:
outcome.append(field_names['name'])
for event in events["data"]:
events = {} if events is None else events
for field_names in events.get("fields"):
outcome.append(field_names.get('name'))
for event in events.get("data"):
result = dict(zip(outcome, event))
event_list.append(result)
event_list.sort(key=lambda item: (item["inc_mtime"], item["dg_guid"]))
event_list.sort(key=lambda item: (item.get("inc_mtime"), item.get("dg_guid")))
return event_list


Expand All @@ -141,7 +142,10 @@ def get_events_command(client: Client, args: dict) -> Tuple[list, CommandResults
limit = int(args.get("limit", 1000))
if limit:
event_list = event_list[:limit]
hr = tableToMarkdown(name='Test Event', t=event_list)
if not event_list:
hr = "No events found."
else:
hr = tableToMarkdown(name='Test Event', t=event_list)
demisto.debug(f'get events command that ran with the limit: {limit}')
return event_list, CommandResults(readable_output=hr)

Expand All @@ -163,19 +167,21 @@ def create_events_for_push(event_list: list, last_time: str, id_list: list, limi
event_list_for_push = []
demisto.debug('Checking duplications and creating events for pushing to XSIAM')
for event in event_list:
inc_time = event.get("inc_mtime")
if last_time:
last_time_date = arg_to_datetime(arg=last_time, required=True).date() # type: ignore[union-attr]
event_date = arg_to_datetime(arg=event.get("inc_mtime"), required=True).date() # type: ignore[union-attr]
if event.get("inc_mtime") < last_time or event.get("dg_guid") in id_list:
event_date = arg_to_datetime(arg=inc_time, required=True).date() if inc_time else None # type: ignore[union-attr]
if (inc_time and inc_time < last_time) or event.get("dg_guid") in id_list:
continue
if last_time_date == event_date:
if last_time_date == event_date and event.get("dg_guid"):
id_list.append(event.get("dg_guid"))
else:
elif event.get("dg_guid"):
id_list = [event.get("dg_guid")]
else:
id_list.append(event.get("dg_guid"))
if event.get("dg_guid"):
id_list.append(event.get("dg_guid"))
event_list_for_push.append(event)
last_time = event.get("inc_mtime")
last_time = inc_time if inc_time else last_time
index += 1
if index == limit:
break
Expand Down Expand Up @@ -216,7 +222,7 @@ def add_time_to_events(events: list[dict]) -> None:
"""
if events:
for event in events:
create_time = arg_to_datetime(arg=event.get('inc_mtime'))
create_time = arg_to_datetime(arg=event.get('inc_mtime')) if event.get('inc_mtime') else None
event['_time'] = create_time.strftime(DATE_FORMAT) if create_time else None


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ script:
description: Gets events from Hello World.
execution: false
name: digital-guardian-get-events
dockerimage: demisto/python3:3.10.13.78960
dockerimage: demisto/python3:3.10.14.98471
isfetchevents: true
runonce: false
script: '-'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def test_add_time_key_to_events():
events = util_load_json('test_data/events.json')
add_time_to_events(events)

assert events[0]['_time'] == "2023-05-23T06:56:39Z"
assert events[0]['_time'] is None
assert events[1]['_time'] == "2023-05-23T11:53:11Z"


Expand Down Expand Up @@ -120,4 +120,4 @@ def test_fetch_events_command(mocker):
mock_events = util_load_json('test_data/events.json')
assert events == mock_events
assert next_run == {'start_time': '2023-05-23 11:53:11',
'id_list': ['1dc3c1fa-5474-4fc0-a7c3-74ff42d28e5e', 'c742c377-b429-428a-b0c9-515cbbf143be']}
'id_list': ['1dc3c1fa-5474-4fc0-a7c3-74ff42d28e5e']}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"dg_description": "This file outlook.exe was going to [demo.digitalg@gmail.com]",
"inc_id": "230523-WIQHA",
"dg_comment": "-",
"inc_mtime": "2023-05-23 06:56:39",
"inc_mtime": "",
"dg_guid": "1dc3c1fa-5474-4fc0-a7c3-74ff42d28e5e",
"inc_sev": "Critical",
"dg_utype": "Incident",
Expand All @@ -22,7 +22,7 @@
"inc_id": "230523-RG0AB",
"dg_comment": "-",
"inc_mtime": "2023-05-23 11:53:11",
"dg_guid": "c742c377-b429-428a-b0c9-515cbbf143be",
"dg_guid": "",
"inc_sev": "Critical",
"dg_utype": "Incident",
"dg_tenant": "279b59f3-02f3-44ea-a7c3-9bac2eb0224d"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"dg_description": "This file outlook.exe was going to [demo.digitalg@gmail.com]",
"inc_id": "230523-WIQHA",
"dg_comment": "-",
"inc_mtime": "2023-05-23 06:56:39",
"inc_mtime": "",
"dg_guid": "1dc3c1fa-5474-4fc0-a7c3-74ff42d28e5e",
"inc_sev": "Critical",
"dg_utype": "Incident",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
"This file outlook.exe was going to [demo.digitalg@gmail.com]",
"230523-WIQHA",
"-",
"2023-05-23 06:56:39",
"",
"1dc3c1fa-5474-4fc0-a7c3-74ff42d28e5e",
"Critical",
"Incident",
Expand All @@ -121,7 +121,7 @@
"230523-RG0AB",
"-",
"2023-05-23 11:53:11",
"c742c377-b429-428a-b0c9-515cbbf143be",
"",
"Critical",
"Incident",
"279b59f3-02f3-44ea-a7c3-9bac2eb0224d"
Expand Down
12 changes: 12 additions & 0 deletions Packs/DigitalGuardian/ReleaseNotes/1_1_5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

#### Integrations

##### Digital Guardian

Fixed an issue where the ***fetch-incidents*** command did not handle empty responses gracefully.
- Updated the Docker image to *demisto/python3:3.10.14.98471*.

##### Digital Guardian ARC Event Collector

- Fixed an issue where the ***Fetch-events*** command did not handle empty responses gracefully.
- Updated the Docker image to *demisto/python3:3.10.14.98471*.
2 changes: 1 addition & 1 deletion Packs/DigitalGuardian/pack_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Digital Guardian",
"description": "Digital Guardian ARC Watchlist Integration",
"support": "partner",
"currentVersion": "1.1.4",
"currentVersion": "1.1.5",
"author": "Digital Guardian",
"url": "https://digitalguardian.com",
"email": "support@digitalguardian.com",
Expand Down

0 comments on commit 390b83b

Please sign in to comment.