@@ -49,23 +49,23 @@ def get_token_request(self) -> dict:
4949 token_response .pop ("team_name" , None )
5050 return token_response
5151
52- def get_audit_events_request (self , params : dict ) -> list :
52+ def get_audit_events_request (self , params : dict ) -> dict :
5353 """Gets audit events request.
5454
5555 Args:
5656 self (OktaASAClient): Okta ASA Client.
5757 params (Dict): Request parameters.
5858
5959 Returns:
60- list: A list of events .
60+ dict: The response dict form: {" list": [], "related_objects": {}} .
6161 """
62- events_response : list = self ._http_request ("GET" , "/auditsV2" , params = params ). get ( "list" , [] )
62+ events_response : dict = self ._http_request ("GET" , "/auditsV2" , params = params )
6363
6464 return events_response
6565
6666 def execute_audit_events_request (
6767 self , offset : Optional [str ], count : Optional [int ], descending : Optional [bool ], prev : Optional [bool ]
68- ) -> list :
68+ ) -> tuple [ list , dict ] :
6969 """Gets audit events request.
7070
7171 Args:
@@ -76,13 +76,13 @@ def execute_audit_events_request(
7676 prev (bool): Controls the direction of paging
7777
7878 Returns:
79- Dict : The response.
79+ tuple[list,dict] : The response "list" and the response "related_objects" .
8080 """
8181
8282 params = assign_params (offset = offset , count = count , descending = descending , prev = prev )
8383 self .generate_token_if_required ()
84- events_response = self .get_audit_events_request (params )
85- return events_response
84+ response = self .get_audit_events_request (params )
85+ return response . get ( "list" ,[]), response . get ( "related_objects" ,{})
8686
8787 def generate_token_if_required (self , hard : bool = False ) -> None :
8888 """Checks if token refresh required and return the token.
@@ -112,14 +112,15 @@ def generate_token_if_required(self, hard: bool = False) -> None:
112112 self ._headers = {"Authorization" : f"Bearer { token } " }
113113
114114 def search_events (
115- self , limit : Optional [int ] = 10000 , offset : str | None = None
115+ self , limit : Optional [int ] = 10000 , add_time_mapping : bool = False , offset : str | None = None
116116 ) -> tuple [List [Dict ], Optional [str ], Optional [str ]]:
117117 """
118118 Searches for Okta ASA events using the '/auditsV2' API endpoint.
119119 All the parameters are passed directly to the API as HTTP POST parameters in the request
120120
121121 Args:
122122 limit (int): limit.
123+ add_time_mapping (bool): whether to add time mapping.
123124 offset (str): The UUID of an object used as an offset for pagination.
124125
125126 Returns:
@@ -133,9 +134,12 @@ def search_events(
133134 count = min (limit , 1000 ) if limit else 1000
134135 while limit and len (results ) < limit :
135136 descending = bool (not offset )
136- events = self .execute_audit_events_request (offset = offset , count = count , descending = descending , prev = None )
137+ events , related_objects = self .execute_audit_events_request (
138+ offset = offset , count = count , descending = descending , prev = None
139+ )
137140 if not events :
138141 break
142+ add_time_and_related_object_data_to_events (events , related_objects , add_time_mapping )
139143 event_offset = events [0 ] if descending else events [len (events ) - 1 ]
140144 offset = event_offset .get ("id" )
141145 returned_timestamp = event_offset .get ("timestamp" )
@@ -165,18 +169,32 @@ def is_token_expired(expires_date: str) -> bool:
165169 return current_utc_time > expires_datetime_date
166170
167171
168- def add_time_to_events (events : List [Dict ]):
172+ def add_time_and_related_object_data_to_events (events : List [Dict ], related_objects : Dict , add_time_mapping : bool ):
169173 """
170- Adds the _time key to the events.
174+ Adds the "_time" key to the event and enhances the "server", "project" keys values of an event.
175+ Related object structure is "related_objects": {"id_of_keys_to_enhance": {"type": "some_type", "object": {}}}
171176 Args:
172177 events: List[Dict] - list of events to add the _time key to.
178+ related_objects: Dict - A dict of events related_objects to add the related objects to.
179+ add_time_mapping (bool): whether to add time mapping.
173180 Returns:
174- list: The events with the _time key.
181+ list: The events with the _time key and related object information .
175182 """
183+ keys_to_enhance = ["project" , "server" ]
176184 for event in events :
177- create_time = arg_to_datetime (arg = event .get ("timestamp" ))
178- event ["_time" ] = create_time .strftime (DATE_FORMAT ) if create_time else None
179-
185+ if add_time_mapping :
186+ create_time = arg_to_datetime (arg = event .get ("timestamp" ))
187+ event ["_time" ] = create_time .strftime (DATE_FORMAT ) if create_time else None
188+
189+ for key in keys_to_enhance :
190+ event_details = event .get ("details" , {})
191+ id_of_key_to_enhance = event_details .get (key )
192+ if not event_details or not id_of_key_to_enhance :
193+ continue
194+ # structure is {"type": "some_type", "object": {}}
195+ related_object_dict = related_objects .get (id_of_key_to_enhance ,{})
196+ if key == related_object_dict .get ("type" ) and (related_object_data := related_object_dict .get ("object" )):
197+ event_details [key ] = related_object_data if related_object_data else id_of_key_to_enhance
180198
181199"""COMMAND FUNCTIONS"""
182200
@@ -206,21 +224,23 @@ def test_module(client: OktaASAClient) -> str:
206224 return "ok"
207225
208226
209- def get_events_command (client : OktaASAClient , args : dict = {}) -> tuple [List [Dict ], CommandResults ]:
227+ def get_events_command (
228+ client : OktaASAClient , args : dict = {}, add_time_mapping : bool = False
229+ ) -> tuple [List [Dict ], CommandResults ]:
210230 """
211231 Gets audit events from Audits Events endpoint.
212232
213233 Args:
214234 self (OktaASAClient): Okta ASA Client.
215235 args (dict): A dictionary containing the command arguments.
216-
236+ add_time_mapping (bool): whether to add time mapping.
217237 Returns:
218238 List[Dict]: list of events.
219239 CommandResults: command results containing Audits Events.
220240 """
221241
222242 limit = arg_to_number (args .get ("limit" )) or 50
223- events , _ , _ = client .search_events (limit = limit )
243+ events , _ , _ = client .search_events (limit = limit , add_time_mapping = add_time_mapping )
224244 hr = tableToMarkdown (name = "Audits Events" , t = events )
225245 return events , CommandResults (readable_output = hr )
226246
@@ -230,13 +250,15 @@ def fetch_events_command(
230250 last_run : dict [str , str ],
231251 team_name : str ,
232252 max_audit_events_per_fetch : Optional [int ],
253+ add_time_mapping : bool
233254) -> tuple [dict [str , str ], List [Dict ]]:
234255 """
235256 Args:
236257 client (OktaASAClient): OktaASAClient client to use.
237258 last_run (dict): A dict with a key containing the latest event created time we got from last fetch.
238259 max_audit_events_per_fetch (int): number of events per fetch.
239260 team_name (str): The name of the team.
261+ add_time_mapping (bool): whether to add time mapping.
240262 Returns:
241263 dict: Next run dictionary containing the timestamp that will be used in ``last_run`` on the next fetch.
242264 list: List of events that will be created in XSIAM.
@@ -246,6 +268,7 @@ def fetch_events_command(
246268 events , offset , timestamp = client .search_events (
247269 limit = max_audit_events_per_fetch ,
248270 offset = last_run .get ("offset" ) if last_run and last_run .get ("team_name" ) == team_name else None ,
271+ add_time_mapping = add_time_mapping
249272 )
250273 # Save the next_run as a dict with the last_fetch key to be stored
251274 next_run : dict = {"offset" : offset , "timestamp" : timestamp , "team_name" : team_name } if offset else last_run
@@ -271,7 +294,7 @@ def main() -> None: # pragma: no cover
271294 team_name = params .get ("team_name" , "" ).lower ()
272295 base_url = urljoin (params .get ("url" ), f"/v1/teams/{ team_name } " )
273296 verify_certificate = not params .get ("insecure" , False )
274- max_audit_events_per_fetch = arg_to_number (params .get ("max_audit_events_per_fetch" , "10000 " ))
297+ max_audit_events_per_fetch = arg_to_number (params .get ("max_audit_events_per_fetch" , "5000 " ))
275298 proxy = params .get ("proxy" , False )
276299
277300 demisto .debug (f"{ INTEGRATION_NAME } : Command being called is { command } " )
@@ -286,19 +309,17 @@ def main() -> None: # pragma: no cover
286309
287310 elif command == "okta-asa-get-events" :
288311 should_push_events = argToBoolean (args .pop ("should_push_events" ))
289- events , results = get_events_command (client , demisto .args ())
312+ events , results = get_events_command (client , demisto .args (), should_push_events )
290313 return_results (results )
291314 if should_push_events :
292- add_time_to_events (events )
293315 send_events_to_xsiam (events , vendor = VENDOR , product = PRODUCT )
294316
295317 elif command == "fetch-events" :
296318 last_run = demisto .getLastRun ()
297319 next_run , events = fetch_events_command (
298- client = client , last_run = last_run , max_audit_events_per_fetch = max_audit_events_per_fetch , team_name = team_name
320+ client = client , last_run = last_run , max_audit_events_per_fetch = max_audit_events_per_fetch , team_name = team_name ,
321+ add_time_mapping = True
299322 )
300-
301- add_time_to_events (events )
302323 send_events_to_xsiam (events , vendor = VENDOR , product = PRODUCT )
303324 demisto .setLastRun (next_run )
304325
0 commit comments