Ejemplo n.º 1
0
def handle_state(context,
                 trigger_id,
                 title,
                 elements,
                 receiver='',
                 submit_label='Submit',
                 state='n/a'):
    """Send a dialog into Slack

    Args:
        context (dict): The state context object. This is included automatically by Socless Core and SHOULD NOT be supplied by the user when creating a playbook
        receiver (str): The name of the State in the playbook that will receive the dialog response
        trigger_id (str): trigger_id required to open a Dialog
        title (str): Dialog title
        elements (list): Dialog elements
        submit_label (str): Label for Dialog's submit button
        state (str): this string simply echoes back what your app passed to dialog.open. Use it as a pointer that references sensitive data stored elsewhere.

    Note:
        - See https://api.slack.com/dialogs for more details on to create elements for a slack dialog
        - This integration starts a Human Response workflow. When used in a playbook, it needs to be followed by a Task state that uses the _socless_outbound_message_response Activity to receive the response from a user
        - A user can respond to a dialog by either submitting it or cancelling it. The response payload contains a key named `type` that can be either `dialog_submission` or `dialog_cancellation`. In your playboks,
          be sure to check what type of response a user provided before acting on it.
    """
    USE_NEW_INTERACTION = 'task_token' in context

    message_id = gen_id()

    dialog = {
        'title': title,
        'elements': elements,
        'submit_label': submit_label,
        'notify_on_cancel': True,
        'callback_id': message_id,
        'state': state
    }

    payload = {'trigger_id': trigger_id, 'dialog': dialog}

    url = "https://slack.com/api/dialog.open"
    headers = {
        'content-type': 'application/json',
        'Authorization': "Bearer {}".format(SLACK_BOT_TOKEN)
    }
    if USE_NEW_INTERACTION:
        init_human_interaction(context, payload, message_id)

    resp = requests.post(url, json=payload, headers=headers)
    json_resp = resp.json()

    if not json_resp["ok"]:
        raise Exception(json_resp['error'])

    if not USE_NEW_INTERACTION:
        investigation_id = context['artifacts']['event']['investigation_id']
        execution_id = context.get('execution_id')
        socless_dispatch_outbound_message(receiver, message_id,
                                          investigation_id, execution_id,
                                          payload)
    return {'response': json_resp, "message_id": message_id}
Ejemplo n.º 2
0
def handle_state(
    context,
    target: str,
    target_type: str,
    message_template: str,
    receiver: str = "",
    response_desc: str = "[response]",
    as_user: bool = True,
    token: str = "",
):
    """Send a Slack Message and store the message id for the message.
    Args:
        target         : the username or slack id to send this message to
        target_type    : "slack_id" | "user" | "channel"
        token          : you can pass an alternate token via Jinja template in playbook.json (ssm, environment, etc)
    Returns:

    """
    helper = SlackHelper(token)

    if not message_template:
        raise Exception("No text was supplied to Slack message")

    USE_NEW_INTERACTION = "task_token" in context

    message_id = gen_id(6)

    context["_message_id"] = message_id
    extended_template = "{message_template}\n```{slash_command} {context[_message_id]} {response_desc}```\n".format(
        message_template=message_template,
        slash_command=SLACK_SLASH_COMMAND,
        context=context,
        response_desc=response_desc,
    )
    message = socless_template_string(extended_template, context)

    if USE_NEW_INTERACTION:
        init_human_interaction(context, message, message_id)

    resp = helper.slack_post_msg_wrapper(target,
                                         target_type,
                                         text=message,
                                         as_user=as_user)

    if not USE_NEW_INTERACTION:
        investigation_id = context["artifacts"]["event"]["investigation_id"]
        execution_id = context.get("execution_id")
        socless_dispatch_outbound_message(receiver, message_id,
                                          investigation_id, execution_id,
                                          message)

    return {
        "response": resp.data,  # type: ignore
        "message_id": message_id,
        "slack_id": resp["channel"],  # type: ignore
    }
