From a11a88db1f9376f2437c35ce581d9e356c30e308 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 5 Apr 2026 21:09:56 +0100 Subject: [PATCH] Remove requirement for client to send expiration --- backend/common/views.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/backend/common/views.py b/backend/common/views.py index e56ba4f4..dd9453c7 100644 --- a/backend/common/views.py +++ b/backend/common/views.py @@ -220,8 +220,10 @@ class HealthCheck(APIView): class StreamAuthView(APIView): """resolves to /api/stream-auth/ Called by nginx auth_request to validate signed streaming URLs. - Reads the original URI from X-Original-URI, extracts sig + expires - query params, validates HMAC and Redis presence. No DRF auth. + Reads the original URI from X-Original-URI, extracts sig from the query + string, looks up the Redis entry (which stores video_id/user_id/expires), + and validates the HMAC. No DRF auth. Expiry is enforced by Redis TTL and + the explicit expires check below. """ authentication_classes = [] @@ -235,23 +237,17 @@ class StreamAuthView(APIView): query = parse_qs(parsed.query) sig = query.get("sig", [None])[0] - expires_raw = query.get("expires", [None])[0] - - if not sig or not expires_raw: - return HttpResponse(status=403) - - try: - expires = int(expires_raw) - except ValueError: - return HttpResponse(status=403) - - if expires < int(time.time()): + if not sig: return HttpResponse(status=403) cached = RedisArchivist().get_message_dict(f"stream_token:{sig}") if not cached: return HttpResponse(status=403) + expires = cached.get("expires") + if not isinstance(expires, int) or expires < int(time.time()): + return HttpResponse(status=403) + payload = f"{cached['video_id']}:{expires}:{cached['user_id']}" expected = hmac.new( settings.SECRET_KEY.encode(),