Esempio n. 1
0
    def template_params(self, paramsStr):
        """
        Translate the template params if they exist from the context
        """
        actualParams = {}
        if paramsStr:
            try:
                params = json.loads(paramsStr)

            except ValueError as e:
                return_error('Unable to parse templateParams: {}'.format(
                    str(e)))
            # Build a simple key/value

            for p in params:
                if params[p].get('value'):
                    actualParams[p] = params[p]['value']

                elif params[p].get('key'):
                    actualParams[p] = demisto.dt(demisto.context(),
                                                 params[p]['key'])

            return actualParams

        else:
            return None
Esempio n. 2
0
def configure_job(job_name: str,
                  existing_job: Optional[Dict[str, Any]] = None) -> bool:
    """Configures the job in the XSOAR instance.
    """
    instance_context = demisto.context()
    job_params = existing_job or {}

    for job in instance_context.get('ConfigurationSetup', {}).get('Jobs', []):
        if job.get('name') == job_name:
            job_params.update(job)
            break

    if not job_params:
        return False

    res = demisto.executeCommand('demisto-api-post', {
        'uri': '/jobs',
        'body': job_params
    })
    if is_error(res):
        error_message = f'{SCRIPT_NAME} - {get_error(res)}'
        demisto.debug(error_message)
        return_error(error_message)
        return False

    return True
Esempio n. 3
0
def main():
    input_args = demisto.args()
    # If user did not provide a lower threshold then split is not needed.
    threshold = input_args.get('similarity_threshold')

    try:
        threshold = float(threshold)
    except ValueError as e:
        raise DemistoException(
            f'Could not use threshold: {threshold}. Error: {e}')

    root_context_path = 'EmailCampaign'
    above_threshold_context_path = f'{root_context_path}.{ABOVE_THE_THRESHOLD_ITEMS_CONTEXT_PATH}'
    below_threshold_context_path = f'{root_context_path}.{BELOW_THRESHOLD_ITEMS_CONTEXT_PATH}'
    context = demisto.get(demisto.context(), f'{above_threshold_context_path}')

    # If there are no incident to split
    if not context:
        return
    only_lower_values, only_higher_values = filter_by_threshold(
        context, threshold)
    result = []
    result.append(
        save_to_context(only_lower_values,
                        below_threshold_context_path,
                        table_header='Low Similarity Incidents Result'))
    result.append(
        save_to_context(only_higher_values,
                        above_threshold_context_path,
                        True,
                        table_header='High Similarity Incidents Result'))
    return_results(result)
def list_members_command(client: MsGraphClient,
                         args: Dict) -> Tuple[str, Dict, Dict]:
    """List a group members by group id. return outputs in Demisto's format.

    Args:
        client: Client object with request
        args: Usually demisto.args()

    Returns:
        Outputs.
    """
    group_id = str(args.get('group_id'))
    next_link = args.get('next_link')
    top = args.get('top')
    filter_ = args.get('filter')
    members = client.list_members(group_id, next_link, top, filter_)

    if not members['value']:
        human_readable = f'The group {group_id} has no members.'
        return human_readable, NO_OUTPUTS, NO_OUTPUTS

    members_readable, members_outputs = parse_outputs(members['value'])

    # get the group data from the context
    group_data = demisto.dt(
        demisto.context(),
        f'{INTEGRATION_CONTEXT_NAME}(val.ID === "{group_id}")')
    if not group_data:
        return_error(
            'Could not find group data in the context, please run "!msgraph-groups-get-group" to retrieve group data.'
        )
    if isinstance(group_data, list):
        group_data = group_data[0]

    if '@odata.nextLink' in members:
        next_link_response = members['@odata.nextLink']
        group_data[
            'Members'] = members_outputs  # add a field with the members to the group
        group_data['MembersNextLink'] = next_link_response
        entry_context = {
            f'{INTEGRATION_CONTEXT_NAME}(val.ID === obj.ID)': group_data
        }
        title = f'Group {group_id} members ' \
                f'(Note that there are more results. Please use the next_link argument to see them. The value can be ' \
                f'found in the context under {INTEGRATION_CONTEXT_NAME}.MembersNextLink): '
    else:
        group_data[
            'Members'] = members_outputs  # add a field with the members to the group
        entry_context = {
            f'{INTEGRATION_CONTEXT_NAME}(val.ID === obj.ID)': group_data
        }
        title = f'Group {group_id} members:'

    human_readable = tableToMarkdown(
        name=title,
        t=members_readable,
        headers=['ID', 'Display Name', 'Job Title', 'Mail'],
        removeNull=True)

    return human_readable, entry_context, members