Ejemplo n.º 3
0
def handle_state(context,
                 target,
                 target_type,
                 message_template,
                 receiver="",
                 response_desc='[response]'):
    """
    Send a Slack Message and store the message id for the message
    """

    if not message_template:
        raise Exception("No text was supplied to Slack message")

    USE_NEW_INTERACTION = 'task_token' in context

    message_id = gen_id(6)

    context['_message_id'] = message_id
    extended_template = "{message_template}\n```{slash_command} {context[_message_id]} {response_desc}```\n".format(
        message_template=message_template,
        slash_command=SLACK_SLASH_COMMAND,
        context=context,
        response_desc=response_desc)
    message = socless_template_string(extended_template, context)
    target_id = get_channel_id(target, target_type)

    if USE_NEW_INTERACTION:
        init_human_interaction(context, message, message_id)

    r = slack_client.chat_postMessage(channel=target_id,
                                      text=message,
                                      as_user=True)

    if not r.data['ok']:
        raise Exception(
            f"Human Reponse workflow failed to initiate because slack_client failed to send message: {r.data}"
        )

    if not USE_NEW_INTERACTION:
        investigation_id = context['artifacts']['event']['investigation_id']
        execution_id = context.get('execution_id')
        socless_dispatch_outbound_message(receiver, message_id,
                                          investigation_id, execution_id,
                                          message)

    return {
        "response": r.data,
        "message_id": message_id,
        "slack_id": target_id
    }
Ejemplo n.º 4
0
def handle_state(
    context,
    target_type: str,
    target: str,
    text: str,
    receiver: str = "",
    prompt_text: str = "",
    yes_text: str = "Yes",
    no_text: str = "No",
    as_user: bool = True,
    token: str = "",
):
    """Send a Slack Message and store the message id for the message.
    Args:
        target         : the username or slack id to send this message to
        target_type    : "slack_id" | "user" | "channel"
        token          : you can pass an alternate token via Jinja template in playbook.json (ssm, environment, etc)
    Returns:

    """
    helper = SlackHelper(token)
    USE_NEW_INTERACTION = "task_token" in context

    if not all([target_type, target, text]):
        raise Exception(
            "Incomplete inputs: target, target_type and text must be supplied")

    ATTACHMENT_YES_ACTION = {
        "name": "yes_text",
        "style": "default",
        "text": "",
        "type": "button",
        "value": "true",
    }
    ATTACHMENT_NO_ACTION = {
        "name": "no_text",
        "style": "danger",
        "text": "",
        "type": "button",
        "value": "false",
    }

    ATTACHMENT_TEMPLATE = {
        "text": "",
        "mrkdwn_in": ["text"],
        "fallback": "New message",
        "callback_id": "",
        "color": "#3AA3E3",
        "attachment_type": "default",
        "actions": [],
    }

    message_id = gen_id(6)
    context["_message_id"] = message_id
    text = socless_template_string(text, context)
    prompt_text = socless_template_string(prompt_text, context)

    ATTACHMENT_TEMPLATE["text"] = "*{}*".format(prompt_text)
    ATTACHMENT_TEMPLATE["callback_id"] = message_id
    ATTACHMENT_YES_ACTION["text"] = yes_text
    ATTACHMENT_NO_ACTION["text"] = no_text
    ATTACHMENT_TEMPLATE["actions"] = [
        ATTACHMENT_YES_ACTION, ATTACHMENT_NO_ACTION
    ]

    payload = {"text": text, "ATTACHMENT_TEMPLATE": ATTACHMENT_TEMPLATE}

    if USE_NEW_INTERACTION:
        init_human_interaction(context, payload, message_id)

    resp = helper.slack_post_msg_wrapper(
        target,
        target_type,
        text=text,
        attachments=[ATTACHMENT_TEMPLATE],
        as_user=as_user,
    )

    if not USE_NEW_INTERACTION:
        investigation_id = context["artifacts"]["event"]["investigation_id"]
        execution_id = context.get("execution_id")
        socless_dispatch_outbound_message(receiver, message_id,
                                          investigation_id, execution_id,
                                          payload)

    return {
        "response": resp.data,  # type: ignore
        "message_id": message_id,
        "slack_id": resp["channel"],  # type: ignore
    }
