Require auth session for media proxy
This commit is contained in:
@@ -135,6 +135,7 @@ AUTH_SESSION_COOKIE_NAME = "chgrid_session_token"
|
||||
AUTH_SESSION_COOKIE_MAX_AGE_SECONDS = 14 * 24 * 60 * 60
|
||||
AUTH_SESSION_COOKIE_SET_PATH = "/auth/session/set"
|
||||
AUTH_SESSION_COOKIE_CLEAR_PATH = "/auth/session/clear"
|
||||
AUTH_SESSION_COOKIE_CHECK_PATH = "/auth/session/check"
|
||||
AUTH_SESSION_COOKIE_CLIENT_HEADER = "X-Chgrid-Auth-Client"
|
||||
AUTH_LOGIN_FAILURE_MESSAGE = "We couldn't log you in. Check your details and try again."
|
||||
AUTH_RESUME_FAILURE_MESSAGE = "We couldn't restore your session. Please log in again."
|
||||
@@ -301,7 +302,7 @@ class SignalingServer:
|
||||
"""Handle lightweight same-origin auth cookie set/clear HTTP endpoints."""
|
||||
|
||||
path = request.path.split("?", 1)[0]
|
||||
if path not in {AUTH_SESSION_COOKIE_SET_PATH, AUTH_SESSION_COOKIE_CLEAR_PATH}:
|
||||
if path not in {AUTH_SESSION_COOKIE_SET_PATH, AUTH_SESSION_COOKIE_CLEAR_PATH, AUTH_SESSION_COOKIE_CHECK_PATH}:
|
||||
return None
|
||||
|
||||
headers = Headers()
|
||||
@@ -311,6 +312,17 @@ class SignalingServer:
|
||||
if client_header != "1":
|
||||
return HttpResponse(400, "Bad Request", headers, b"missing client header")
|
||||
|
||||
if path == AUTH_SESSION_COOKIE_CHECK_PATH:
|
||||
cookie_header = str(request.headers.get("Cookie", "")).strip()
|
||||
token = self._cookie_value(cookie_header, AUTH_SESSION_COOKIE_NAME)
|
||||
if not token:
|
||||
return HttpResponse(401, "Unauthorized", headers, b"missing session")
|
||||
try:
|
||||
self.auth_service.resume(token)
|
||||
except AuthError:
|
||||
return HttpResponse(401, "Unauthorized", headers, b"invalid session")
|
||||
return HttpResponse(204, "No Content", headers, b"")
|
||||
|
||||
if path == AUTH_SESSION_COOKIE_CLEAR_PATH:
|
||||
headers["Set-Cookie"] = self._clear_session_cookie_header(request=request)
|
||||
return HttpResponse(200, "OK", headers, b"cleared")
|
||||
|
||||
@@ -9,6 +9,7 @@ from websockets.http11 import Request
|
||||
|
||||
from app.server import (
|
||||
AUTH_SESSION_COOKIE_CLIENT_HEADER,
|
||||
AUTH_SESSION_COOKIE_CHECK_PATH,
|
||||
AUTH_SESSION_COOKIE_CLEAR_PATH,
|
||||
AUTH_SESSION_COOKIE_NAME,
|
||||
AUTH_SESSION_COOKIE_SET_PATH,
|
||||
@@ -61,6 +62,36 @@ async def test_session_cookie_clear_endpoint_expires_cookie() -> None:
|
||||
assert "HttpOnly" in set_cookie
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_session_cookie_check_endpoint_accepts_valid_cookie() -> None:
|
||||
server = SignalingServer("127.0.0.1", 8765, None, None)
|
||||
username = f"user_{uuid.uuid4().hex[:8]}"
|
||||
session = server.auth_service.register(username, "password99")
|
||||
request = _request(
|
||||
AUTH_SESSION_COOKIE_CHECK_PATH,
|
||||
headers={
|
||||
AUTH_SESSION_COOKIE_CLIENT_HEADER: "1",
|
||||
"Cookie": f"{AUTH_SESSION_COOKIE_NAME}={session.token}",
|
||||
},
|
||||
)
|
||||
|
||||
response = await server._process_http_request(SimpleNamespace(), request)
|
||||
|
||||
assert response is not None
|
||||
assert response.status_code == 204
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_session_cookie_check_endpoint_rejects_missing_cookie() -> None:
|
||||
server = SignalingServer("127.0.0.1", 8765, None, None)
|
||||
request = _request(AUTH_SESSION_COOKIE_CHECK_PATH, headers={AUTH_SESSION_COOKIE_CLIENT_HEADER: "1"})
|
||||
|
||||
response = await server._process_http_request(SimpleNamespace(), request)
|
||||
|
||||
assert response is not None
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
def test_session_token_from_websocket_cookie_reads_named_cookie() -> None:
|
||||
server = SignalingServer("127.0.0.1", 8765, None, None)
|
||||
websocket = SimpleNamespace(
|
||||
|
||||
Reference in New Issue
Block a user