Esempio n. 5
0
def delete_ticket_command(client, args) -> Tuple[str, dict, dict]:
    """Function which deleted a specific ticket by ticket id.
        Args:
            client : Integretion client which communicates with the api.
            args: Users arguments of the command.
       Returns:
           human readable, context, raw response of this command.
    """
    ticket_id = args.get('ticket_id')
    try:
        response = client.delete_ticket_request(ticket_id)
    except Exception as e:
        raise DemistoException(e)
    if response.get('Result') == 'Success':
        context = {}
        old_context = demisto.dt(demisto.context(),
                                 f'QuestKace.Ticket(val.ID === {ticket_id})')
        if old_context:
            if isinstance(old_context, list):
                old_context = old_context[0]
            old_context['IsDeleted'] = True
            context = {'QuestKace.Ticket(val.ID === obj.ID)': old_context}
        return f'Ticket was deleted successfully. Ticket number {ticket_id}', context, {}
    else:
        raise DemistoException('Error while deleting the ticket.')
Esempio n. 6
0
def configure_job(job_name: str,
                  existing_job: Optional[Dict[str, Any]] = None) -> bool:
    """Configures the job in the XSOAR instance.
    """
    instance_context = demisto.context()
    job_params = existing_job or {}
    is_scheduled = job_params.get('scheduled')

    for job in instance_context.get('ConfigurationSetup', {}).get('Jobs', []):
        if job.get('name') == job_name:
            job_params.update(job)
            break

    if not job_params:
        return False

    if is_scheduled is False:
        job_params['scheduled'] = False

    status, res = execute_command(
        'demisto-api-post',
        {
            'uri': '/jobs',
            'body': job_params
        },
        fail_on_error=False,
    )

    if not status:
        error_message = f'{SCRIPT_NAME} - {res}'
        demisto.debug(error_message)
        return False

    return True
def delete_group_command(client: MsGraphClient,
                         args: Dict) -> Tuple[str, Dict, Dict]:
    """Delete a group by group id and return outputs in Demisto's format

    Args:
        client: Client object with request
        args: Usually demisto.args()

    Returns:
        Outputs.
    """
    group_id = str(args.get('group_id'))
    client.delete_group(group_id)

    # get the group data from the context
    group_data = demisto.dt(
        demisto.context(),
        f'{INTEGRATION_CONTEXT_NAME}(val.ID === "{group_id}")')
    if isinstance(group_data, list):
        group_data = group_data[0]

    # add a field that indicates that the group was deleted
    group_data['Deleted'] = True  # add a field with the members to the group
    entry_context = {
        f'{INTEGRATION_CONTEXT_NAME}(val.ID === obj.ID)': group_data
    }

    human_readable = f'Group: "{group_id}" was deleted successfully.'
    return human_readable, entry_context, NO_OUTPUTS