Ejemplo n.º 5
0
def handle_state(context,
                 target_type,
                 target,
                 text,
                 receiver='',
                 prompt_text='',
                 yes_text='Yes',
                 no_text='No'):
    """
    Send a Slack Message and store the message id for the message
    """
    USE_NEW_INTERACTION = 'task_token' in context

    if not all([target_type, target, text]):
        raise Exception(
            "Incomplete inputs: target, target_type and text must be supplied")
    target_id = get_channel_id(target, target_type)

    ATTACHMENT_YES_ACTION = {
        "name": "yes_text",
        "style": "default",
        "text": "",
        "type": "button",
        "value": "true"
    }
    ATTACHMENT_NO_ACTION = {
        "name": "no_text",
        "style": "danger",
        "text": "",
        "type": "button",
        "value": "false"
    }

    ATTACHMENT_TEMPLATE = {
        "text": "",
        "mrkdwn_in": ["text"],
        "fallback": "New message",
        "callback_id": "",
        "color": "#3AA3E3",
        "attachment_type": "default",
        "actions": []
    }

    message_id = gen_id(6)
    context['_message_id'] = message_id
    text = socless_template_string(text, context)
    prompt_text = socless_template_string(prompt_text, context)

    ATTACHMENT_TEMPLATE['text'] = "*{}*".format(prompt_text)
    ATTACHMENT_TEMPLATE['callback_id'] = message_id
    ATTACHMENT_YES_ACTION['text'] = yes_text
    ATTACHMENT_NO_ACTION['text'] = no_text
    ATTACHMENT_TEMPLATE['actions'] = [
        ATTACHMENT_YES_ACTION, ATTACHMENT_NO_ACTION
    ]

    payload = {"text": text, "ATTACHMENT_TEMPLATE": ATTACHMENT_TEMPLATE}

    if USE_NEW_INTERACTION:
        init_human_interaction(context, payload, message_id)

    resp = slack_client.chat_postMessage(channel=target_id,
                                         text=text,
                                         attachments=[ATTACHMENT_TEMPLATE],
                                         as_user=True)

    if not resp.data['ok']:
        raise Exception(resp.data['error'])

    if not USE_NEW_INTERACTION:
        investigation_id = context['artifacts']['event']['investigation_id']
        execution_id = context.get('execution_id')
        socless_dispatch_outbound_message(receiver, message_id,
                                          investigation_id, execution_id,
                                          payload)

    return {
        'response': resp.data,
        "message_id": message_id,
        "slack_id": target_id
    }
Ejemplo n.º 6
0
def handle_state(
    context,
    trigger_id: str,
    title: str,
    elements: list,
    receiver: str = "",
    submit_label: str = "Submit",
    state: str = "n/a",
    token: str = "",
):
    """Send a dialog into Slack

    Args:
        receiver     : The name of the State in the playbook that will receive the dialog response
        trigger_id   : trigger_id required to open a Dialog
        title        : Dialog title
        elements     : Dialog elements
        submit_label : Label for Dialog's submit button
        state        : this string simply echoes back what your app passed to dialog.open. Use it as a pointer that references sensitive data stored elsewhere.
        token        : you can pass an alternate token via Jinja template in playbook.json (ssm, environment, etc)

    Note:
        - See https://api.slack.com/dialogs for more details on to create elements for a slack dialog
        - This integration starts a Human Response workflow. When used in a playbook, it needs to be followed by a Task state that uses the _socless_outbound_message_response Activity to receive the response from a user
        - A user can respond to a dialog by either submitting it or cancelling it. The response payload contains a key named `type` that can be either `dialog_submission` or `dialog_cancellation`. In your playboks,
            be sure to check what type of response a user provided before acting on it.
    """
    if not token:
        token = SOCLESS_BOT_TOKEN

    USE_NEW_INTERACTION = "task_token" in context

    message_id = gen_id()

    dialog = {
        "title": title,
        "elements": elements,
        "submit_label": submit_label,
        "notify_on_cancel": True,
        "callback_id": message_id,
        "state": state,
    }

    payload = {"trigger_id": trigger_id, "dialog": dialog}

    url = "https://slack.com/api/dialog.open"
    headers = {
        "content-type": "application/json",
        "Authorization": "Bearer {}".format(token),
    }
    if USE_NEW_INTERACTION:
        init_human_interaction(context, payload, message_id)

    resp = requests.post(url, json=payload, headers=headers)
    json_resp = resp.json()

    if not json_resp["ok"]:
        raise Exception(json_resp["error"])

    if not USE_NEW_INTERACTION:
        investigation_id = context["artifacts"]["event"]["investigation_id"]
        execution_id = context.get("execution_id")
        socless_dispatch_outbound_message(receiver, message_id,
                                          investigation_id, execution_id,
                                          payload)
    return {"response": json_resp, "message_id": message_id}