Beispiel #1
0
def return_involved_incidents_entry(incidents_df, indicators_df, fields_to_display):
    incidents_df['Id'] = incidents_df['id'].apply(lambda x: "[%s](#/Details/%s)" % (x, x))
    incidents_df = incidents_df.sort_values('created', ascending=False).reset_index(drop=True)
    incidents_df['created_dt'] = incidents_df['created'].apply(lambda x: dateutil.parser.parse(x))  # type: ignore
    incidents_df['Created'] = incidents_df['created_dt'].apply(lambda x: x.strftime("%B %d, %Y"))
    incidents_df['similarity'] = incidents_df['similarity'].fillna(1)
    incidents_df['similarity'] = incidents_df['similarity'].apply(lambda x: '{:.1f}%'.format(x * 100))
    current_incident_id = demisto.incident()['id']
    incidents_df['DBot Score'] = incidents_df['id'].apply(lambda id_: get_reputation(id_, indicators_df))
    # add a mark at current incident, at its similarity cell
    incidents_df['similarity'] = incidents_df.apply(
        lambda x: '{} (current)'.format(x['similarity']) if x['id'] == current_incident_id else x['similarity'], axis=1)
    incidents_df['status'] = incidents_df['status'].apply(lambda x: STATUS_DICT[x] if x in STATUS_DICT else '')
    incidents_df.rename({
        'name': 'Name',
        FROM_FIELD: 'Email From',
        'similarity': 'Similarity to Current Incident',
        'status': 'Status'},
        axis=1, inplace=True)
    incidents_headers = ['Id', 'Created', 'Name', 'Status', 'Email From', 'DBot Score',
                         'Similarity to Current Incident']
    if fields_to_display is not None:
        fields_to_display = [f for f in fields_to_display if f in incidents_df.columns]
        incidents_df[fields_to_display] = incidents_df[fields_to_display].fillna('')
        fields_to_display = [f for f in fields_to_display if len(get_non_na_empty_values(incidents_df, f)) > 0]
        incidents_headers += fields_to_display
    hr = '\n\n' + tableToMarkdown('Involved Incidents', incidents_df[incidents_headers].to_dict(orient='records'),
                                  headers=incidents_headers)
    return_outputs_custom(hr, tag='incidents')
Beispiel #2
0
def main():
    incident = demisto.incident()
    custom_fields = incident.get('CustomFields', {})
    identity_results_str = custom_fields.get('identitytable', {})
    identity_results = json.loads(identity_results_str)

    if not identity_results:
        return CommandResults()

    if isinstance(identity_results, list):
        events_arr = []
        for event in identity_results:
            events_arr.append(event)
        markdown = tableToMarkdown("",
                                   events_arr,
                                   headers=events_arr[0].keys())

    else:
        markdown = tableToMarkdown("", identity_results)

    return {
        'ContentsFormat': formats['markdown'],
        'Type': entryTypes['note'],
        'Contents': markdown
    }
def main():
    incident = demisto.incident()
    if not incident:
        raise ValueError(
            "Error - demisto.incident() expected to return current incident "
            "from context but returned None")
    custom_fields = incident.get('CustomFields', {})
    identity_results_str = custom_fields.get('identitytable', {})
    is_successful = custom_fields.get('successfulidentityenrichment', '')
    if is_successful == 'false':
        return CommandResults(readable_output='Identity enrichment failed.')

    identity_results = json.loads(identity_results_str)

    if not identity_results:
        return CommandResults(
            readable_output='No users were found in the notable.')

    if isinstance(identity_results, list):
        events_arr = []
        for event in identity_results:
            events_arr.append(event)
        markdown = tableToMarkdown("",
                                   events_arr,
                                   headers=events_arr[0].keys())

    else:
        markdown = tableToMarkdown("", identity_results)

    return {
        'ContentsFormat': formats['markdown'],
        'Type': entryTypes['note'],
        'Contents': markdown
    }
