mirror of
https://github.com/zulip/zulip.git
synced 2025-11-06 23:13:25 +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.csrf import csrf_exempt
|
||||||
from django.views.decorators.http import require_POST
|
from django.views.decorators.http import require_POST
|
||||||
from zephyr.models import UserProfile, UserActivity, get_client
|
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.utils.timezone import now
|
||||||
from django.db import transaction, IntegrityError
|
from django.db import transaction, IntegrityError
|
||||||
from django.conf import settings
|
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
|
user_profile_by_user_cache_key
|
||||||
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
import base64
|
||||||
|
|
||||||
class _RespondAsynchronously(object):
|
class _RespondAsynchronously(object):
|
||||||
pass
|
pass
|
||||||
@@ -90,6 +91,35 @@ def authenticated_api_view(view_func):
|
|||||||
return view_func(request, user_profile, *args, **kwargs)
|
return view_func(request, user_profile, *args, **kwargs)
|
||||||
return _wrapped_view_func
|
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):
|
def authenticate_log_and_execute_json(request, client, view_func, *args, **kwargs):
|
||||||
if not request.user.is_authenticated():
|
if not request.user.is_authenticated():
|
||||||
return json_error("Not logged in", status=401)
|
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
|
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):
|
def json_response(res_type="success", msg="", data={}, status=200):
|
||||||
content = {"result": res_type, "msg": msg}
|
content = {"result": res_type, "msg": msg}
|
||||||
content.update(data)
|
content.update(data)
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ from zephyr.decorator import require_post, \
|
|||||||
has_request_variables, POST, authenticated_json_view, \
|
has_request_variables, POST, authenticated_json_view, \
|
||||||
to_non_negative_int, json_to_dict, json_to_list, json_to_bool, \
|
to_non_negative_int, json_to_dict, json_to_list, json_to_bool, \
|
||||||
JsonableError, RequestVariableMissingError, get_user_profile_by_email, \
|
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.query import last_n
|
||||||
from zephyr.lib.avatar import gravatar_hash
|
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.timestamp import timestamp_to_datetime, datetime_to_timestamp
|
||||||
from zephyr.lib.cache import cache_with_key
|
from zephyr.lib.cache import cache_with_key
|
||||||
|
|
||||||
@@ -150,6 +150,20 @@ def principal_to_user_profile(agent, principal):
|
|||||||
|
|
||||||
return principal_user_profile
|
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
|
@require_post
|
||||||
def accounts_register(request):
|
def accounts_register(request):
|
||||||
key = request.POST['key']
|
key = request.POST['key']
|
||||||
|
|||||||
Reference in New Issue
Block a user