Esempio n. 8
0
def policy_delete_command(client: AzureWAFClient, **args: Dict[str, str]):
    """
    Gets a policy name and resource group (or taking instance's default)
    and delete the policy from the resource group.
    """
    policy_name = str(args.get('policy_name', ''))
    resource_group_name = str(
        args.get('resource_group_name', client.resource_group_name))

    # policy_path is unique and used as unique id in the product.
    policy_id = f'/{SUBSCRIPTION_PATH.format(client.subscription_id)}/' \
                f'{RESOURCE_PATH.format(resource_group_name)}/{POLICY_PATH}/{policy_name}'
    status = client.delete_policy(policy_name, resource_group_name)
    md = ""
    context = None

    if status.status_code in [200, 202]:
        old_context = demisto.dt(demisto.context(),
                                 f'AzureWAF.Policy(val.id === "{policy_id}")')

        # updating the context with deleted policy.
        if old_context:
            if isinstance(old_context, list):
                old_context = old_context[0]
            old_context['IsDeleted'] = True
            context = {'AzureWAF.Policy(val.id === obj.id)': old_context}

        md = f"Policy {policy_name} was deleted successfully."

    if status.status_code == 204:
        md = f"Policy {policy_name} was not found."

    return CommandResults(outputs=context, readable_output=md)
Esempio n. 9
0
def generate_netcraft_context_with_notes(list_of_notes_contexts):
    all_takedowns_entry_context = demisto.context().get("Netcraft", {}).get(
        "Takedown", {})
    for note_context in list_of_notes_contexts:
        all_takedowns_entry_context = add_note_to_suitable_takedown_in_context(
            note_context, all_takedowns_entry_context)
    return all_takedowns_entry_context
Esempio n. 10
0
def viper_upload_command():
    """
    Command to upload a file to Viper database
    """

    # Get entry id, filename and filepath
    file_entry = demisto.args().get('EntryID')
    filename = demisto.getFilePath(file_entry)['name']
    filepath = demisto.getFilePath(file_entry)['path']

    # Send file to Viper
    response = viper_upload(filepath, filename, file_entry.lower())

    # Update tags if necessary
    if response == 'add tags':
        curr_hash = demisto.context().get('File')[2]['SHA256']
        url_fragment = "project/default/malware/{}/tag/".format(curr_hash)
        curr_tags = [
            result['data']['tag'] for result in http_request(
                'GET', url_fragment, None, None, None)['results']
        ]
        if file_entry not in curr_tags:
            demisto.results("File already in Viper. Updating tags...")
            data = {'tag': file_entry}
            add_tags = http_post(url_fragment, None, data=data)
        else:
            demisto.results(
                "File already in Viper. Viper entry is up to date.")
Esempio n. 11
0
def file_upload_raw(body, file_entry_id, filename_to_upload):
    uri = 'php/fileupload.php'
    if not filename_to_upload:  # first priority for the file name is user's argument
        # second priority for the file name is the file name in the context
        filename_dq = demisto.dt(
            demisto.context(), 'File(val=val.EntryID=="' + file_entry_id + '")=val.Name')
        if filename_dq and filename_dq[0]:
            filename_to_upload = filename_dq
        else:
            # last priority for the file name is demisto's entryID
            filename_to_upload = file_entry_id

    with open(demisto.getFilePath(file_entry_id)['path'], 'rb') as file_to_upload:
        file_up = {'amas_filename': file_to_upload}
        result = http_request(
            uri,
            'post',
            API_HEADERS,
            body,
            '',
            files=file_up,
        )

    if not result['success']:
        return_error('Failed to upload sample due to: ' + result['errorMessage'])
    return result
Esempio n. 12
0
def domain_delete_command(client: Client, args: dict) -> CommandResults:
    """
    :param client: Cisco Umbrella Client for the api request.
    :param args: args from the user for the command.
    :returns (str) confirmation or error regarding deleting a domain.
    """
    response = {}
    domain_name = args.get('name', '')
    domain_id = args.get('id', '')
    if not domain_name and not domain_id:
        raise DemistoException(
            'Both domain name and domain id do not exist, Please supply one of them in order to set the domain to '
            'delete command')
    try:
        response = client.delete_domains(domain_id=domain_id,
                                         domain_name=domain_name)
    except Exception as e:
        # When deleting a domain by id and the id does not exist.
        if any(exp in str(e)
               for exp in ["Domain not in domain list", "Not Found"]):
            return CommandResults(
                readable_output=
                'The domain was not found in the list, Please insert an existing domain name or id.'
            )
    if domain_name:
        curr_context = demisto.dt(
            demisto.context(),
            f'UmbrellaEnforcement.Domains(val.name == "{domain_name}")')
    else:
        curr_context = demisto.dt(
            demisto.context(),
            f'UmbrellaEnforcement.Domains(val.id == "{domain_id}")')

    if curr_context:
        if isinstance(curr_context, list):
            curr_context = curr_context[0]
        curr_context['IsDeleted'] = True
    if response and int(response.status_code) == 204:  # type: ignore
        message = f"{domain_name if domain_name else domain_id} domain was removed from blacklist"
    else:
        # When deleting a domain by name, if name does not exist the returned code is 200 but the response is empty.
        message = f"{domain_name if domain_name else domain_id} domain not in the blacklist or Error"
    return CommandResults(readable_output=message,
                          outputs_prefix='UmbrellaEnforcement.Domains',
                          outputs_key_field='id',
                          outputs=curr_context)
