from rest_framework.authtoken.models import Token from django.contrib.auth import get_user_model from django.shortcuts import redirect from django.urls import reverse from django.contrib import messages User = get_user_model() def enhanced_auth_middleware(get_response): """ Enhanced middleware for API authentication with admin restriction Handles custom documentation system authentication """ def middleware(request): # Define protected paths that require staff access protected_paths = ["/swagger", "/redoc", "/docs"] is_protected_path = any(path in request.path for path in protected_paths) if is_protected_path: # Check if user is authenticated and is staff if request.user.is_authenticated and request.user.is_staff: # Handle swagger token authentication from session if 'swagger_token' in request.session: token = request.session['swagger_token'] # Validate the token still exists and is valid try: token_obj = Token.objects.get(key=token) if token_obj.user.is_active: request.META['HTTP_AUTHORIZATION'] = f"Token {token}" else: # Token user is inactive, clear session del request.session['swagger_token'] if 'swagger_user_info' in request.session: del request.session['swagger_user_info'] except Token.DoesNotExist: # Token doesn't exist, clear session del request.session['swagger_token'] if 'swagger_user_info' in request.session: del request.session['swagger_user_info'] # If no swagger token in session, provide default admin token for basic access elif not request.META.get('HTTP_AUTHORIZATION'): # Create or get token for the current admin user token, _ = Token.objects.get_or_create(user=request.user) request.META['HTTP_AUTHORIZATION'] = f"Token {token.key}" else: # User is not authenticated or not staff # For swagger-auth paths, allow access (they handle their own auth) if '/swagger-auth/' not in request.path: # Redirect to admin login for other protected paths messages.warning(request, 'You must be logged in as a staff member to access API documentation.') from django.utils.translation import get_language language = get_language() or 'en' return redirect(f"/{language}/admin/login/?next={request.path}") # For non-protected API paths, handle normal authentication elif "/admin/" not in request.path and request.META.get('HTTP_AUTHORIZATION') is None: if request.user.is_authenticated and request.user.is_staff: token, _ = Token.objects.get_or_create(user=request.user) request.META['HTTP_AUTHORIZATION'] = f"Token {token.key}" return get_response(request) return middleware