33 lines
1.1 KiB
Python
33 lines
1.1 KiB
Python
from __future__ import annotations
|
|
|
|
from django.utils.translation import gettext_lazy as _
|
|
from rest_framework import authentication, exceptions
|
|
|
|
from apps.accounts.models import ApiKey
|
|
|
|
|
|
class ApiKeyAuthentication(authentication.BaseAuthentication):
|
|
"""Authenticate via X-API-Key header (hashed lookup)."""
|
|
|
|
keyword = "X-API-Key"
|
|
|
|
def authenticate(self, request):
|
|
raw_key = request.headers.get(self.keyword) or request.META.get("HTTP_X_API_KEY")
|
|
if not raw_key:
|
|
return None
|
|
if len(raw_key) < 8:
|
|
raise exceptions.AuthenticationFailed(_("Invalid API key"))
|
|
|
|
prefix = raw_key[:8]
|
|
candidates = ApiKey.objects.select_related("user").filter(
|
|
prefix=prefix, is_active=True, user__is_active=True
|
|
)
|
|
for api_key in candidates:
|
|
if api_key.verify(raw_key):
|
|
api_key.touch()
|
|
return (api_key.user, api_key)
|
|
raise exceptions.AuthenticationFailed(_("Invalid API key"))
|
|
|
|
def authenticate_header(self, request):
|
|
return self.keyword
|