@@ -312,9 +312,51 @@ def list_domain_infratags(self, domains: list, cluster: Optional[bool] = False,
312
312
results [domain ] = response
313
313
except Exception as e :
314
314
demisto .error (f"Error fetching infratags for domain { domain } : { str (e )} " )
315
- results [domain ] = {"error" : str (e )}
315
+
316
+
317
+ def get_enrichment_data (self , resource : str , resource_type : str , explain : bool = False , scan_data : bool = False ) -> Dict :
318
+ """
319
+ Retrieve comprehensive enrichment information for a given resource (domain, IPv4, or IPv6).
320
+
321
+ Args:
322
+ resource (str): The resource identifier (domain name, IPv4 address, or IPv6 address)
323
+ resource_type (str): Type of resource ('domain', 'ipv4', 'ipv6')
324
+ explain (bool, optional): Whether to show details of data used to calculate scores (default: False)
325
+ scan_data (bool, optional): Whether to show details of data collected from scanning (default: False)
326
+
327
+ Returns:
328
+ Dict: The enrichment data response from the API
329
+
330
+ Raises:
331
+ ValueError: If resource_type is not one of 'domain', 'ipv4', 'ipv6'
332
+ DemistoException: If the API request fails
333
+ """
334
+ if resource_type not in {'domain' , 'ipv4' , 'ipv6' }:
335
+ raise ValueError ("resource_type must be one of: 'domain', 'ipv4', 'ipv6'" )
336
+
337
+ demisto .debug (f'Fetching enrichment data for { resource_type } : { resource } ' )
338
+ url_suffix = f'explore/enrich/{ resource_type } /{ resource } '
339
+
340
+ params = {
341
+ 'explain' : 1 if explain else 0 ,
342
+ 'scan_data' : 1 if scan_data else 0
343
+ }
344
+
345
+ try :
346
+ response = self ._http_request (
347
+ method = 'GET' ,
348
+ url_suffix = url_suffix ,
349
+ params = params
350
+ )
351
+ demisto .debug (f'Enrichment response: { response } ' )
352
+ return response
353
+
354
+ except Exception as e :
355
+ raise DemistoException (f'Failed to fetch enrichment data for { resource_type } { resource } : { str (e )} ' )
356
+
357
+
358
+
316
359
317
- return results
318
360
319
361
320
362
@@ -510,6 +552,106 @@ def list_domain_infratags_command(client: Client, args: dict) -> CommandResults:
510
552
)
511
553
512
554
555
+ def get_enrichment_data_command (client : Client , args : Dict [str , Any ]) -> CommandResults :
556
+ """
557
+ Command handler for fetching enrichment data for a resource (domain, IPv4, or IPv6).
558
+
559
+ Args:
560
+ client (Client): The client instance to use for API calls
561
+ args (Dict[str, Any]): Command arguments
562
+ - resource (str): The resource to get enrichment data for (domain name, IPv4, or IPv6)
563
+ - resource_type (str): Type of resource ('domain', 'ipv4', 'ipv6')
564
+ - explain (bool, optional): Whether to show calculation details
565
+ - scan_data (bool, optional): Whether to include scan data
566
+
567
+ Returns:
568
+ CommandResults: The formatted results for XSOAR
569
+ """
570
+ resource = args .get ('resource' )
571
+ resource_type = args .get ('resource_type' )
572
+
573
+ if not resource or not resource_type :
574
+ raise ValueError ('"resource" and "resource_type" arguments are required' )
575
+
576
+
577
+ if resource_type not in {'domain' , 'ipv4' , 'ipv6' }:
578
+ raise ValueError ("'resource_type' must be one of: 'domain', 'ipv4', 'ipv6'" )
579
+
580
+ explain = argToBoolean (args .get ('explain' , False ))
581
+ scan_data = argToBoolean (args .get ('scan_data' , False ))
582
+
583
+ demisto .debug (f'Processing enrichment data for { resource_type } : { resource } ' )
584
+
585
+ try :
586
+ raw_response = client .get_enrichment_data (
587
+ resource = resource ,
588
+ resource_type = resource_type ,
589
+ explain = explain ,
590
+ scan_data = scan_data
591
+ )
592
+
593
+ if not raw_response :
594
+ return CommandResults (
595
+ readable_output = f'No enrichment data found for { resource_type } : { resource } ' ,
596
+ outputs_prefix = 'SilentPush.Enrichment' ,
597
+ outputs_key_field = 'resource' ,
598
+ outputs = {
599
+ 'resource' : resource ,
600
+ 'type' : resource_type ,
601
+ 'found' : False
602
+ }
603
+ )
604
+
605
+ markdown = []
606
+ markdown .append (f'## Enrichment Data for { resource_type } : { resource } \n ' )
607
+
608
+ enrichment_data = raw_response .get ('response' , {})
609
+
610
+
611
+ overview = {
612
+ 'Resource' : resource ,
613
+ 'Type' : resource_type
614
+ }
615
+
616
+ if 'risk_score' in enrichment_data :
617
+ overview ['Risk Score' ] = enrichment_data ['risk_score' ]
618
+ if 'first_seen' in enrichment_data :
619
+ overview ['First Seen' ] = enrichment_data ['first_seen' ]
620
+ if 'last_seen' in enrichment_data :
621
+ overview ['Last Seen' ] = enrichment_data ['last_seen' ]
622
+
623
+ markdown .append (tableToMarkdown ('Overview' , [overview ]))
624
+
625
+ if scan_data and enrichment_data .get ('scan_data' ):
626
+ scan_info = enrichment_data ['scan_data' ]
627
+ markdown .append ('\n ### Scan Data' )
628
+ markdown .append (tableToMarkdown ('' , [scan_info ]))
629
+
630
+ if explain and enrichment_data .get ('explanation' ):
631
+ explain_info = enrichment_data ['explanation' ]
632
+ markdown .append ('\n ### Score Explanation' )
633
+ markdown .append (tableToMarkdown ('' , [explain_info ]))
634
+
635
+ readable_output = '\n ' .join (markdown )
636
+
637
+ outputs = {
638
+ 'resource' : resource ,
639
+ 'type' : resource_type ,
640
+ 'found' : True ,
641
+ 'data' : enrichment_data
642
+ }
643
+
644
+ return CommandResults (
645
+ outputs_prefix = 'SilentPush.Enrichment' ,
646
+ outputs_key_field = 'resource' ,
647
+ outputs = outputs ,
648
+ readable_output = readable_output ,
649
+ raw_response = raw_response
650
+ )
651
+
652
+ except Exception as e :
653
+ demisto .error (f'Failed to get enrichment data: { str (e )} ' )
654
+ raise
513
655
514
656
''' MAIN FUNCTION '''
515
657
@@ -552,6 +694,7 @@ def main():
552
694
'silentpush-get-domain-certificates' : get_domain_certificates_command ,
553
695
'silentpush-search-domains' : search_domains_command ,
554
696
'silentpush-list-domain-infratags' : list_domain_infratags_command ,
697
+ 'silentpush-get-enrichment-data' : get_enrichment_data_command
555
698
}
556
699
557
700
if command in command_handlers :
0 commit comments