def main():
    try:
        incident = demisto.incident()
        custom_fields = incident.get('CustomFields', {})
        fetched = custom_fields.get('numberoffetchedevents',
                                    0)  # define which incident field to use
        total = custom_fields.get('numberofeventsinoffense',
                                  0)  # define which incident field to use

        if fetched == 0:
            message = 'The offense contains Events but non were fetched. ' \
                      'Event fetching can be configured in the integration instance settings.'
        else:
            message = 'Events details on this page are based on the fetched events.'

        html = HTML_TEMPLATE.format(fetched=fetched,
                                    total=total,
                                    message=message)

        return {
            'ContentsFormat': 'html',
            'Type': entryTypes['note'],
            'Contents': html
        }

    except Exception as exp:
        return_error('could not parse QRadar offense', error=exp)
def main():
    current_incident_id = demisto.args().get('incidentID')
    if current_incident_id is None:
        incident = demisto.incident()
        current_incident_id = incident['id']
    related_incidents_ids = demisto.args().get('relatedIncidentsIDs', [])
    if type(related_incidents_ids) is not list:
        related_incidents_ids = related_incidents_ids.split(",")
        related_incidents_ids = [x for x in related_incidents_ids if x]
    indicators = demisto.args().get('indicators', [])

    if len(indicators) and len(related_incidents_ids) == 0:
        return_error("No related incidents or indicators specified")

    canvas, connections = generate_canvas(current_incident_id,
                                          related_incidents_ids, indicators)
    override = demisto.args().get('overrideUserCanvas') == 'true'
    res = demisto.executeCommand(
        'drawCanvas', {
            'canvas': canvas,
            'canvasLinks': connections,
            'id': current_incident_id,
            'overrideUserCanvas': override
        })
    if res is None:
        return_error("Unexpected error")
    elif is_error(res):
        return_error(get_error(res))
    else:
        hr = "### Check the incidents and indicators layout on the [canvas](#/Canvas/{0})".format(
            current_incident_id)
        return_outputs(hr)
def create_context_for_campaign_details(campaign_found=False,
                                        incidents_df=None):
    if not campaign_found:
        return {
            'isCampaignFound': campaign_found,
        }
    else:
        incident_id = demisto.incident()['id']
        incidents_df['recipients'] = incidents_df.apply(
            lambda row: get_recipients(row), axis=1)
        incidents_df['recipientsdomain'] = incidents_df.apply(
            lambda row: extract_domain_from_recipients(row), axis=1)
        context_keys = [
            'id', 'similarity', FROM_FIELD, FROM_DOMAIN_FIELD, 'recipients',
            'recipientsdomain'
        ]
        incident_df = incidents_df[
            context_keys]  # lgtm [py/hash-unhashable-value]
        incident_df = incident_df[incident_df['id'] != incident_id]
        incident_df.rename({FROM_DOMAIN_FIELD: 'emailfromdomain'},
                           axis=1,
                           inplace=True)
        incidents_context = incident_df.fillna(1).to_dict(orient='records')
        return {
            'isCampaignFound':
            campaign_found,
            'involvedIncidentsCount':
            len(incidents_df) if incidents_df is not None else 0,
            'incidents':
            incidents_context
        }
def get_incident_owners(incident_ids) -> list:
    """
    Gets the campaign incident owners by their ids.

    Args:
        incident_ids: All the campaign incident ids.

    Returns:
        List of the incident owners.
    """

    res = demisto.executeCommand(
        'GetIncidentsByQuery',
        {'query': "id:({})".format(' '.join(incident_ids))})

    if isError(res):
        return_error(
            f'Error occurred while trying to get incidents by query: {get_error(res)}'
        )

    incidents_from_query = json.loads(res[0]['Contents'])

    incident_owners = set(
        [incident['owner'] for incident in incidents_from_query])
    incident_owners.add(
        demisto.incident()["owner"])  # Add the campaign incident owner
    incident_owners_res = list(filter(lambda x: x, incident_owners))

    return incident_owners_res
