webhooks/papertrail: Requests from Papertrail are not JSON requests.

Papertrail sends requests with the content type
`application/x-www-form-urlencoded`, with the payload parameter holding the
JSON body. This commit fixes the papertrail integration to use the payload
parameter in the request's POST data instead of trying to parse the
request's entire body as JSON.

Papertrail documentation here:
https://help.papertrailapp.com/kb/how-it-works/web-hooks#encoding
This commit is contained in:
Puneeth Chaganti
2019-09-03 20:45:31 +05:30
committed by Tim Abbott
parent b3df3f2e22
commit df134be235
3 changed files with 35 additions and 3 deletions

View File

@@ -0,0 +1,11 @@
{
"saved_search": {
"id": 42,
"name": "Important stuff",
"query": "cron OR server1",
"html_edit_url": "https://papertrailapp.com/searches/42/edit",
"html_search_url": "https://papertrailapp.com/searches/42"
},
"max_id": 7711582041804800,
"min_id": 7711561783320576
}

View File

@@ -1,3 +1,5 @@
from urllib.parse import urlencode
from zerver.lib.test_classes import WebhookTestCase
class PapertrailHookTests(WebhookTestCase):
@@ -50,5 +52,16 @@ message body 4
self.send_and_test_stream_message('long_post', expected_topic, expected_message,
content_type="application/x-www-form-urlencoded")
def test_incorrect_message(self) -> None:
with self.assertRaises(AssertionError) as e:
self.send_and_test_stream_message('incorrect_post', '', '',
content_type="application/x-www-form-urlencoded")
self.assertIn("Missing expected keys", e.exception.args[0])
def get_body(self, fixture_name: str) -> str:
return self.webhook_fixture_data("papertrail", fixture_name, file_type="json")
# Papertrail webhook sends a POST request with payload parameter
# containing the JSON body. Documented here:
# https://help.papertrailapp.com/kb/how-it-works/web-hooks#encoding
body = self.webhook_fixture_data("papertrail", fixture_name, file_type="json")
return urlencode({'payload': body})

View File

@@ -1,6 +1,7 @@
from typing import Any, Dict
from typing import Any, Dict, Optional
from django.http import HttpRequest, HttpResponse
from django.utils.translation import ugettext as _
from zerver.decorator import api_key_only_webhook_view
from zerver.lib.request import REQ, has_request_variables
@@ -16,10 +17,17 @@ SEARCH_TEMPLATE = """
```
""".strip()
def ensure_keys(name: str, data: Any) -> Optional[str]:
if 'events' in data and 'saved_search' in data:
saved_search = data['saved_search']
if 'name' in saved_search and 'html_search_url' in saved_search:
return None
return _("Missing expected keys")
@api_key_only_webhook_view('Papertrail')
@has_request_variables
def api_papertrail_webhook(request: HttpRequest, user_profile: UserProfile,
payload: Dict[str, Any]=REQ(argument_type='body')) -> HttpResponse:
payload: Dict[str, Any]=REQ(validator=ensure_keys)) -> HttpResponse:
matches = MATCHES_TEMPLATE.format(
name=payload["saved_search"]["name"],