authentik.enterprise.endpoints.connectors.agent.views.apple_nonce

 1from base64 import b64encode
 2from datetime import timedelta
 3from secrets import token_bytes
 4from urllib.parse import unquote
 5
 6from django.http import HttpRequest, HttpResponseBadRequest, JsonResponse
 7from django.utils.decorators import method_decorator
 8from django.utils.timezone import now
 9from django.views import View
10from django.views.decorators.csrf import csrf_exempt
11
12from authentik.endpoints.connectors.agent.models import AppleNonce, DeviceToken
13
14
15@method_decorator(csrf_exempt, name="dispatch")
16class NonceView(View):
17
18    def post(self, request: HttpRequest, *args, **kwargs):
19        raw_token = unquote(self.request.POST.get("x-ak-device-token"))
20        device_token = DeviceToken.objects.filter(key=raw_token).first()
21        if not device_token:
22            return HttpResponseBadRequest()
23        nonce = AppleNonce.objects.create(
24            nonce=b64encode(token_bytes(32)).decode(),
25            expires=now() + timedelta(minutes=5),
26            device_token=device_token,
27        )
28        return JsonResponse(
29            {
30                "Nonce": nonce.nonce,
31            }
32        )
@method_decorator(csrf_exempt, name='dispatch')
class NonceView(django.views.generic.base.View):
16@method_decorator(csrf_exempt, name="dispatch")
17class NonceView(View):
18
19    def post(self, request: HttpRequest, *args, **kwargs):
20        raw_token = unquote(self.request.POST.get("x-ak-device-token"))
21        device_token = DeviceToken.objects.filter(key=raw_token).first()
22        if not device_token:
23            return HttpResponseBadRequest()
24        nonce = AppleNonce.objects.create(
25            nonce=b64encode(token_bytes(32)).decode(),
26            expires=now() + timedelta(minutes=5),
27            device_token=device_token,
28        )
29        return JsonResponse(
30            {
31                "Nonce": nonce.nonce,
32            }
33        )

Intentionally simple parent class for all views. Only implements dispatch-by-method and simple sanity checking.

def post(self, request: django.http.request.HttpRequest, *args, **kwargs):
19    def post(self, request: HttpRequest, *args, **kwargs):
20        raw_token = unquote(self.request.POST.get("x-ak-device-token"))
21        device_token = DeviceToken.objects.filter(key=raw_token).first()
22        if not device_token:
23            return HttpResponseBadRequest()
24        nonce = AppleNonce.objects.create(
25            nonce=b64encode(token_bytes(32)).decode(),
26            expires=now() + timedelta(minutes=5),
27            device_token=device_token,
28        )
29        return JsonResponse(
30            {
31                "Nonce": nonce.nonce,
32            }
33        )
def dispatch(self, request, *args, **kwargs):
135    def dispatch(self, request, *args, **kwargs):
136        # Try to dispatch to the right method; if a method doesn't exist,
137        # defer to the error handler. Also defer to the error handler if the
138        # request method isn't on the approved list.
139        if request.method.lower() in self.http_method_names:
140            handler = getattr(
141                self, request.method.lower(), self.http_method_not_allowed
142            )
143        else:
144            handler = self.http_method_not_allowed
145        return handler(request, *args, **kwargs)