Beispiel #8
0
def create_context_for_campaign_details(campaign_found=False, incidents_df=None,
                                        additional_context_fields: list = None):
    if not campaign_found:
        return {
            'isCampaignFound': campaign_found,
        }
    else:
        incident_id = demisto.incident()['id']
        incidents_df['recipients'] = incidents_df.apply(lambda row: get_recipients(row), axis=1)
        incidents_df['recipientsdomain'] = incidents_df.apply(lambda row: extract_domain_from_recipients(row), axis=1)
        context_keys = {'id', 'similarity', FROM_FIELD, FROM_DOMAIN_FIELD, 'recipients', 'recipientsdomain'}
        invalid_context_keys = set()
        if additional_context_fields is not None:
            for key in additional_context_fields:
                if key in incidents_df.columns:
                    context_keys.add(key)
                else:
                    invalid_context_keys.add(key)

        if invalid_context_keys:
            return_warning(INVALID_KEY_WARNING.format(fields=invalid_context_keys))

        incident_df = incidents_df[context_keys]  # lgtm [py/hash-unhashable-value]
        if not SELF_IN_CONTEXT:
            incident_df = incident_df[incident_df['id'] != incident_id]

        incident_df.rename({FROM_DOMAIN_FIELD: 'emailfromdomain'}, axis=1, inplace=True)
        incidents_context = incident_df.fillna(1).to_dict(orient='records')
        return {
            'isCampaignFound': campaign_found,
            'involvedIncidentsCount': len(incidents_df) if incidents_df is not None else 0,
            INCIDENTS_CONTEXT_TD: incidents_context
        }
Beispiel #9
0
    def merge_contexts(self, current_incident_data: dict,
                       campaign_data: dict) -> dict:
        """
        This will update the existing incident's campaign data with the rest of the campaign data,
        according to the following logic:
        If we have a new campaign, copy the all current incident's campaign context to campaign.
        If we have an existing campaign - if the current incident is new, add the new incident to the campaign.
            Also, update other campaign incident's similarity to match the new one.
        """
        if not campaign_data:
            demisto.debug(
                "Creating new Campaign with the current incident data.")
            return current_incident_data

        if self.is_incident_new_in_campaign(demisto.incident()["id"],
                                            campaign_data):
            demisto.debug(
                "Adding current incident as new incident to Campaign.")

            self.add_current_incident_to_campaign(current_incident_data,
                                                  campaign_data)
            self.update_similarity_to_last_incident(
                current_incident_data.get('incidents', []))
            return campaign_data

        else:
            demisto.debug("Current incident already exists in Campaign.")

            return campaign_data
Beispiel #10
0
def main():
    args = demisto.args()
    command_args = {'alert_status': None, 'alert_id': None, 'aggregate_alert_id': None}
    incident = demisto.incident()

    alert_status = args['new']
    alert_status = alert_status.lower().replace(' ', '_')
    command_args['alert_status'] = alert_status

    labels = incident.get('labels', [])
    for label in labels:
        if label.get('type') == 'id':
            command_args['alert_id'] = label.get('value')
        if label.get('type') == 'aggregate_alert_id':
            command_args['aggregate_alert_id'] = label.get('value')

    demisto.info(
        "Update status: alert id - {}, aggregate_alert_id - {}, new status - {}".format(
            command_args.get('alert_id', ''),
            command_args.get('aggregate_alert_id', ''),
            alert_status))
    res = demisto.executeCommand("cybersixgill-update-alert-status", command_args)

    if isError(res[0]):
        return_error('Failed to update Actionable alert status - {}'.format(res[0]['Contents']))
    else:
        demisto.results("Actionable Alert Status Updated successfully.")