Esempio n. 13
0
def build_grid(context_path: str, keys: List[str], columns: List[str],
               unpack_nested_elements: bool) -> pd.DataFrame:
    """ Build new DateFrame from current context retrieved by DT.
        There are 3 cases:
            1. DT returns dict - In this case we will insert it in the table as key, value in each row.
            2. DT returns list - In this case each entry in the list will represent a row.
            3. DT return unknown obj (str..) - return empty list.

    Args:
        context_path: DT context path.
        keys: Keys to be included
        columns: Grid columns name.
        unpack_nested_elements: True for unpacking nested elements, False otherwise.

    Returns:
        pd.DataFrame: New Table include data from Entry Context
    """
    # Retrieve entry context data
    entry_context_data = demisto.dt(demisto.context(), context_path)
    # Validate entry context structure
    data_type = validate_entry_context(context_path, entry_context_data, keys,
                                       unpack_nested_elements)

    demisto.debug('context object is valid. starting to build the grid.')
    # Building new Grid
    if unpack_nested_elements:
        # Handle entry context as dict, with unpacking of nested elements
        table = pd.DataFrame(
            unpack_all_data_from_dict(entry_context_data, keys, columns))
        table.rename(columns=dict(zip(table.columns, columns)), inplace=True)
    elif data_type == 'list':
        # Handle entry context as list of value
        table = pd.DataFrame(entry_context_data)
        table.rename(columns=dict(zip(table.columns, columns)), inplace=True)
    elif isinstance(entry_context_data, list):
        # Handle entry context as list of dicts
        entry_context_data = [
            filter_dict(item, keys, len(columns))
            for item in entry_context_data
        ]
        table = pd.DataFrame(entry_context_data)
        table.rename(columns=dict(zip(table.columns, columns)), inplace=True)
    elif isinstance(entry_context_data, dict):
        # Handle entry context key-value of primitive types option
        # If the keys arg is * it means we don't know which keys we have in the context - Will create key-value table.
        if keys == ['*']:
            entry_context_data = filter_dict(entry_context_data, keys).items()
            table = pd.DataFrame(entry_context_data, columns=columns[:2])
        else:
            entry_context_data = filter_dict(entry_context_data, keys)
            table = pd.DataFrame([entry_context_data])
            table.rename(columns=dict(zip(table.columns, columns)),
                         inplace=True)

    else:
        table = []

    return table
Esempio n. 14
0
def get_campaign_incident_similarities() -> list:
    """
    Gets all the campaign incident similarities.

    Returns:
        List of all the similarities.
    """
    incidents = demisto.get(demisto.context(), "EmailCampaign.incidents")
    return [incident["similarity"] for incident in incidents]
Esempio n. 15
0
def get_incident_ids() -> list:
    """
    Gets all the campaign incident ids.

    Returns:
        List of all the ids.
    """
    incidents = demisto.get(demisto.context(), "EmailCampaign.incidents")
    return [incident["id"] for incident in incidents]
