mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 16:14:02 +00:00
integrations: Handle errors in Groove payloads.
This commit is contained in:
committed by
showell
parent
374025e10b
commit
aeeb9d07a8
59
zerver/webhooks/groove/fixtures/malformed_payload.json
Normal file
59
zerver/webhooks/groove/fixtures/malformed_payload.json
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
"created_at": "2017-12-14 20:09:19 +0530",
|
||||||
|
"href": "http://api.groovehq.com/v1/tickets/9",
|
||||||
|
"links": {
|
||||||
|
"customer": {
|
||||||
|
"id": "0070883940",
|
||||||
|
"href": "http://api.groovehq.com/v1/customers/customer@example.lcom"
|
||||||
|
},
|
||||||
|
"drafts": {
|
||||||
|
"href": "http://api.groovehq.com/v1/tickets/9/drafts"
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"href": "http://api.groovehq.com/v1/tickets/9/state"
|
||||||
|
},
|
||||||
|
"messages": {
|
||||||
|
"href": "http://api.groovehq.com/v1/tickets/9/messages"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": 9,
|
||||||
|
"priority": "low",
|
||||||
|
"resolution_time": null,
|
||||||
|
"state": "opened",
|
||||||
|
|
||||||
|
"updated_at": "2017-12-14 20:09:19 +0530",
|
||||||
|
"system_updated_at": "2017-12-14 20:09:19 +0530",
|
||||||
|
"assigned_group_id": null,
|
||||||
|
"assigned_group": null,
|
||||||
|
"closed_by": null,
|
||||||
|
"tags": [],
|
||||||
|
"tag_ids": [],
|
||||||
|
"mailbox": "Inbox",
|
||||||
|
"mailbox_id": "5063661921",
|
||||||
|
"message_count": 1,
|
||||||
|
"attachment_count": 0,
|
||||||
|
"summary": "The content of the body goes here.",
|
||||||
|
"search_summary": null,
|
||||||
|
"last_message_type": "enduser",
|
||||||
|
"last_message_author": {
|
||||||
|
"id": "1734497920",
|
||||||
|
"type": "Agent"
|
||||||
|
},
|
||||||
|
"type": "Widget",
|
||||||
|
"snoozed_until": null,
|
||||||
|
"snoozed_by_id": null,
|
||||||
|
"interaction_count": 1,
|
||||||
|
"state_changed_at": "2017-12-14 20:09:19 +0530",
|
||||||
|
"assigned_at": null,
|
||||||
|
"deleted_at": null,
|
||||||
|
"browser": null,
|
||||||
|
"page_title": null,
|
||||||
|
"page_url": null,
|
||||||
|
"platform": null,
|
||||||
|
"last_message": "The content of the body goes here.",
|
||||||
|
"assignee": null,
|
||||||
|
"app_url": "https://ghostfox.groovehq.com/groove_client/tickets/68659446",
|
||||||
|
"app_customer_url": "https://ghostfox.groovehq.com/groove_client/contacts/customers/49825873",
|
||||||
|
|
||||||
|
"last_message_plain_text": "The content of the body goes here."
|
||||||
|
}
|
@@ -108,5 +108,18 @@ class GrooveHookTests(WebhookTestCase):
|
|||||||
X_GROOVE_EVENT='ticket_state_changed')
|
X_GROOVE_EVENT='ticket_state_changed')
|
||||||
self.assert_json_success(result)
|
self.assert_json_success(result)
|
||||||
|
|
||||||
|
def test_groove_header_missing(self) -> None:
|
||||||
|
self.subscribe(self.test_user, self.STREAM_NAME)
|
||||||
|
result = self.client_post(self.url, self.get_body('ticket_state_changed'),
|
||||||
|
content_type="application/x-www-form-urlencoded")
|
||||||
|
self.assert_json_error(result, 'Missing event header')
|
||||||
|
|
||||||
|
def test_groove_malformed_payload(self) -> None:
|
||||||
|
self.subscribe(self.test_user, self.STREAM_NAME)
|
||||||
|
result = self.client_post(self.url, self.get_body('malformed_payload'),
|
||||||
|
content_type="application/x-www-form-urlencoded",
|
||||||
|
X_GROOVE_EVENT='ticket_started')
|
||||||
|
self.assert_json_error(result, 'Missing required data')
|
||||||
|
|
||||||
def get_body(self, fixture_name: Text) -> Text:
|
def get_body(self, fixture_name: Text) -> Text:
|
||||||
return self.fixture_data("groove", fixture_name, file_type="json")
|
return self.fixture_data("groove", fixture_name, file_type="json")
|
||||||
|
@@ -2,6 +2,9 @@
|
|||||||
from typing import Any, Dict, Optional, Text
|
from typing import Any, Dict, Optional, Text
|
||||||
|
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from zerver.decorator import api_key_only_webhook_view
|
from zerver.decorator import api_key_only_webhook_view
|
||||||
from zerver.lib.actions import check_send_stream_message
|
from zerver.lib.actions import check_send_stream_message
|
||||||
@@ -78,13 +81,20 @@ def api_groove_webhook(request: HttpRequest, user_profile: UserProfile,
|
|||||||
payload: Dict[str, Any]=REQ(argument_type='body'),
|
payload: Dict[str, Any]=REQ(argument_type='body'),
|
||||||
stream: Text=REQ(default='groove'),
|
stream: Text=REQ(default='groove'),
|
||||||
topic: Optional[Text]=REQ(default='notifications')) -> HttpResponse:
|
topic: Optional[Text]=REQ(default='notifications')) -> HttpResponse:
|
||||||
# The event identifier is stored in the X_GROOVE_EVENT header.
|
try:
|
||||||
event = request.META['X_GROOVE_EVENT']
|
# The event identifier is stored in the X_GROOVE_EVENT header.
|
||||||
|
event = request.META['X_GROOVE_EVENT']
|
||||||
|
except KeyError:
|
||||||
|
logging.error('No header with the Groove payload')
|
||||||
|
return json_error(_('Missing event header'))
|
||||||
# We listen to several events that are used for notifications.
|
# We listen to several events that are used for notifications.
|
||||||
# Other events are ignored.
|
# Other events are ignored.
|
||||||
if event in EVENTS_FUNCTION_MAPPER:
|
if event in EVENTS_FUNCTION_MAPPER:
|
||||||
body = EVENTS_FUNCTION_MAPPER[event](payload)
|
try:
|
||||||
|
body = EVENTS_FUNCTION_MAPPER[event](payload)
|
||||||
|
except KeyError as e:
|
||||||
|
logging.error('Required key not found : ' + e.args[0])
|
||||||
|
return json_error(_('Missing required data'))
|
||||||
if body is not None:
|
if body is not None:
|
||||||
check_send_stream_message(user_profile, request.client, stream, topic, body)
|
check_send_stream_message(user_profile, request.client, stream, topic, body)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user