Beispiel #11
0
def main():
    try:
        incident = demisto.incident()
        custom_fields = incident.get('CustomFields', {})
        last_mirror_in_time = custom_fields.get('lastmirroredintime', None)
        message = custom_fields.get('incomingmirrorerror', '')

        if message == '':
            status = 'Not Started'
        elif message == 'Mirroring events has reached events limit in this incident.':
            status = 'Completed and Stopped'
        elif message == 'All available events in the offense were mirrored.':
            status = 'Completed'
        elif message == 'In queue.':
            status = 'In Progress'
        else:
            status = 'Failure'

        html = HTML_TEMPLATE.format(status=status,
                                    message=message,
                                    last_mirror_in_time=last_mirror_in_time)

        return {
            'ContentsFormat': 'html',
            'Type': entryTypes['note'],
            'Contents': html
        }

    except Exception as exp:
        return_error('could not parse QRadar offense', error=exp)
def perform_add_to_campaign(ids, action):
    demisto.debug('starting add to campaign')
    campaign_id = demisto.incident()['id']
    campaign_incident_context = demisto.executeCommand('getContext', {'id': campaign_id})
    demisto.debug(f'got incident context: {campaign_incident_context}')

    if isError(campaign_incident_context):
        return_error(COMMAND_ERROR_MSG.format(action=action, ids=','.join(ids),
                                              error=get_error(campaign_incident_context)))

    incident_context = demisto.dt(campaign_incident_context, 'Contents.context.EmailCampaign.incidents')
    if isinstance(incident_context, dict) or isinstance(incident_context, str):
        incident_context = [incident_context]

    for incident_id in ids:
        search_path = f'Contents.context.EmailCampaign.LowerSimilarityIncidents(val.id=={incident_id})'
        similar_incident_data = demisto.dt(campaign_incident_context, search_path)

        if similar_incident_data:
            similar_incident_data = similar_incident_data[0]
            _add_campaign_to_incident(incident_id, campaign_id)

            # Add the incident to context under "incidents":
            incident_context.append(similar_incident_data)

    _remove_incident_from_lower_similarity_context(campaign_incident_context, ids)

    res = demisto.executeCommand('SetByIncidentId', {'key': 'EmailCampaign.incidents',
                                                     'value': incident_context})
    if is_error(res):
        return_error('Failed to change current context. Error details:\n{}'.format(get_error(res)))

    return COMMAND_SUCCESS.format(action=action, ids=','.join(ids))
Beispiel #13
0
def main():
    try:
        incident = demisto.incident()
        magnitude = incident.get('CustomFields', {}).get(
            'magnitudeoffense', 0)  # define which incident field to use

        if 8 <= magnitude <= 10:
            magnitude = str(magnitude)
            html = "<h1 style='color:#D13C3C;text-align:center;'>" + magnitude + "</h1>"

        elif 4 <= magnitude <= 7:
            magnitude = str(magnitude)
            html = "<h1 style='color:#D17D00;text-align:center;'>" + magnitude + "</h1>"

        else:
            magnitude = str(magnitude)
            html = "<h1 style='color:#1DB846;text-align:center;'>" + magnitude + "</h1>"

        return {
            'ContentsFormat': formats['html'],
            'Type': entryTypes['note'],
            'Contents': html
        }

    except Exception as exp:
        return_error('could not parse QRadar assets', error=exp)
def main():
    try:
        incident = demisto.incident()
        assets = incident.get('CustomFields', {}).get('assettable', {})

        if not assets:
            return ''

        if not isinstance(assets, dict):
            assets = json.loads(assets)

        if not isinstance(assets, list):
            assets = [assets]

        for asset in assets:
            if "interfaces" in asset:
                if isinstance(asset["interfaces"], str):
                    asset["interfaces"] = json.loads(asset["interfaces"])
                # using yaml to prettify the output of the field
                asset["interfaces"] = yaml.dump(asset["interfaces"])

        markdown = tableToMarkdown("Asset Table", assets)
        return {
            'ContentsFormat': formats['markdown'],
            'Type': entryTypes['note'],
            'Contents': markdown
        }

    except Exception as exp:
        return_error('could not parse QRadar assets', error=exp)
