🔒️(backend) derive connection-test room max age from token TTL

Refactor CONNECTION_TEST_ROOM_MAX_AGE_SECONDS so it is no longer an
independent setting but a quantity derived from (or added on top of)
the token TTL.

This prevents a misconfiguration where the token would outlive the
delete-room callback. In that case, an attacker holding a valid
token could recreate the room after the callback fired and escape
the intended cleanup.
This commit is contained in:
lebaudantoine
2026-08-05 13:59:09 +02:00
committed by aleb_the_flash
parent 1328098c45
commit b593516802
3 changed files with 15 additions and 6 deletions
+5 -1
View File
@@ -1612,9 +1612,13 @@ class DiagnosticsViewSet(viewsets.ViewSet):
# eject someone who stays connected. Schedule a hard DeleteRoom when Celery
# is available.
if settings.CELERY_ENABLED:
max_age = (
settings.CONNECTION_TEST_TOKEN_TTL_SECONDS
+ settings.CONNECTION_TEST_ROOM_EXTRA_AGE_SECONDS
)
delete_connection_test_room.apply_async(
args=[room],
countdown=settings.CONNECTION_TEST_ROOM_MAX_AGE_SECONDS,
countdown=max_age,
)
return drf_response.Response(
@@ -118,14 +118,15 @@ def test_api_diagnostics_connection_schedules_room_deletion(
"""When Celery is enabled, schedule a hard room delete after max age."""
settings.CELERY_ENABLED = True
settings.CONNECTION_TEST_ROOM_MAX_AGE_SECONDS = 300
settings.CONNECTION_TEST_TOKEN_TTL_SECONDS = 300
settings.CONNECTION_TEST_ROOM_EXTRA_AGE_SECONDS = 10
settings.CONNECTION_TEST_ROOM_PREFIX = "connection-test"
response = client.post("/api/v1.0/diagnostics/connection/")
assert response.status_code == 200
room = response.json()["livekit"]["room"]
mock_apply_async.assert_called_once_with(args=[room], countdown=300)
mock_apply_async.assert_called_once_with(args=[room], countdown=310)
@mock.patch("core.api.viewsets.delete_connection_test_room.apply_async")