|
|
- import json
- import uuid
- from functools import wraps
-
- from django.contrib.auth.models import User
- from django.http import HttpResponseBadRequest, JsonResponse
- from six import string_types
-
-
- def uuid_or_400(f):
- @wraps(f)
- def wrapper(request, *args, **kwds):
- try:
- uuid.UUID(args[0])
- except ValueError:
- return HttpResponseBadRequest()
-
- return f(request, *args, **kwds)
- return wrapper
-
-
- def make_error(msg):
- return JsonResponse({"error": msg}, status=400)
-
-
- def check_api_key(f):
- @wraps(f)
- def wrapper(request, *args, **kwds):
- try:
- data = json.loads(request.body.decode("utf-8"))
- except ValueError:
- return make_error("could not parse request body")
-
- api_key = str(data.get("api_key", ""))
- if api_key == "":
- return make_error("wrong api_key")
-
- try:
- user = User.objects.get(profile__api_key=api_key)
- except User.DoesNotExist:
- return make_error("wrong api_key")
-
- request.json = data
- request.user = user
- return f(request, *args, **kwds)
-
- return wrapper
-
-
- def validate_json(schema):
- """ Validate request.json contents against `schema`.
-
- Supports a tiny subset of JSON schema spec.
-
- """
-
- def decorator(f):
- @wraps(f)
- def wrapper(request, *args, **kwds):
- for key, spec in schema["properties"].items():
- if key not in request.json:
- continue
-
- value = request.json[key]
- if spec["type"] == "string":
- if not isinstance(value, string_types):
- return make_error("%s is not a string" % key)
- elif spec["type"] == "number":
- if not isinstance(value, int):
- return make_error("%s is not a number" % key)
- if "minimum" in spec and value < spec["minimum"]:
- return make_error("%s is too small" % key)
- if "maximum" in spec and value > spec["maximum"]:
- return make_error("%s is too large" % key)
-
- return f(request, *args, **kwds)
- return wrapper
- return decorator
|