Esempio n. 16
0
def install_custom_pack(pack_id: str, skip_verify: bool,
                        skip_validation: bool) -> Tuple[bool, str]:
    """Installs a custom pack in the machine.

    Args:
        pack_id (str): The ID of the pack to install.
        skip_verify (bool): If true will skip pack signature validation.
        skip_validation (bool) if true will skip all pack validations.

    Returns:
        - bool. Whether the installation of the pack was successful or not.
        - str. In case of failure, the error message.

    Notes:
        Assumptions: The zipped file is in the war-room, and the context includes the data related to it.

    """
    pack_file_entry_id = ''

    instance_context = demisto.context()
    context_files = instance_context.get('File', [])
    if not isinstance(context_files, list):
        context_files = [context_files]

    for file_in_context in context_files:
        if file_in_context['Name'] == f'{pack_id}.zip':
            pack_file_entry_id = file_in_context['EntryID']
            break

    uri = build_url_parameters(skip_verify=skip_verify,
                               skip_validation=skip_validation)

    if pack_file_entry_id:
        status, res = execute_command(
            'demisto-api-multipart',
            {
                'uri': uri,
                'entryID': pack_file_entry_id
            },
            fail_on_error=False,
        )

        if not status:
            error_message = f'{SCRIPT_NAME} - {res}'
            demisto.debug(error_message)
            return False, f'Issue occurred while installing the pack on the machine.\n{res}'

    else:
        error_message = 'Could not find file entry ID.'
        demisto.debug(f'{SCRIPT_NAME}, "{pack_id}" - {error_message}.')
        return False, error_message

    return True, ''
def get_incidents_ids_from_context() -> list:
    """
    Gets the campaign incident ids.

    Returns:
        List of incident ids.
    """
    relevant_incidents = demisto.get(demisto.context(), 'EmailCampaign.incidents')
    ids = [item.get('id') for item in relevant_incidents]

    if not ids:
        ids = []

    return ids
Esempio n. 18
0
def main():
    try:
        incidents = get_campaign_incidents_from_context()
        fields_to_display = demisto.get(demisto.context(), 'EmailCampaign.fieldsToDisplay')
        if incidents:
            update_incident_with_required_keys(incidents, KEYS_FETCHED_BY_QUERY)
            update_empty_fields()
            readable_output = get_incidents_info_md(incidents, fields_to_display)
        else:
            readable_output = NO_CAMPAIGN_INCIDENTS_MSG

        return_results(CommandResults(readable_output=readable_output))
    except Exception as err:
        return_error(str(err))
Esempio n. 19
0
    def get_file_details(self):
        cmd_res = demisto.executeCommand('getFilePath', {'id': demisto.args().get("entryID")})
        file_res = cmd_res[0]
        if isError(file_res):
            file_res["Contents"] = "Error fetching entryID: " + file_res["Contents"]
            self.res = file_res
        else:  # Got file path:
            self.file_path = file_res.get('Contents').get('path')
            self.file_name = file_res.get('Contents').get('name')
            file = demisto.dt(demisto.context(), "File(val.EntryID === '{}')".format(demisto.args().get('entryID')))
            if isinstance(file, list):
                file = file[0]

            self.file_type = file.get("Type")
Esempio n. 20
0
def get_packs_data_from_context() -> List[Dict[str, str]]:
    """Fetched packs' data from context and formats it to an installable object.

    Returns:
        List[Dict[str, str]]: Installable objects list.
    """
    instance_context = demisto.context()
    context_packs_data = instance_context.get('ConfigurationSetup',
                                              {}).get('MarketplacePacks')

    return [{
        'id': pack['packid'],
        'version': pack['packversion'],
    } for pack in context_packs_data]
