mirror of
https://github.com/zulip/zulip.git
synced 2026-06-21 21:32:29 +08:00
Fix trello integration by adding handling HEAD confirmation request.
Previously, we rejected the HEAD requests that the trello integration uses to check if the server accepts the integration. Add decorator for returning 200 status code if request is HEAD. Fixes: #2311.
This commit is contained in:
parent
2abe11e209
commit
d8dee522b6
@ -7,7 +7,7 @@ from django.views.decorators.csrf import csrf_exempt
|
||||
from django.http import QueryDict, HttpResponseNotAllowed, HttpRequest
|
||||
from django.http.multipartparser import MultiPartParser
|
||||
from zerver.models import UserProfile, get_client, get_user_profile_by_email
|
||||
from zerver.lib.response import json_error, json_unauthorized
|
||||
from zerver.lib.response import json_error, json_unauthorized, json_success
|
||||
from django.shortcuts import resolve_url
|
||||
from django.utils.decorators import available_attrs
|
||||
from django.utils.timezone import now
|
||||
@ -649,3 +649,13 @@ def uses_mandrill(func):
|
||||
kwargs['mail_client'] = get_mandrill_client()
|
||||
return func(*args, **kwargs)
|
||||
return wrapped_func # type: ignore # https://github.com/python/mypy/issues/1927
|
||||
|
||||
def return_success_on_head_request(view_func):
|
||||
# type: (Callable) -> Callable
|
||||
@wraps(view_func)
|
||||
def _wrapped_view_func(request, *args, **kwargs):
|
||||
# type: (HttpResponse, *Any, **Any) -> Callable
|
||||
if request.method == 'HEAD':
|
||||
return json_success()
|
||||
return view_func(request, *args, **kwargs)
|
||||
return _wrapped_view_func
|
||||
|
||||
@ -17,6 +17,7 @@ from zerver.lib.test_classes import (
|
||||
ZulipTestCase,
|
||||
WebhookTestCase,
|
||||
)
|
||||
from zerver.lib.response import json_response
|
||||
from zerver.lib.request import \
|
||||
REQ, has_request_variables, RequestVariableMissingError, \
|
||||
RequestVariableConversionError, JsonableError
|
||||
@ -25,7 +26,8 @@ from zerver.decorator import (
|
||||
authenticated_json_post_view, authenticated_json_view,
|
||||
authenticate_notify,
|
||||
get_client_name, internal_notify_view, is_local_addr,
|
||||
rate_limit, validate_api_key, logged_in_and_active
|
||||
rate_limit, validate_api_key, logged_in_and_active,
|
||||
return_success_on_head_request
|
||||
)
|
||||
from zerver.lib.validator import (
|
||||
check_string, check_dict, check_bool, check_int, check_list
|
||||
@ -872,3 +874,31 @@ class TestZulipLoginRequiredDecorator(ZulipTestCase):
|
||||
with mock.patch('zerver.decorator.get_subdomain', return_value='acme'):
|
||||
result = self.client_get('/accounts/accept_terms/')
|
||||
self.assertEqual(result.status_code, 302)
|
||||
|
||||
class ReturnSuccessOnHeadRequestDecorator(ZulipTestCase):
|
||||
def test_return_success_on_head_request_returns_200_if_request_method_is_head(self):
|
||||
class HeadRequest(object):
|
||||
method = 'HEAD'
|
||||
|
||||
request = HeadRequest()
|
||||
|
||||
@return_success_on_head_request
|
||||
def test_function(request):
|
||||
return json_response(msg=u'from_test_function')
|
||||
|
||||
response = test_function(request)
|
||||
self.assert_json_success(response)
|
||||
self.assertNotEqual(ujson.loads(response.content).get('msg'), u'from_test_function')
|
||||
|
||||
def test_return_success_on_head_request_returns_normal_response_if_request_method_is_not_head(self):
|
||||
class HeadRequest(object):
|
||||
method = 'POST'
|
||||
|
||||
request = HeadRequest()
|
||||
|
||||
@return_success_on_head_request
|
||||
def test_function(request):
|
||||
return json_response(msg=u'from_test_function')
|
||||
|
||||
response = test_function(request)
|
||||
self.assertEqual(ujson.loads(response.content).get('msg'), u'from_test_function')
|
||||
|
||||
@ -6,6 +6,11 @@ class TrelloHookTests(WebhookTestCase):
|
||||
URL_TEMPLATE = u"/api/v1/external/trello?stream={stream}&api_key={api_key}"
|
||||
FIXTURE_DIR_NAME = 'trello'
|
||||
|
||||
def test_trello_confirmation_request(self):
|
||||
# type: () -> None
|
||||
response = self.client.head(self.build_webhook_url())
|
||||
self.assertEqual(response.status_code, 200, response)
|
||||
|
||||
def test_trello_webhook_when_card_was_moved_to_another_list(self):
|
||||
# type: () -> None
|
||||
expected_message = u"TomaszKolek moved [This is a card.](https://trello.com/c/r33ylX2Z) from Basics to Intermediate."
|
||||
|
||||
@ -6,6 +6,7 @@ from typing import Mapping, Any, Tuple
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from zerver.lib.actions import check_send_message
|
||||
from zerver.decorator import return_success_on_head_request
|
||||
from zerver.lib.response import json_success, json_error
|
||||
from zerver.models import UserProfile, Client
|
||||
from zerver.decorator import REQ, has_request_variables, api_key_only_webhook_view
|
||||
@ -15,6 +16,7 @@ from .board_actions import SUPPORTED_BOARD_ACTIONS, process_board_action
|
||||
from .exceptions import UnsupportedAction
|
||||
|
||||
@api_key_only_webhook_view('Trello')
|
||||
@return_success_on_head_request
|
||||
@has_request_variables
|
||||
def api_trello_webhook(request, user_profile, client, payload=REQ(argument_type='body'), stream=REQ(default='trello')):
|
||||
# type: (HttpRequest, UserProfile, Client, Mapping[str, Any], text_type) -> HttpResponse
|
||||
|
||||
Loading…
Reference in New Issue
Block a user