Beispiel #15
0
def rubrik_radar_analysis_status_command(client: Client, args: Dict[str, Any]) -> CommandResults:
    incident = demisto.incident().get("CustomFields")

    # activitySeriesId is an optional value for the command. When not set,
    # look up the value in the incident custom fields
    activitySeriesId = args.get('activitySeriesId', None)
    if not activitySeriesId:
        try:
            activitySeriesId = incident.get("rubrikpolarisactivityseriesid")
        except AttributeError as e:
            # if still not found return an error message about it being
            # required
            return_error(
                message="The activitySeriesId value is required. Either manually provide or run this "
                        "command in a 'Rubrik Radar Anomaly' incident where it will automatically looked "
                        "up using the incident context.",
                error=e)

    operation_name = f"{OPERATION_NAME_PREFIX}AnomalyEventSeriesDetailsQuery"

    query = """query %s($activitySeriesId: UUID!, $clusterUuid: UUID!) {
                    activitySeries(activitySeriesId: $activitySeriesId, clusterUuid: $clusterUuid) {
                        activityConnection {
                            nodes {
                                    id
                                    message
                                    time
                            }
                        }
                        progress
                        lastUpdated
                        lastActivityStatus
                    }
                }
                    """ % operation_name

    variables = {
        "clusterUuid": incident.get("rubrikpolariscdmclusterid"),
        "activitySeriesId": activitySeriesId
    }

    radar_update_events = client.gql_query(operation_name, query, variables, False)

    context = {
        "ClusterID": incident.get("rubrikpolariscdmclusterid"),
        "ActivitySeriesId": activitySeriesId,
        "Message": radar_update_events["data"]["activitySeries"]["activityConnection"]["nodes"]
    }

    if radar_update_events["data"]["activitySeries"]["lastActivityStatus"] == "Success":
        context["EventComplete"] = "True"
    else:
        context["EventComplete"] = "False"

    return CommandResults(
        outputs_prefix='Rubrik.Radar',
        outputs_key_field='ActivitySeriesId',
        outputs=context
    )
Beispiel #16
0
def get_pcap() -> Dict[str, Any]:
    alert_id = demisto.incident()['CustomFields'].get('alertid')
    if not alert_id:
        return_error(
            'Forescout EyeInspect alert ID is missing inside the incident.')

    return demisto.executeCommand('forescout-ei-alert-pcap-get',
                                  {'alert_id': alert_id})
def associate_to_current_incident(indicators: List[Dict[str, str]]):
    incident_id = demisto.incident()['id']
    execute_command(
        'associateIndicatorsToIncident',
        {
            'incidentId': incident_id,
            'indicatorsValues': list(map(lambda x: x['value'], indicators))
        }
    )
def set_incident_owners(incident_ids, action, user_name):

    incident_ids.append(demisto.incident()["id"])

    for incident_id in incident_ids:
        res = demisto.executeCommand("setIncident", {"id": incident_id, "owner": user_name})

        if isError(res):
            return_error(COMMAND_ERROR_MSG.format(action=action, ids=','.join(incident_ids), error=get_error(res)))
def evidence_dynamic_section(args: Dict[str, Any]) -> CommandResults:
    incident = demisto.incident()
    custom_fields = incident.get('CustomFields', {})

    latest_evidence = custom_fields.get('expanselatestevidence', None)
    if latest_evidence is None:
        latest_evidence = "*No Latest Evidence*\n"
    else:
        latest_evidence = convert_to_markdown(json.loads(latest_evidence))

    return CommandResults(readable_output=latest_evidence)