Esempio n. 21
0
def main(args):
    incident = demisto.incident()
    custom_fields = incident.get('CustomFields', {})
    email_from = custom_fields.get('emailfrom')
    email_cc = custom_fields.get('emailcc')
    email_to = custom_fields.get('emailto')
    email_subject = custom_fields.get('emailsubject')
    email_html = custom_fields.get('emailhtml', '')
    email_html_image = custom_fields.get('emailhtmlimage')
    attachments = incident.get('attachment', {})
    files = demisto.context().get('File', [])

    if not email_html_image or 'src="cid' in email_html_image:
        if 'src="cid' in email_html:
            entry_id_list = get_entry_id_list(attachments, files)
            html_body = create_email_html(email_html, entry_id_list)
            email_reply = set_email_reply(email_from, email_to, email_cc,
                                          email_subject, html_body,
                                          attachments)
            demisto.executeCommand(
                "setIncident",
                {'customFields': {
                    "emailhtmlimage": email_reply
                }})
            return_results({
                'ContentsFormat': formats['html'],
                'Type': entryTypes['note'],
                'Contents': email_reply,
            })

        else:
            email_reply = set_email_reply(email_from, email_to, email_cc,
                                          email_subject, email_html,
                                          attachments)
            return_results({
                'ContentsFormat': formats['html'],
                'Type': entryTypes['note'],
                'Contents': email_reply
            })

    else:
        return_results({
            'ContentsFormat': formats['html'],
            'Type': entryTypes['note'],
            'Contents': email_html_image
        })
Esempio n. 22
0
def install_custom_pack(pack_id: str) -> bool:
    """Installs a custom pack in the machine.

    Args:
        pack_id (str): The ID of the pack to install.

    Returns:
        bool. Whether the installation of the pack was successful or not.

    Notes:
        Assumptions: The zipped file is in the war-room, and the context includes the data related to it.

    """
    pack_file_entry_id = ''

    instance_context = demisto.context()
    context_files = instance_context.get('File', [])
    if not isinstance(context_files, list):
        context_files = [context_files]

    for file_in_context in context_files:
        if file_in_context['Name'] == f'{pack_id}.zip':
            pack_file_entry_id = file_in_context['EntryID']
            break

    if pack_file_entry_id:
        res = demisto.executeCommand(
            'demisto-api-multipart',
            {
                'uri': '/contentpacks/installed/upload',
                'entryID': pack_file_entry_id
            },
        )

        if is_error(res):
            error_message = f'{SCRIPT_NAME} - {get_error(res)}'
            demisto.debug(error_message)
            return False

    else:
        demisto.debug(
            f'{SCRIPT_NAME} - An error occurred while installing {pack_id}.')
        return False

    return True
Esempio n. 23
0
def main():
    try:
        args = demisto.args()
        # the entry_id argument can be a list of entry ids or a single entry id
        entry_ids = args.get('entry_id', demisto.get(demisto.context(), 'lastCompletedTaskEntries'))
        entry_ids = argToList(entry_ids)

        entries = [demisto.executeCommand('getEntry', {'id': entry_id}) for entry_id in entry_ids]
        error_messages = get_errors(entries)

        return_results(CommandResults(
            readable_output='\n'.join(error_messages),
            outputs_prefix='ErrorEntries',
            outputs=error_messages,
            raw_response=error_messages,
        ))
    except Exception as e:
        return_error(f'Failed to fetch errors for the given entry id(s). Problem: {str(e)}')
Esempio n. 24
0
def template_params():
    """
    Translate the template params if they exist from the context
    """
    actualParams = {}
    paramsStr = demisto.getArg('templateParams')
    if paramsStr:
        try:
            params = json.loads(paramsStr)
        except ValueError as e:
            return_error_mail_sender('Unable to parse templateParams: %s' % (str(e)))
        # Build a simple key/value
        for p in params:
            if params[p].get('value'):
                actualParams[p] = params[p]['value']
            elif params[p].get('key'):
                actualParams[p] = demisto.dt(demisto.context(), params[p]['key'])
    return actualParams
