SendEmailToManager
Send an approval email to the manager of the employee with the given email allowing the manager to reply directly into the incident.
python · Active Directory Query
Source
import textwrap from string import Template import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 from CommonServerUserPython import * def find_additional_incident_info(incident: dict) -> dict: additional_info = {} if incident.get("labels"): for label in incident["labels"]: if label["type"] == "Email/from": additional_info["employee_email"] = label["value"].lower() if incident.get("name"): additional_info["incident_subject"] = incident["name"] if incident.get("details"): additional_info["employee_request"] = incident["details"] return additional_info def find_additional_ad_info(email: str, manager_attribute: str) -> dict: additional_info = {} filter_str = rf"(&(objectClass=user)(mail={email}))" response = demisto.executeCommand("ad-search", {"filter": filter_str, "attributes": "displayName," + manager_attribute}) if response and isError(response[0]): demisto.results(response) sys.exit(0) if not (type(response) is list and type(response[0].get("Contents")) is list and type(response[0]["Contents"][0]) is dict): demisto.results("Unable to find manager email.") sys.exit(0) data = response[0]["Contents"][0] if data.get("manager_attribute") and type(data["manager_attribute"]) is list: additional_info["manager_dn"] = data[manager_attribute][0] # This was added as the json structure returned from the AD search during testing # seems to be different from the original. elif ( data.get("attributes") and data["attributes"].get(manager_attribute) and type(data["attributes"][manager_attribute]) is list ): additional_info["manager_dn"] = data["attributes"][manager_attribute][0] else: demisto.results("Unable to find manager email.") sys.exit(0) if data.get("displayName") and type(data["displayName"]) is list: additional_info["employee_name"] = data["displayName"][0] # This was added as the json structure returned from the AD search during testing # seems to be different from the original. elif data.get("attributes") and data["attributes"].get("displayName") and type(data["attributes"]["displayName"]) is list: additional_info["employee_name"] = data["attributes"]["displayName"][0] filter_str = rf'(&(objectClass=User)(distinguishedName={additional_info["manager_dn"]}))' response = demisto.executeCommand("ad-search", {"filter": filter_str, "attributes": "displayName,mail"}) if response and isError(response[0]): demisto.results(response) sys.exit(0) if type(response) is list and type(response[0].get("Contents")) is list and type(response[0]["Contents"][0]) is dict: data = response[0]["Contents"][0] if data.get("mail") and type(data["mail"]) is list: additional_info["manager_email"] = data["mail"][0] # This was added as the json structure returned from the AD search during testing # seems to be different from the original. elif data.get("attributes") and data["attributes"].get("mail") and type(data["attributes"]["mail"]) is list: additional_info["manager_email"] = data["attributes"]["mail"][0] if data.get("displayName") and type(data["displayName"]) is list: additional_info["manager_name"] = data["displayName"][0] # This was added as the json structure returned from the AD search during testing # seems to be different from the original. elif data.get("attributes") and data["attributes"].get("displayName") and type(data["attributes"]["displayName"]) is list: additional_info["manager_name"] = data["attributes"]["displayName"][0] return additional_info def generate_mail_subject( incident_subject: str, investigation_id: str, allow_reply: bool, persistent: Optional[bool] = None, reply_entries_tag: Optional[str] = None, ) -> str: subject = incident_subject + f" - #{investigation_id}" if allow_reply: params = {} if persistent is not None: persistent_str = str(persistent).lower() params["persistent"] = persistent_str if reply_entries_tag is not None: params["replyEntriesTag"] = reply_entries_tag response = demisto.executeCommand("addEntitlement", params) if response and isError(response[0]): demisto.results(response) sys.exit(0) entitlement = demisto.get(response[0], "Contents") if not entitlement: demisto.results("Unable to get entitlement") sys.exit(0) subject += " " + entitlement return subject def generate_mail_body(manager_name: str, employee_name: str, employee_request: str) -> str: body = """ Hi $manager_name, We've received the following request below from $employee_name. \ Please reply to this email with either "approve" or "deny". Cheers, Your friendly security team """ body_template = Template(body) result_body = body_template.safe_substitute(manager_name=manager_name, employee_name=employee_name) result_body = textwrap.dedent(result_body) return result_body + "\n----------" + employee_request def main(): # pragma: no cover args = demisto.args() email = args.get("email") manager_attribute = args.get("manager", "manager") allow_reply = argToBoolean(args.get("allowReply")) mail_body = args.get("body") employee_request = args.get("request") reply_entries_tag = args.get("replyEntriesTag") persistent = argToBoolean(args.get("persistent")) last_incident = demisto.incidents()[0] additional_info = find_additional_incident_info(last_incident) if not email: if additional_info.get("employee_email"): email = additional_info.get("employee_email") else: demisto.results("Could not find employee email.") additional_info.update(find_additional_ad_info(email=email, manager_attribute=manager_attribute)) if not employee_request: employee_request = additional_info.get("employee_request") if not mail_body: mail_body = generate_mail_body( manager_name=additional_info["manager_name"], employee_name=additional_info["employee_name"], employee_request=employee_request, ) demisto.results( demisto.executeCommand( "send-mail", { "to": additional_info["manager_email"], "subject": generate_mail_subject( incident_subject=additional_info["incident_subject"], investigation_id=demisto.investigation().get("id"), allow_reply=allow_reply, persistent=persistent, reply_entries_tag=reply_entries_tag, ), "body": mail_body, }, ) ) if __name__ in ("__builtin__", "builtins", "__main__"): main()
README
Send an approval email to the manager of the employee, allowing the manager to reply directly into the incident
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Tags | communication |
| Cortex XSOAR Version | 5.0.0 |
Dependencies
This script uses the following commands and scripts.
- send-mail
- ad-search
Inputs
| Argument Name | Description |
|---|---|
| The employee email. We will send an email to his manager. If not provided will be taken from incident label ‘Email/from’ | |
| manager | The manager attribute in Active Directory. Default is ‘manager’. |
| allowReply | If true, we will add an entitlement to the subject allowing manager to reply to war room |
| body | The contents of the email body. It’s a template that can include $empName and $managerName which will be replaced with actual values. |
| request | The contents of the request from the manager. Will be added below the body. If none is provided, incident details will be taken. |
| replyEntriesTag | Tag to add on email reply entries |
| persistent | Indicates whether to use one-time entitlement or a persistent one |
Outputs
There are no outputs for this script.