Don't handle json payload key errors inside webhooks.

Fixes first part of #6213.
This commit is contained in:
Robert Hönig
2017-08-24 17:31:04 +02:00
committed by Tim Abbott
parent ecb428100f
commit 18a080cd6c
23 changed files with 273 additions and 363 deletions

View File

@@ -82,12 +82,8 @@ def api_helloworld_webhook(request, user_profile,
body = 'Hello! I am happy to be here! :smile:'
# try to add the Wikipedia article of the day
# return appropriate error if not successful
try:
body_template = '\nThe Wikipedia featured article for today is **[{featured_title}]({featured_url})**'
body += body_template.format(**payload)
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
# send the message
check_send_message(user_profile, request.client, 'stream',
@@ -95,7 +91,6 @@ def api_helloworld_webhook(request, user_profile,
# return json result
return json_success()
```
The above code imports the required functions and defines the main webhook
@@ -137,10 +132,11 @@ functions.
In the body of the function we define the body of the message as `Hello! I am
happy to be here! :smile:`. The `:smile:` indicates an emoji. Then we append a
link to the Wikipedia article of the day as provided by the json payload. If
the json payload does not include data for `featured_title` and `featured_url`
we catch a `KeyError` and use `json_error` to return the appropriate
information: a 400 http status code with relevant details.
link to the Wikipedia article of the day as provided by the json payload.
* Sometimes, it might occur that a json payload does not contain all required keys your
integration checks for. In such a case, any `KeyError` thrown is handled by the server
backend and will create an appropriate response.
Then we send a public (stream) message with `check_send_message` which will
validate the message and then send it.

View File

@@ -17,12 +17,8 @@ def api_airbrake_webhook(request, user_profile,
payload=REQ(argument_type='body'),
stream=REQ(default='airbrake')):
# type: (HttpRequest, UserProfile, Dict[str, Any], Text) -> HttpResponse
try:
subject = get_subject(payload)
body = get_body(payload)
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
check_send_message(user_profile, request.client, 'stream', [stream], subject, body)
return json_success()

View File

@@ -17,10 +17,7 @@ from typing import Dict, Any, Text
def api_appfollow_webhook(request, user_profile, stream=REQ(default="appfollow"),
payload=REQ(argument_type="body")):
# type: (HttpRequest, UserProfile, Text, Dict[str, Any]) -> HttpResponse
try:
message = payload["text"]
except KeyError:
return json_error(_("Missing 'text' argument in JSON"))
app_name = re.search('\A(.+)', message).group(0)
check_send_message(user_profile, request.client, "stream", [stream], app_name, convert_markdown(message))

View File

@@ -44,7 +44,6 @@ class UnknownTriggerType(Exception):
def api_bitbucket2_webhook(request, user_profile, payload=REQ(argument_type='body'),
stream=REQ(default='bitbucket'), branches=REQ(default=None)):
# type: (HttpRequest, UserProfile, Dict[str, Any], str, Optional[Text]) -> HttpResponse
try:
type = get_type(request, payload)
if type != 'push':
subject = get_subject_based_on_type(payload, type)
@@ -59,10 +58,6 @@ def api_bitbucket2_webhook(request, user_profile, payload=REQ(argument_type='bod
bodies_list = get_push_bodies(payload)
for body, subject in zip(bodies_list, subjects):
check_send_message(user_profile, request.client, 'stream', [stream], subject, body)
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
return json_success()
def get_subject_for_branch_specified_events(payload, branch_name=None):

View File

@@ -29,12 +29,9 @@ CODESHIP_STATUS_MAPPER = {
def api_codeship_webhook(request, user_profile, payload=REQ(argument_type='body'),
stream=REQ(default='codeship')):
# type: (HttpRequest, UserProfile, Dict[str, Any], str) -> HttpResponse
try:
payload = payload['build']
subject = get_subject_for_http_request(payload)
body = get_body_for_http_request(payload)
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
check_send_message(user_profile, request.client, 'stream', [stream], subject, body)
return json_success()

View File

@@ -22,7 +22,6 @@ VERIFICATION_EVENT = 'verification'
def api_crashlytics_webhook(request, user_profile, payload=REQ(argument_type='body'),
stream=REQ(default='crashlytics')):
# type: (HttpRequest, UserProfile, Dict[str, Any], Text) -> HttpResponse
try:
event = payload['event']
if event == VERIFICATION_EVENT:
subject = CRASHLYTICS_SETUP_SUBJECT_TEMPLATE
@@ -37,8 +36,6 @@ def api_crashlytics_webhook(request, user_profile, payload=REQ(argument_type='bo
impacted_devices_count=issue_body['impacted_devices_count'],
url=issue_body['url']
)
except KeyError as e:
return json_error(_("Missing key {} in JSON".format(str(e))))
check_send_message(user_profile, request.client, 'stream', [stream],
subject, body)

View File

@@ -24,13 +24,10 @@ def api_delighted_webhook(request, user_profile,
stream=REQ(default='delighted'),
topic=REQ(default='Survey Response')):
# type: (HttpRequest, UserProfile, Dict[str, Dict[str, Any]], text_type, text_type) -> HttpResponse
try:
person = payload['event_data']['person']
selected_payload = {'email': person['email']}
selected_payload['score'] = payload['event_data']['score']
selected_payload['comment'] = payload['event_data']['comment']
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
BODY_TEMPLATE = body_template(selected_payload['score'])
body = BODY_TEMPLATE.format(**selected_payload)

View File

@@ -133,11 +133,7 @@ def api_freshdesk_webhook(request, user_profile, payload=REQ(argument_type='body
ticket = TicketDict(ticket_data)
subject = "#%s: %s" % (ticket.id, ticket.subject)
try:
event_info = parse_freshdesk_event(ticket.triggered_event)
except ValueError:
return json_error(_("Malformed event %s") % (ticket.triggered_event,))
if event_info[1] == "created":
content = format_freshdesk_ticket_creation_message(ticket)

View File

@@ -71,8 +71,6 @@ def api_gogs_webhook(request, user_profile,
repo = payload['repository']['name']
event = request.META['HTTP_X_GOGS_EVENT']
try:
if event == 'push':
branch = payload['ref'].replace('refs/heads/', '')
if branches is not None and branches.find(branch) == -1:
@@ -98,8 +96,6 @@ def api_gogs_webhook(request, user_profile,
)
else:
return json_error(_('Invalid event "{}" in request headers').format(event))
except KeyError as e:
return json_error(_('Missing key {} in JSON').format(str(e)))
check_send_message(user_profile, request.client, 'stream', [stream], topic, body)
return json_success()

View File

@@ -18,14 +18,10 @@ def api_gosquared_webhook(request, user_profile,
stream=REQ(default='gosquared'),
topic=REQ(default=None)):
# type: (HttpRequest, UserProfile, Dict[str, Dict[str, Any]], Text, Text) -> HttpResponse
try:
domain_name = payload['siteDetails']['domain']
user_num = payload['concurrents']
user_acc = payload['siteDetails']['acct']
acc_url = 'https://www.gosquared.com/now/' + user_acc
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
body = BODY_TEMPLATE.format(website_name=domain_name, website_url=acc_url, user_num=user_num)
# allows for customisable topics
if topic is None:

View File

@@ -40,7 +40,6 @@ def api_greenhouse_webhook(request, user_profile,
payload=REQ(argument_type='body'),
stream=REQ(default='greenhouse'), topic=REQ(default=None)):
# type: (HttpRequest, UserProfile, Dict[str, Any], str, str) -> HttpResponse
try:
if payload['action'] == 'update_candidate':
candidate = payload['payload']['candidate']
else:
@@ -57,8 +56,5 @@ def api_greenhouse_webhook(request, user_profile,
if topic is None:
topic = "{} - {}".format(action, str(candidate['id']))
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
check_send_message(user_profile, request.client, 'stream', [stream], topic, body)
return json_success()

View File

@@ -48,12 +48,7 @@ def api_hellosign_webhook(request, user_profile,
stream=REQ(default='hellosign'),
topic=REQ(default=None)):
# type: (HttpRequest, UserProfile, Dict[str, Dict[str, Any]], text_type, text_type) -> HttpResponse
try:
model_payload = ready_payload(payload['signature_request']['signatures'],
payload)
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
model_payload = ready_payload(payload['signature_request']['signatures'], payload)
body = format_body(payload['signature_request']['signatures'], model_payload)
topic = topic or model_payload['contract_title']
check_send_message(user_profile, request.client, 'stream', [stream],

View File

@@ -21,12 +21,8 @@ def api_helloworld_webhook(request, user_profile,
body = 'Hello! I am happy to be here! :smile:'
# try to add the Wikipedia article of the day
# return appropriate error if not successful
try:
body_template = '\nThe Wikipedia featured article for today is **[{featured_title}]({featured_url})**'
body += body_template.format(**payload)
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
# send the message
check_send_message(user_profile, request.client, 'stream', [stream], topic, body)

View File

@@ -18,10 +18,7 @@ def api_homeassistant_webhook(request, user_profile,
# type: (HttpRequest, UserProfile, Dict[str, str], Text) -> HttpResponse
# construct the body of the message
try:
body = payload["message"]
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
# set the topic to the topic parameter, if given
if "topic" in payload:

View File

@@ -17,14 +17,9 @@ def api_mention_webhook(request, user_profile,
stream=REQ(default='mention'),
topic=REQ(default='news')):
# type: (HttpRequest, UserProfile, Dict[str, Iterable[Dict[str, Any]]], Text, Optional[Text]) -> HttpResponse
try:
title = payload["title"]
source_url = payload["url"]
description = payload["description"]
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
# construct the body of the message
body = '**[%s](%s)**:\n%s' % (title, source_url, description)

View File

@@ -41,14 +41,11 @@ def api_opsgenie_webhook(request, user_profile,
if 'message' in payload['alert']:
info['additional_info'] += "Message: *{}*\n".format(payload['alert']['message'])
body = ''
try:
body_template = "**OpsGenie: [Alert for {integration_name}.](https://app.opsgenie.com/alert/V2#/show/{alert_id})**\n" \
"Type: *{alert_type}*\n" \
"{additional_info}" \
"{tags}"
body += body_template.format(**info)
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
# send the message
check_send_message(user_profile, request.client, 'stream', [stream], topic, body)

View File

@@ -19,7 +19,6 @@ def api_papertrail_webhook(request, user_profile,
# type: (HttpRequest, UserProfile, Dict[str, Any], Text, Text) -> HttpResponse
# construct the message of the message
try:
message_template = '**"{}"** search found **{}** matches - {}\n```'
message = [message_template.format(payload["saved_search"]["name"],
str(len(payload["events"])),
@@ -36,8 +35,6 @@ def api_papertrail_webhook(request, user_profile,
else:
message.append('```')
post = '\n'.join(message)
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
# send the message
check_send_message(user_profile, request.client, 'stream', [stream], topic, post)

View File

@@ -167,14 +167,9 @@ def api_pivotal_webhook(request, user_profile, stream=REQ()):
subject = content = None
try:
subject, content = api_pivotal_webhook_v3(request, user_profile, stream)
except AttributeError:
return json_error(_("Failed to extract data from Pivotal XML response"))
except Exception:
# Attempt to parse v5 JSON payload
try:
subject, content = api_pivotal_webhook_v5(request, user_profile, stream)
except AttributeError:
return json_error(_("Failed to extract data from Pivotal V5 JSON response"))
if subject is None or content is None:
return json_error(_("Unable to handle Pivotal payload"))

View File

@@ -23,7 +23,6 @@ def api_semaphore_webhook(request, user_profile,
# semaphore only gives the last commit, even if there were multiple commits
# since the last build
try:
branch_name = payload["branch_name"]
project_name = payload["project_name"]
result = payload["result"]
@@ -32,26 +31,18 @@ def api_semaphore_webhook(request, user_profile,
commit_url = payload["commit"]["url"]
author_email = payload["commit"]["author_email"]
message = payload["commit"]["message"]
except KeyError as e:
return json_error(_("Missing key %s in JSON") % (str(e),))
if event == "build":
try:
build_url = payload["build_url"]
build_number = payload["build_number"]
except KeyError as e:
return json_error(_("Missing key %s in JSON") % (str(e),))
content = u"[build %s](%s): %s\n" % (build_number, build_url, result)
elif event == "deploy":
try:
build_url = payload["build_html_url"]
build_number = payload["build_number"]
deploy_url = payload["html_url"]
deploy_number = payload["number"]
server_name = payload["server_name"]
except KeyError as e:
return json_error(_("Missing key %s in JSON") % (str(e),))
content = u"[deploy %s](%s) of [build %s](%s) on server %s: %s\n" % \
(deploy_number, deploy_url, build_number, build_url, server_name, result)

View File

@@ -22,7 +22,6 @@ def api_solano_webhook(request, user_profile,
event = payload.get('event')
if event == 'test':
return handle_test_event(user_profile, request.client, stream, topic)
try:
try:
author = payload['committers'][0]
except KeyError:
@@ -31,8 +30,6 @@ def api_solano_webhook(request, user_profile,
build_log = payload['url']
repository = payload['repository']['url']
commit_id = payload['commit_id']
except KeyError as e:
return json_error(_('Missing key {} in JSON').format(str(e)))
good_status = ['passed']
bad_status = ['failed', 'error']

View File

@@ -20,7 +20,6 @@ def api_stripe_webhook(request, user_profile,
# type: (HttpRequest, UserProfile, Dict[str, Any], Text, Optional[Text]) -> HttpResponse
body = None
event_type = payload["type"]
try:
data_object = payload["data"]["object"]
if event_type.startswith('charge'):
@@ -157,8 +156,6 @@ def api_stripe_webhook(request, user_profile,
if topic is None:
topic = "Transfer {}".format(object_id)
except KeyError as e:
return json_error(_("Missing key {} in JSON".format(str(e))))
if body is None:
return json_error(_("We don't support {} event".format(event_type)))

View File

@@ -252,10 +252,7 @@ def parse_message(message):
def generate_content(data):
# type: (Mapping[str, Any]) -> str
""" Gets the template string and formats it with parsed data. """
try:
return templates[data['type']][data['event']] % data['values']
except KeyError:
return json_error(_("Unknown message"))
def get_owner_name(message):
# type: (Mapping[str, Any]) -> str

View File

@@ -16,12 +16,9 @@ SUBJECT_TEMPLATE = "{service_url}"
def send_message_for_event(event, user_profile, client, stream):
# type: (Dict[str, Any], UserProfile, Client, str) -> None
try:
event_type = get_event_type(event)
subject = SUBJECT_TEMPLATE.format(service_url=event['check']['url'])
body = EVENT_TYPE_BODY_MAPPER[event_type](event)
except KeyError as e:
return json_error(_("Missing key {} in JSON").format(str(e)))
check_send_message(user_profile, client, 'stream', [stream], subject, body)
def get_body_for_up_event(event):