Esempio n. 25
0
def main():
    fields_mapping = {}
    for xdr_field in XDR_INCIDENT_FIELDS:
        if xdr_field in demisto.args() and demisto.args().get(
                xdr_field) is not None:
            custom_field_in_demisto = demisto.args().get(xdr_field)
            fields_mapping[xdr_field] = custom_field_in_demisto

    playbook_to_run = demisto.args().get('playbook_to_run')
    incident_id = demisto.args().get('incident_id')
    first_run = demisto.args().get('first') == 'true'
    interval = int(demisto.args().get('interval'))
    xdr_incident_from_previous_run = demisto.args().get(
        'xdr_incident_from_previous_run')
    xdr_alerts_field = demisto.args().get('xdr_alerts')
    xdr_file_artifacts_field = demisto.args().get('xdr_file_artifacts')
    xdr_network_artifacts_field = demisto.args().get('xdr_network_artifacts')
    verbose = demisto.args().get('verbose') == 'true'

    xdr_incident_markdown_field = demisto.args().get(
        'xdr_incident_markdown_field')  # deprecated
    if xdr_incident_markdown_field:
        # deprecated field
        raise ValueError(
            'Deprecated xdr_incident_markdown_field argument, instead use xdr_alerts, xdr_file_artifacts, '
            'xdr_network_artifacts. For more information follow Demisto documentation.'
        )

    previous_scheduled_task_id = demisto.get(demisto.context(),
                                             'XDRSyncScriptTaskID')
    if first_run and previous_scheduled_task_id:
        if verbose:
            demisto.debug(
                'Stopping previous scheduled task with ID: {}'.format(
                    previous_scheduled_task_id))

        demisto.executeCommand('StopScheduledTask',
                               {'taskID': previous_scheduled_task_id})
        demisto.setContext('XDRSyncScriptTaskID', '')

    xdr_incident_sync(incident_id, fields_mapping, playbook_to_run,
                      xdr_incident_from_previous_run, first_run, interval,
                      xdr_alerts_field, xdr_file_artifacts_field,
                      xdr_network_artifacts_field, verbose)
Esempio n. 26
0
def _handle_existing_outputs(anchor_hash: str, output_key: str, new_hashes_outputs: list):
    context = demisto.get(demisto.context(), f'{output_key}')
    if not context:
        context = []
    elif not isinstance(context, list):
        context = [context]
    context = list(filter(lambda item: item.get('SourceHash') == anchor_hash, context))

    if context:
        context = context[0].get('compared_hashes')

    new_hashes = [current_hash.get('hash') for current_hash in new_hashes_outputs]
    res = []

    for item in context:
        if item.get('hash') not in new_hashes:
            res.append(item)
    res += new_hashes_outputs
    return res
Esempio n. 27
0
def upload_file_command():
    ticket_type = get_table_name(demisto.args().get('ticket_type'))
    ticket_id = demisto.args()['id']
    file_id = demisto.args()['file_id']
    file_name = demisto.args().get('file_name',
                                   demisto.dt(demisto.context(), "File(val.EntryID=='" + file_id + "').Name"))
    file_name = file_name[0] if isinstance(file_name, list) else file_name

    res = upload_file(ticket_id, file_id, file_name, ticket_type)

    if not res or 'result' not in res or not res['result']:
        return_error('Unable to retrieve response')

    hr = {
        'Filename': res['result'].get('file_name'),
        'Download link': res['result'].get('download_link'),
        'System ID': res['result'].get('sys_id')
    }

    context = {
        'ID': ticket_id,
        'File': {}
    }
    context['File']['Filename'] = res['result'].get('file_name')
    context['File']['Link'] = res['result'].get('download_link')
    context['File']['SystemID'] = res['result'].get('sys_id')

    entry = {
        'Type': entryTypes['note'],
        'Contents': res,
        'ContentsFormat': formats['json'],
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('File uploaded successfully', hr),
        'EntryContext': {
            'ServiceNow.Ticket(val.ID===obj.ID)': context,
            'Ticket(val.ID===obj.ID)': context
        }
    }

    return entry