Beispiel #20
0
def main(args):
    incident = demisto.incident()
    account_name = incident.get('account')
    account_name = f"acc_{account_name}/" if account_name != "" else ""

    is_widget = argToBoolean(args.get('isWidget', True))
    if is_widget is True:
        workers = demisto.executeCommand(
            "demisto-api-get",
            {"uri": f"{account_name}workers/status"})[0]['Contents']

        if not workers['response']['ProcessInfo']:
            table = [{'Details': '-', 'Duration': '-', 'StartedAt': '-'}]
        else:
            table = workers['response']['ProcessInfo']
            nano_to_secs(table)
            format_time(table)
            format_details(table)
        md = tableToMarkdown('Workers Status',
                             table,
                             headers=[
                                 'InvestigationID', 'PlaybookName', 'TaskID',
                                 'TaskName', 'StartTime', 'Duration'
                             ])

        dmst_entry = {
            'Type': entryTypes['note'],
            'Contents': md,
            'ContentsFormat': formats['markdown'],
            'HumanReadable': md,
            'ReadableContentsFormat': formats['markdown'],
            'EntryContext': {
                'workers': table
            }
        }

        return dmst_entry
    else:
        workers = demisto.executeCommand(
            "demisto-api-get", {"uri": "/workers/status"})[0]['Contents']
        demisto.executeCommand(
            "setIncident", {
                'healthcheckworkerstotal': workers['response']['Total'],
                'healthcheckworkersbusy': workers['response']['Busy']
            })
        add_actions = analyze_data(workers['response'])

        results = CommandResults(readable_output="HealthCheckWorkers Done",
                                 outputs_prefix="HealthCheck.ActionableItems",
                                 outputs=add_actions)

    return results
Beispiel #21
0
def main():
    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')
    attachments = incident.get('attachment', [])
    email_latest_message = custom_fields.get('emaillatestmessage')

    try:
        email_related_incident_code = email_subject.split('<')[1].split('>')[0]
        email_original_subject = email_subject.split('<')[-1].split('>')[1]
        email_related_incident = get_email_related_incident_id(
            email_related_incident_code, email_original_subject)
        update_latest_message_field(email_related_incident,
                                    email_latest_message)
        query = f"id:{email_related_incident}"
        incident_details = get_incident_by_query(query)[0]
        check_incident_status(incident_details, email_related_incident)
        get_attachments_using_instance(email_related_incident,
                                       incident.get('labels'))

        # Adding a 5 seconds sleep in order to wait for all the attachments to get uploaded to the server.
        time.sleep(5)
        files = get_incident_related_files(email_related_incident)
        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,
                                      html_body, attachments)
        add_entries(email_reply, email_related_incident)
        # False - to not create new incident
        demisto.results(False)

    except (IndexError, ValueError, DemistoException) as e:
        demisto.executeCommand(
            'setIncident', {
                'id': incident.get('id'),
                'customFields': {
                    'emailgeneratedcode': get_unique_code()
                }
            })
        # True - For creating new incident
        demisto.results(True)
        if type(e).__name__ == 'IndexError':
            demisto.debug(
                'No related incident was found. A new incident was created.')
        else:
            demisto.debug(f"A new incident was created. Reason: \n {e}")
def refresh_issue_assets_command(args: Dict[str, Any]) -> CommandResults:
    incident = demisto.incident()
    custom_fields = incident.get('CustomFields', {})
    assets = custom_fields.get('expanseasset', [])

    for asset in assets:
        asset_type = asset.get('assettype')
        asset_key = asset.get('assetkey')

        if asset_type == 'Domain':
            new_asset = demisto.executeCommand('expanse-get-domain',
                                               {"domain": asset_key})
        elif asset_type == 'IpRange':
            new_asset = demisto.executeCommand('expanse-get-iprange', {
                "id": asset_key,
                "include": "annotations"
            })
        elif asset_type == 'Certificate':
            new_asset = demisto.executeCommand('expanse-get-certificate',
                                               {"md5_hash": asset_key})
        elif asset_type == 'CloudResource':
            new_asset = demisto.executeCommand('expanse-get-cloud-resource',
                                               {"id": asset_key})
        else:
            # Unknown asset type, ignore.
            continue

        if isinstance(new_asset, list):
            for na in new_asset:
                if isinstance(na, dict) and 'Contents' in na:
                    contents = na.get('Contents')
                    break
        if not contents:
            continue

        if isinstance(contents, list):
            if len(contents) == 0:
                continue
            contents = contents[0]

        if not isinstance(contents, dict):
            continue

        if (annotations := contents.get('annotations', None)) and isinstance(
                annotations, dict):
            if (tags := annotations.get('tags', None)) and isinstance(
                    tags, list) and len(tags) > 0:
                asset['tags'] = '\n'.join(t['name'] for t in tags
                                          if 'name' in t)
