@@ -312,9 +312,51 @@ def list_domain_infratags(self, domains: list, cluster: Optional[bool] = False,
312312 results [domain ] = response
313313 except Exception as e :
314314 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+
316359
317- return results
318360
319361
320362
@@ -510,6 +552,106 @@ def list_domain_infratags_command(client: Client, args: dict) -> CommandResults:
510552 )
511553
512554
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
513655
514656''' MAIN FUNCTION '''
515657
@@ -552,6 +694,7 @@ def main():
552694 'silentpush-get-domain-certificates' : get_domain_certificates_command ,
553695 'silentpush-search-domains' : search_domains_command ,
554696 'silentpush-list-domain-infratags' : list_domain_infratags_command ,
697+ 'silentpush-get-enrichment-data' : get_enrichment_data_command
555698 }
556699
557700 if command in command_handlers :
0 commit comments