File indexing completed on 2026-08-12 09:36:20
0001 """Stable anonymous source and request identities for the SWF proxy hop."""
0002
0003 import re
0004 import secrets
0005 import uuid
0006
0007 from django.conf import settings
0008 from django.core import signing
0009
0010
0011 SOURCE_COOKIE_NAME = 'swf_source_prod'
0012 SOURCE_COOKIE_SALT = 'swf-remote-source-v1'
0013 SOURCE_COOKIE_MAX_AGE = 365 * 24 * 60 * 60
0014 SOURCE_ID_RE = re.compile(r'^[0-9a-f]{32}$')
0015
0016
0017 def _source_id(request):
0018 signed_value = request.COOKIES.get(SOURCE_COOKIE_NAME, '')
0019 if signed_value:
0020 try:
0021 value = signing.loads(signed_value, salt=SOURCE_COOKIE_SALT)
0022 except signing.BadSignature:
0023 value = ''
0024 if isinstance(value, str) and SOURCE_ID_RE.fullmatch(value):
0025 return value, False
0026 return secrets.token_hex(16), True
0027
0028
0029 class ProxyIdentityMiddleware:
0030 """Attach trusted proxy metadata and persist an anonymous source id.
0031
0032 The source id is an observability label, not authentication or
0033 authorization. Authenticated user identity remains request.user and the
0034 X-Remote-User tunnel header.
0035 """
0036
0037 def __init__(self, get_response):
0038 self.get_response = get_response
0039
0040 def __call__(self, request):
0041 source_id, set_cookie = _source_id(request)
0042 request.swf_source_id = source_id
0043 request.swf_request_id = uuid.uuid4().hex
0044
0045 response = self.get_response(request)
0046 response['X-SWF-Request-ID'] = request.swf_request_id
0047 if set_cookie:
0048 response.set_cookie(
0049 SOURCE_COOKIE_NAME,
0050 signing.dumps(source_id, salt=SOURCE_COOKIE_SALT),
0051 max_age=SOURCE_COOKIE_MAX_AGE,
0052 path=settings.FORCE_SCRIPT_NAME or '/',
0053 secure=not settings.DEBUG,
0054 httponly=True,
0055 samesite='Lax',
0056 )
0057 return response