Esempio n. 28
0
def build_grid(context_path: str, keys: List[str],
               columns: List[str]) -> pd.DataFrame:
    """ Build new DateFrame from current context retrieved by DT.
        There is 3 cases:
            1. DT returns dict (list including 1 item only)- In this case we will insert it in the table as key,
            value each row.
            2. DT returns list - In this case each entry in the list will represent a row.
            3. DT return unknown obj (str..) - return empty list.

    Args:
        context_path: DT context path.
        keys: Keys to be included
        columns: Grid columns name.

    Returns:
        pd.DataFrame: New Table include data from Entry Context
    """
    # Retrieve entry context data
    entry_context_data = demisto.dt(demisto.context(), context_path)
    # Validate entry context structure
    validate_entry_context(entry_context_data, keys)
    # Building new Grid
    if len(entry_context_data) > 1:
        # Handle entry context list option
        entry_context_data = [
            filter_dict(item, keys, len(columns))
            for item in entry_context_data
        ]
        table = pd.DataFrame(entry_context_data)
        table.rename(columns=dict(zip(table.columns, columns)), inplace=True)
    elif len(entry_context_data) == 1 and isinstance(entry_context_data[0],
                                                     dict):
        # Handle entry context key-vlaue option
        entry_context_data = filter_dict(entry_context_data[0], keys).items()
        table = pd.DataFrame(entry_context_data, columns=columns[:2])
    else:
        table = []

    return table
Esempio n. 29
0
def main() -> None:

    ORANGE_HTML_STYLE = "color:#FF9000;font-size:250%;>"
    GREEN_HTML_STYLE = "color:#00CD33;font-size:275%;>"
    RED_HTML_STYLE = "color:#FF1744;font-size:275%;>"
    DIV_HTML_STYLE = "display:block;text-align:center;"

    try:
        sonar_total_hits = demisto.context()["Rubrik"]["Sonar"]["totalHits"]

        if not sonar_total_hits:
            html = f"<div style={DIV_HTML_STYLE}><h1 style={GREEN_HTML_STYLE}{str(sonar_total_hits)}</h1></div>"
        else:
            html = f"<div style={DIV_HTML_STYLE}><h1 style={RED_HTML_STYLE}{str(sonar_total_hits)}</h1></div>"

    except KeyError:
        html = f"<div style={DIV_HTML_STYLE}><h1 style={ORANGE_HTML_STYLE}No Results Found</h1></div>"

    demisto.results({
        'ContentsFormat': formats['html'],
        'Type': entryTypes['note'],
        'Contents': html
    })
Esempio n. 30
0
def wait_for_key(args: Dict[str, Any]):
    context_key = args.get('context_key', 'None')

    max_iterations = 10
    try:
        max_iterations = int(args.get('iterations', 10))
    except (ValueError, TypeError):
        return_error('Please provide an integer value for "iterations"')

    demisto_context = demisto.context()
    itr = 0
    done = False
    while not done and itr < max_iterations:
        if demisto_context.get(context_key) is not None:
            done = True
        demisto.executeCommand("Sleep", {"seconds": "1"})
        itr = itr + 1

    if done is False:
        readable_output = f'Could not find "{context_key}" after "{str(itr)}" iterations'
    else:
        readable_output = f'Found "{context_key}" after "{str(itr)}" iterations'

    return CommandResults(readable_output=readable_output)
Esempio n. 31
0
def get_packs_data_from_context():
    """Fetched packs' data from context and formats it to an installable object.
    """
    instance_context = demisto.context()
    context_packs_data = instance_context.get('ContentData')

    if isinstance(context_packs_data, list):

        context_entries = [{
            'packid': pack['packID'],
            'packversion': 'latest',
        } for pack in context_packs_data]

    else:
        context_entries = [{
            'packid': context_packs_data['packID'],
            'packversion': 'latest',
        }]

    return_results(
        CommandResults(
            outputs_prefix='ConfigurationSetup',
            outputs={'MarketplacePacks': context_entries},
        ))
Esempio n. 32
0
def generate_netcraft_context_with_notes(list_of_notes_contexts):
    all_takedowns_entry_context = demisto.context().get("Netcraft", {}).get("Takedown", {})
    for note_context in list_of_notes_contexts:
        all_takedowns_entry_context = add_note_to_suitable_takedown_in_context(note_context,
                                                                               all_takedowns_entry_context)
    return all_takedowns_entry_context