mirror of
https://github.com/zulip/zulip.git
synced 2025-11-07 07:23:22 +00:00
Implement generic rest_dispatch method for new API.
(imported from commit 912ee803db03098f195d18648ab98401915fead6)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.decorators.http import require_POST
|
||||
from zephyr.models import UserProfile, UserActivity, get_client
|
||||
from zephyr.lib.response import json_success, json_error
|
||||
from zephyr.lib.response import json_success, json_error, HttpResponseUnauthorized
|
||||
from django.utils.timezone import now
|
||||
from django.db import transaction, IntegrityError
|
||||
from django.conf import settings
|
||||
@@ -13,6 +13,7 @@ from zephyr.lib.cache import user_profile_by_email_cache_key, \
|
||||
user_profile_by_user_cache_key
|
||||
|
||||
from functools import wraps
|
||||
import base64
|
||||
|
||||
class _RespondAsynchronously(object):
|
||||
pass
|
||||
@@ -90,6 +91,35 @@ def authenticated_api_view(view_func):
|
||||
return view_func(request, user_profile, *args, **kwargs)
|
||||
return _wrapped_view_func
|
||||
|
||||
def authenticated_rest_api_view(view_func):
|
||||
@csrf_exempt
|
||||
@wraps(view_func)
|
||||
def _wrapped_view_func(request, *args, **kwargs):
|
||||
# First try block attempts to get the credentials we need to do authentication
|
||||
try:
|
||||
# Grab the base64-encoded authentication string, decode it, and split it into
|
||||
# the email and API key
|
||||
auth_type, encoded_value = request.META['HTTP_AUTHORIZATION'].split()
|
||||
# case insensitive per RFC 1945
|
||||
if auth_type.lower() != "basic":
|
||||
return json_error("Only Basic authentication is supported.")
|
||||
email, api_key = base64.b64decode(encoded_value).split(":")
|
||||
except ValueError:
|
||||
return json_error("Invalid authorization header for basic auth")
|
||||
except KeyError:
|
||||
return HttpResponseUnauthorized("humbug")
|
||||
|
||||
# Now we try to do authentication or die
|
||||
try:
|
||||
user_profile = validate_api_key(email, api_key)
|
||||
except JsonableError, e:
|
||||
resp = HttpResponseUnauthorized("humbug")
|
||||
resp.content = e.error
|
||||
return resp
|
||||
process_client(request, user_profile)
|
||||
return view_func(request, user_profile, *args, **kwargs)
|
||||
return _wrapped_view_func
|
||||
|
||||
def authenticate_log_and_execute_json(request, client, view_func, *args, **kwargs):
|
||||
if not request.user.is_authenticated():
|
||||
return json_error("Not logged in", status=401)
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
from django.http import HttpResponse
|
||||
from django.http import HttpResponse, HttpResponseNotAllowed
|
||||
import simplejson
|
||||
|
||||
class HttpResponseUnauthorized(HttpResponse):
|
||||
status_code = 401
|
||||
|
||||
def __init__(self, realm):
|
||||
HttpResponse.__init__(self)
|
||||
self["WWW-Authenticate"] = 'Basic realm="%s"' % realm
|
||||
|
||||
def json_method_not_allowed(methods):
|
||||
resp = HttpResponseNotAllowed(methods)
|
||||
resp.content = simplejson.dumps({"result": "error",
|
||||
"msg": "Method Not Allowed",
|
||||
"allowed_methods": methods})
|
||||
return resp
|
||||
|
||||
def json_response(res_type="success", msg="", data={}, status=200):
|
||||
content = {"result": res_type, "msg": msg}
|
||||
content.update(data)
|
||||
|
||||
@@ -34,10 +34,10 @@ from zephyr.decorator import require_post, \
|
||||
has_request_variables, POST, authenticated_json_view, \
|
||||
to_non_negative_int, json_to_dict, json_to_list, json_to_bool, \
|
||||
JsonableError, RequestVariableMissingError, get_user_profile_by_email, \
|
||||
get_user_profile_by_user_id
|
||||
get_user_profile_by_user_id, authenticated_rest_api_view, \
|
||||
from zephyr.lib.query import last_n
|
||||
from zephyr.lib.avatar import gravatar_hash
|
||||
from zephyr.lib.response import json_success, json_error, json_response
|
||||
from zephyr.lib.response import json_success, json_error, json_response, json_method_not_allowed
|
||||
from zephyr.lib.timestamp import timestamp_to_datetime, datetime_to_timestamp
|
||||
from zephyr.lib.cache import cache_with_key
|
||||
|
||||
@@ -150,6 +150,20 @@ def principal_to_user_profile(agent, principal):
|
||||
|
||||
return principal_user_profile
|
||||
|
||||
METHODS = ('GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'PATCH')
|
||||
|
||||
@authenticated_rest_api_view
|
||||
def rest_dispatch(request, user_profile, **kwargs):
|
||||
supported_methods = {}
|
||||
# duplicate kwargs so we can mutate the original as we go
|
||||
for arg in list(kwargs):
|
||||
if arg in METHODS:
|
||||
supported_methods[arg] = kwargs[arg]
|
||||
del kwargs[arg]
|
||||
if request.method in supported_methods.keys():
|
||||
return globals()[supported_methods[request.method]](request, user_profile, **kwargs)
|
||||
return json_method_not_allowed(supported_methods.keys())
|
||||
|
||||
@require_post
|
||||
def accounts_register(request):
|
||||
key = request.POST['key']
|
||||
|
||||
Reference in New Issue
Block a user