takahe/api/decorators.py

53 lines
1.6 KiB
Python
Raw Normal View History

2023-02-19 10:37:02 -08:00
from collections.abc import Callable
2022-12-10 23:25:48 -08:00
from functools import wraps
from django.http import JsonResponse
def identity_required(function):
"""
API version of the identity_required decorator that just makes sure the
token is tied to one, not an app only.
"""
@wraps(function)
def inner(request, *args, **kwargs):
# They need an identity
if not request.identity:
2023-02-19 10:37:02 -08:00
return JsonResponse({"error": "identity_token_required"}, status=401)
2022-12-10 23:25:48 -08:00
return function(request, *args, **kwargs)
# This is for the API only
inner.csrf_exempt = True
2022-12-10 23:25:48 -08:00
return inner
2023-02-19 10:37:02 -08:00
def scope_required(scope: str, requires_identity=True):
"""
Asserts that the token we're using has the provided scope
"""
def decorator(function: Callable):
@wraps(function)
def inner(request, *args, **kwargs):
if not request.token:
2023-03-02 09:22:37 -08:00
if request.identity:
# They're just logged in via cookie - give full access
pass
else:
return JsonResponse(
{"error": "identity_token_required"}, status=401
)
elif not request.token.has_scope(scope):
return JsonResponse({"error": "out_of_scope_for_token"}, status=403)
2023-02-19 10:37:02 -08:00
# They need an identity
if not request.identity and requires_identity:
return JsonResponse({"error": "identity_token_required"}, status=401)
return function(request, *args, **kwargs)
inner.csrf_exempt = True # type:ignore
return inner
return decorator