""" Custom authentication classes for API key authentication. """ from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed from django.contrib.auth import get_user_model from django.core.cache import cache import hashlib User = get_user_model() class APIKeyAuthentication(BaseAuthentication): """ Custom API key authentication for the platform. """ def authenticate(self, request): api_key = self.get_api_key(request) if not api_key: return None # Check cache first user_id = cache.get(f'api_key_{api_key}') if user_id: try: user = User.objects.get(id=user_id, is_api_enabled=True) return (user, None) except User.DoesNotExist: pass # Check database try: user = User.objects.get(api_key=api_key, is_api_enabled=True) # Cache the result for 1 hour cache.set(f'api_key_{api_key}', str(user.id), 3600) return (user, None) except User.DoesNotExist: raise AuthenticationFailed('Invalid API key') def get_api_key(self, request): """ Get API key from request headers. """ # Check X-API-Key header first api_key = request.META.get('HTTP_X_API_KEY') if api_key: return api_key # Check Authorization header as fallback auth_header = request.META.get('HTTP_AUTHORIZATION', '') if auth_header.startswith('ApiKey '): return auth_header.split(' ')[1] return None def authenticate_header(self, request): return 'ApiKey realm="api"'