Cyren-Find-Similar-Incidents

Finds similar incidents by Cyren Case ID This automation runs using the default Limited User role, unless you explicitly change the permissions. For more information, see the section about permissions here: - For Cortex XSOAR 6 see https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/6.x/Cortex-XSOAR-Playbook-Design-Guide/Automations - For Cortex XSOAR 8 Cloud see https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8/Cortex-XSOAR-Cloud-Documentation/Create-a-script - For Cortex XSOAR 8.7 On-prem see https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8.7/Cortex-XSOAR-On-prem-Documentation/Create-a-script

python · Cyren Inbox Security

Details

IDCyren-Find-Similar-Incidents
Languagepython
From Version6.0.0
Docker Imagedemisto/python3:3.12.8.3296088
Tagsdedup duplicate incidents dynamic-section

README

Finds similar incidents by Cyren Case ID

Permissions


This automation runs using the default Limited User role, unless you explicitly change the permissions.
For more information, see the section about permissions here: For Cortex XSOAR 6, see the https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/6.x/Cortex-XSOAR-Playbook-Design-Guide/Automations for Cortex XSOAR 8 Cloud, see the https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8/Cortex-XSOAR-Cloud-Documentation/Create-a-script for Cortex XSOAR 8 On-prem, see the https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/8.7/Cortex-XSOAR-On-prem-Documentation/Create-a-script.

Script Data


Name Description
Script Type python3
Tags dedup, duplicate, incidents, dynamic-section
Cortex XSOAR Version 6.0.0

Inputs


Argument Name Description
case_id the case id of incidents to return

Outputs


Path Description Type
cyrenSimilarIncident.raw_id Similar incident ID. string
cyrenIsSimilarIncidentFound Whether a similar incident was found (“true” or “false”). boolean
cyrenSimilarIncident Similar incident. unknown
cyrenSimilarIncident.name Similar incident name. string
cyrenSimilarIncidentList an array if similar incidents Unknown
cyrenSimilarIncidentCsv comma separated raw ids Unknown

Script Example


## Context Example

```json
{
    "isSimilarIncidentFound": false
}

Human Readable Output

No similar incidents have been found.

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401

TIME_FIELD = "created"
MAX_CANDIDATES_IN_LIST = 1000


def get_incidents_by_case(case_id, incident_id):
    # find incidents that are not closed and do not have the same incident id.
    query = f'cyrencaseid="{case_id}" and -cyrenincidentid="{incident_id}"'

    get_incidents_argument = {"query": query, "size": MAX_CANDIDATES_IN_LIST, "sort": "created.desc"}

    res = demisto.executeCommand("getIncidents", get_incidents_argument)
    if res[0]["Type"] == EntryType.ERROR:
        raise NameError(str(res[0]["Contents"]))

    incident_list = res[0]["Contents"]["data"] or []
    return incident_list


def incident_to_record(incident, time_field):
    def parse_time(date_time_str):
        try:
            if date_time_str.find(".") > 0:
                date_time_str = date_time_str[: date_time_str.find(".")]
            if date_time_str.find("+") > 0:
                date_time_str = date_time_str[: date_time_str.find("+")]
            return date_time_str.replace("T", " ")
        except Exception:
            return date_time_str

    time = parse_time(incident[time_field])
    return {
        "id": "[{}](#/Details/{})".format(incident["id"], incident["id"]),
        "raw_id": incident["id"],
        "cyren_incident_id": incident["CustomFields"]["cyrenincidentid"],
        "name": incident["name"],
        "closed_time": parse_time(incident["closed"]) if incident["closed"] != "0001-01-01T00:00:00Z" else "",
        "time": time,
    }


def did_not_find_duplicates():
    context = {"isSimilarIncidentFound": False}
    demisto.results(
        {
            "ContentsFormat": formats["markdown"],
            "Type": EntryType.NOTE,
            "Contents": "No similar incidents have been found.",
            "EntryContext": context,
        }
    )
    sys.exit(0)


def pretty_title(s):
    s = s.replace("_", " ")
    return s.title()


def main():
    try:
        # case id from parameters
        case_id = demisto.args().get("case_id")
        incident_id = ""
        # case id from current incident context
        if not case_id:
            case_id = demisto.get(demisto.incidents()[0], "CustomFields.cyrencaseid")
        if not case_id:
            return did_not_find_duplicates()

        # don't include this incident id in list
        incident_id = demisto.get(demisto.incidents()[0], "CustomFields.cyrenincidentid")

        similar_incidents = get_incidents_by_case(case_id, incident_id)

        if len(similar_incidents or []) > 0:
            similar_incidents_rows = [incident_to_record(x, TIME_FIELD) for x in similar_incidents]
            similar_incidents_rows = sorted(similar_incidents_rows, key=lambda x: (x["time"], x["id"]))

            similar_incident_csv = ""
            for i in range(len(similar_incidents_rows)):
                similar_incident_csv = similar_incident_csv + ", " + similar_incidents_rows[i]["raw_id"]

            # truncate rows
            similar_incidents_rows = similar_incidents_rows[:MAX_CANDIDATES_IN_LIST]
            context = {
                "cyrenSimilarIncidentList": similar_incidents_rows,
                "cyrenSimilarIncidentCsv": similar_incident_csv,
                "cyrenSimilarIncident": similar_incidents_rows[0],
                "cyrenIsSimilarIncidentFound": True,
            }

            # build printed output
            markdown_result = "**Number of Incidents:** " + str(len(similar_incidents_rows)) + "\n"
            markdown_result = markdown_result + tableToMarkdown(
                "", similar_incidents_rows, ["time", "id", "cyren_incident_id", "name"], pretty_title
            )

            return {
                "ContentsFormat": formats["markdown"],
                "Type": EntryType.NOTE,
                "Contents": markdown_result,
                "EntryContext": context,
            }
        else:
            did_not_find_duplicates()

    except Exception as e:
        return_error(f"Failed to execute CyrenFindSimilarIncidents. Error: {e!s}")


if __name__ in ["__main__", "__builtin__", "builtins"]:
    entry = main()
    return_results(entry)