From 1a33fa0dd247d6683c6a3d8da24b1a4618aee5b1 Mon Sep 17 00:00:00 2001 From: Steve Pletcher Date: Tue, 17 Jan 2017 09:51:38 -0500 Subject: [PATCH] Don't escape angle brackets in the Slack module (#19980) * (Fixes #19579) Don't escape angle brackets in the Slack module * Remove ampersands from escaped characters, update docs * typo --- lib/ansible/modules/notification/slack.py | 36 +++++++++++++++-------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/lib/ansible/modules/notification/slack.py b/lib/ansible/modules/notification/slack.py index 61f06b736b..5ea1aedf35 100644 --- a/lib/ansible/modules/notification/slack.py +++ b/lib/ansible/modules/notification/slack.py @@ -1,6 +1,7 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# (c) 2017, Steve Pletcher # (c) 2016, René Moser # (c) 2015, Stefan Berggren # (c) 2014, Ramon de la Fuente @@ -58,7 +59,9 @@ options: required: true msg: description: - - Message to send. + - Message to send. Note that the module does not handle escaping characters. + Plain-text angle brackets and ampersands should be converted to HTML entities (e.g. & to &) before sending. + See Slack's documentation (U(https://api.slack.com/docs/message-formatting)) for more. required: false default: None channel: @@ -164,32 +167,39 @@ EXAMPLES = """ - title: System B value: 'load average: 5,16, 4,64, 2,43' short: True + +- name: Send a message with a link using Slack markup + slack: + token: thetoken/generatedby/slack + msg: We sent this message using ! + +- name: Send a message with angle brackets and ampersands + slack: + token: thetoken/generatedby/slack + msg: This message has <brackets> & ampersands in plain text. """ OLD_SLACK_INCOMING_WEBHOOK = 'https://%s/services/hooks/incoming-webhook?token=%s' SLACK_INCOMING_WEBHOOK = 'https://hooks.slack.com/services/%s' -# See https://api.slack.com/docs/message-formatting#how_to_escape_characters -# Escaping quotes and apostrophe however is related to how Ansible handles them. -html_escape_table = { - '&': "&", - '>': ">", - '<': "<", +# Escaping quotes and apostrophes to avoid ending string prematurely in ansible call. +# We do not escape other characters used as Slack metacharacters (e.g. &, <, >). +escape_table = { '"': "\"", "'": "\'", } -def html_escape(text): - '''Produce entities within text.''' - return "".join(html_escape_table.get(c,c) for c in text) +def escape_quotes(text): + '''Backslash any quotes within text.''' + return "".join(escape_table.get(c,c) for c in text) def build_payload_for_slack(module, text, channel, username, icon_url, icon_emoji, link_names, parse, color, attachments): payload = {} if color == "normal" and text is not None: - payload = dict(text=html_escape(text)) + payload = dict(text=escape_quotes(text)) elif text is not None: # With a custom color we have to set the message as attachment, and explicitly turn markdown parsing on for it. - payload = dict(attachments=[dict(text=html_escape(text), color=color, mrkdwn_in=["text"])]) + payload = dict(attachments=[dict(text=escape_quotes(text), color=color, mrkdwn_in=["text"])]) if channel is not None: if (channel[0] == '#') or (channel[0] == '@'): payload['channel'] = channel @@ -221,7 +231,7 @@ def build_payload_for_slack(module, text, channel, username, icon_url, icon_emoj for attachment in attachments: for key in keys_to_escape: if key in attachment: - attachment[key] = html_escape(attachment[key]) + attachment[key] = escape_quotes(attachment[key]) if 'fallback' not in attachment: attachment['fallback'] = attachment['text']