def extract_feedback_information():
    feedback_field = get_value_from_context(key="Arcanna.FeedbackField")
    if type(feedback_field) == list and len(feedback_field) > 0:
        feedback_field = feedback_field[0]

    if not feedback_field:
        raise Exception("Failed to get value for Arcanna closing field")

    # Get Values from incident
    feedback_field_value = demisto.incident().get(feedback_field, None)
    if not feedback_field_value:
        # if closing field value is Empty try to get it from Args as a fallback
        feedback_field_value = demisto.args().get(feedback_field, None)

    return feedback_field, feedback_field_value
Beispiel #24
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
        })
def get_duration_html():
    try:
        incident_id = demisto.incident().get('id', {})
        context = demisto.executeCommand("getContext", {'id': incident_id})
        first_date = demisto.get(context[0]['Contents']['context'],
                                 "EmailCampaign.firstIncidentDate")

        if not first_date:
            raise FieldNotFound()
        if isinstance(first_date, list):
            first_date = first_date[-1]

        now = datetime.now().replace(tzinfo=utc)
        parsed_first_date: datetime = dateutil.parser.isoparse(
            first_date).replace(tzinfo=utc)
        diff = now - parsed_first_date

        return f"""
                <table>
                <tr>
                <th style="font-size: 25px;">&#128345;</th>
                <th style="font-size: 30px;">{diff.days}</th>
                <th style="font-size: 30px;">:</th>
                <th style="font-size: 30px;">{(diff.seconds // 3600) % 24}</th>
                <th style="font-size: 30px;">:</th>
                <th style="font-size: 30px;">{(diff.seconds // 60) % 60}</th>
                </tr>
                <tr>
                <td style="font-size: 15px; text-align: center"></td>
                <td style="font-size: 15px; text-align: center">Days</td>
                <td style="font-size: 15px; text-align: center"></td>
                <td style="font-size: 15px; text-align: center">Hours</td>
                <td style="font-size: 15px; text-align: center"></td>
                <td style="font-size: 15px; text-align: center">Minutes</td>
                </tr>
                </table>
        """

    except FieldNotFound:
        return '<div style="text-align: center;">Duration is not available.</div>'
    except Exception as e:
        demisto.error(traceback.format_exc())
        return_error(f"Error calculating duration\n{str(e)}")
Beispiel #26
0
def get_duration_html():
    try:
        incident_id = demisto.incident().get('id', {})
        context = demisto.executeCommand("getContext", {'id': incident_id})
        first_date = demisto.get(context[0]['Contents']['context'],
                                 "EmailCampaign.firstIncidentDate")

        if not first_date:
            raise FieldNotFound()
        if isinstance(first_date, list):
            first_date = first_date[-1]

        now = datetime.now().replace(tzinfo=utc)
        parsed_first_date: datetime = dateutil.parser.isoparse(
            first_date).replace(tzinfo=utc)
        diff = now - parsed_first_date

        return f"""
                    <div class="demisto-duration vertical-strech">
                        <div class="duration-widget">
                            <div class="grid-container">
                                <div class="duration-icon"><i class="wait icon home"></i></div>
                                <div class="days-number">{diff.days}</div>
                                <div class="colon center aligned">:</div>
                                <div class="hours-number">{(diff.seconds // 3600) % 24}</div>
                                <div class="colon-2 center aligned">:</div>
                                <div class="one column wide minutes-number">{(diff.seconds // 60) % 60}</div>
                                <div class="days-label time-unit title-h5 opacity-description">DAYS</div>
                                <div class="hours-label time-unit title-h5 opacity-description">HOURS</div>
                                <div class="minutes-label time-unit title-h5 opacity-description">MIN</div>
                            </div>
                        </div>
                    </div>

    """
    except FieldNotFound:
        return_error(
            "Can't find firstIncidentDate in context, please run FindEmailCampaign"
        )
    except Exception as e:
        demisto.error(traceback.format_exc())
        return_error(f"Error calculating duration\n{str(e)}")
