30 lines
892 B
Python
30 lines
892 B
Python
from typing import Optional
|
|
|
|
from django.http import HttpRequest
|
|
from ninja.security import HttpBearer, django_auth
|
|
|
|
from accounts.models import ApiToken
|
|
|
|
|
|
class TokenAuth(HttpBearer):
|
|
"""`Authorization: Bearer <key>` — how the Flutter app authenticates."""
|
|
|
|
def authenticate(self, request: HttpRequest, token: str) -> Optional[ApiToken]:
|
|
try:
|
|
api_token = ApiToken.objects.select_related("user").get(key=token)
|
|
except ApiToken.DoesNotExist:
|
|
return None
|
|
|
|
if not api_token.user.is_active:
|
|
return None
|
|
|
|
api_token.touch()
|
|
# Downstream views read request.user, same as with session auth.
|
|
request.user = api_token.user
|
|
return api_token
|
|
|
|
|
|
# Bearer first: a request carrying a token never reaches the cookie auth, which
|
|
# would reject it for a missing CSRF token.
|
|
AUTH = [TokenAuth(), django_auth]
|