1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
import calendar
import hashlib
from django.core.exceptions import ObjectDoesNotExist
from django.http import JsonResponse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from ..compat import login_not_required
from ..models import get_access_token_model
from ..views.generic import ClientProtectedScopedResourceView
@method_decorator(csrf_exempt, name="dispatch")
@method_decorator(login_not_required, name="dispatch")
class IntrospectTokenView(ClientProtectedScopedResourceView):
"""
Implements an endpoint for token introspection based
on RFC 7662 https://rfc-editor.org/rfc/rfc7662.html
To access this view the request must pass a OAuth2 Bearer Token
which is allowed to access the scope `introspection`.
"""
required_scopes = ["introspection"]
@staticmethod
def get_token_response(token_value=None):
try:
token_checksum = hashlib.sha256(token_value.encode("utf-8")).hexdigest()
token = (
get_access_token_model()
.objects.select_related("user", "application")
.get(token_checksum=token_checksum)
)
except ObjectDoesNotExist:
return JsonResponse({"active": False}, status=200)
else:
if token.is_valid():
data = {
"active": True,
"scope": token.scope,
"exp": int(calendar.timegm(token.expires.timetuple())),
}
if token.application:
data["client_id"] = token.application.client_id
if token.user:
data["username"] = token.user.get_username()
return JsonResponse(data)
else:
return JsonResponse({"active": False}, status=200)
def get(self, request, *args, **kwargs):
"""
Get the token from the URL parameters.
URL: https://example.com/introspect?token=mF_9.B5f-4.1JqM
:param request:
:param args:
:param kwargs:
:return:
"""
return self.get_token_response(request.GET.get("token", None))
def post(self, request, *args, **kwargs):
"""
Get the token from the body form parameters.
Body: token=mF_9.B5f-4.1JqM
:param request:
:param args:
:param kwargs:
:return:
"""
return self.get_token_response(request.POST.get("token", None))
|