Beispiel #27
0
def main():
    try:
        incident = demisto.incident()
        events = incident.get('CustomFields', {}).get('events', {})
        if not events:
            return CommandResults()
        title = f'Offense Events (Showing first {MAX_EVENTS})'
        if isinstance(events, list):
            events_arr = []
            for event in events:
                events_arr.append(json.loads(event))
            markdown = tableToMarkdown(title,
                                       events_arr[:MAX_EVENTS],
                                       headers=events_arr[0].keys())
        else:
            markdown = tableToMarkdown(title, json.loads(events)[:MAX_EVENTS])

        return CommandResults(readable_output=markdown)
    except Exception as exp:
        return_error('could not parse QRadar events', error=exp)
Beispiel #28
0
def get_current_table(grid_id: str) -> pd.DataFrame:
    """ Get current Data from the grid

    Args:
        grid_id: Grid ID to retrieve data from.

    Returns:
        DataFrame: Existing grid data.
    """
    custom_fields = demisto.incident().get("CustomFields", {})
    if grid_id not in custom_fields:
        raise ValueError(
            f"The following grid id was not found: {grid_id}. Please make sure you entered the correct "
            f"incident type with the \"Machine name\" as it appears in the incident field editor in "
            f"Settings->Advanced ->Fields (Incident). Also make sure that this value appears in the "
            f"incident Context Data under incident - if not then please consult with support."
        )

    current_table: Optional[List[dict]] = custom_fields.get(grid_id)

    return pd.DataFrame(current_table)
Beispiel #29
0
def main():
    incident = demisto.incident()
    incident_id = incident.get('id')

    email_threads = fetch_email_threads(incident_id)
    if email_threads:
        thread_summary_rows = format_threads(email_threads)
    else:
        return_results({
            'ContentsFormat': EntryFormat.HTML,
            'Type': EntryType.NOTE,
            'Contents': no_entries_message
        })
        return None

    demisto.results({
        'ContentsFormat': EntryFormat.TABLE,
        'Type': EntryType.NOTE,
        'Contents': thread_summary_rows,
        'HumanReadable': thread_summary_rows
    })
Beispiel #30
0
def main():
    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')
    attachments = incident.get('attachment', [])
    email_latest_message = custom_fields.get('emaillatestmessage')

    try:
        email_related_incident = email_subject.split('#')[1].split()[0]
        update_latest_message_field(email_related_incident,
                                    email_latest_message)
        query = f"id:{email_related_incident}"
        incident_details = get_incident_by_query(query)
        check_incident_status(incident_details, email_related_incident)
        get_attachments_using_instance(email_related_incident,
                                       incident.get('labels'))

        # Adding a 5 seconds sleep in order to wait for all the attachments to get uploaded to the server.
        time.sleep(5)
        files = get_incident_related_files(email_related_incident)
        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,
                                      html_body, attachments)
        add_entries(email_reply, email_related_incident)
        # False - to not create new incident
        demisto.results(False)

    except (IndexError, ValueError, DemistoException) as e:
        # True - For creating new incident
        demisto.results(True)
        return_error(
            f"The PreprocessEmail script has encountered an error:\n {e} \nA new incidents was created."
        )