Coverage for product_risk_suite/api/middleware.py: 100%
16 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-16 14:44 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-16 14:44 +0000
1from django.http import JsonResponse
3from .models import APIToken
5BEARER_PREFIX = "Bearer "
8class APITokenAuthenticationMiddleware:
9 """Authenticates /graphql requests carrying an `Authorization: Bearer <token>`
10 header against APIToken, independently of AUTHENTICATION_BACKENDS (session
11 login and any configured LDAP backend are untouched)."""
13 def __init__(self, get_response):
14 self.get_response = get_response
16 def __call__(self, request):
17 if request.path == "/graphql" and not request.user.is_authenticated:
18 auth_header = request.headers.get("Authorization", "")
19 if auth_header.startswith(BEARER_PREFIX):
20 raw_token = auth_header[len(BEARER_PREFIX):].strip()
21 token = APIToken.authenticate(raw_token)
22 if token is None:
23 return JsonResponse(
24 {"errors": [{"message": "Invalid or expired API token"}]},
25 status=401,
26 )
27 request.user = token.owner
29 return self.get_response(request)