Compare commits

..

1 Commits

Author SHA1 Message Date
lebaudantoine a48f29abff 🔒️(backend) enforce display name setting on rename API
AUTHENTICATED_PARTICIPANTS_CAN_EDIT_DISPLAY_NAME was only enforced at
LiveKit token generation and by hiding the name field in the frontend.
The `rooms/{id}/rename/` endpoint never checked it, so any authenticated
user with a valid room token could rename themselves via the API even
when the self-hoster had disabled it.

Return 403 from the rename action for authenticated users when the
setting is disabled, mirroring the `can_edit` rule in
`core.utils.generate_token`. Anonymous participants are unaffected, as
they have no account name to fall back on.

Add tests covering the disabled/enabled cases for authenticated users
and the anonymous exception.
2026-09-08 01:08:50 +02:00
4 changed files with 24 additions and 25 deletions
-1
View File
@@ -10,7 +10,6 @@ and this project adheres to
### Fixed
- 🐛(backend) acknowledge unknown LiveKit webhook events instead of 422
- 🔒️(backend) enforce display name setting on rename API
## [1.31.0] - 2026-09-08
+10 -8
View File
@@ -52,6 +52,12 @@ class InvalidPayloadError(LiveKitWebhookError):
status_code = 400
class UnsupportedEventTypeError(LiveKitWebhookError):
"""Unsupported event type."""
status_code = 422
class ActionFailedError(LiveKitWebhookError):
"""Webhook action fails to process or complete."""
@@ -68,7 +74,6 @@ class LiveKitWebhookEventType(Enum):
# Participant events
PARTICIPANT_JOINED = "participant_joined"
PARTICIPANT_LEFT = "participant_left"
PARTICIPANT_CONNECTION_ABORTED = "participant_connection_aborted"
# Track events
TRACK_PUBLISHED = "track_published"
@@ -148,13 +153,10 @@ class LiveKitEventsService:
try:
webhook_type = LiveKitWebhookEventType(data.event)
except ValueError:
logger.warning(
"Ignoring unknown LiveKit webhook event type '%s' for room '%s'",
data.event,
room_name,
)
return
except ValueError as e:
raise UnsupportedEventTypeError(
f"Unknown webhook type: {data.event}"
) from e
# Handle according to received webhook type
handler = self._webhook_handlers.get(webhook_type.value)
@@ -94,7 +94,7 @@ def test_invalid_payload(client, auth_token, mock_livekit_config):
def test_unknown_event_type(client, mock_livekit_config):
"""Should acknowledge (200) an unknown event type rather than reject it."""
"""Should return 422 for unknown event type."""
event_data = json.dumps({"event": "unknown_event_type"})
# Generate auth token for this specific payload
@@ -112,8 +112,10 @@ def test_unknown_event_type(client, mock_livekit_config):
HTTP_AUTHORIZATION=auth_token,
)
assert response.status_code == 200
assert response.json() == {"status": "success"}
assert response.status_code == 422
assert response.json() == {
"status": "error",
}
@mock.patch.object(LiveKitEventsService, "_handle_room_finished")
@@ -16,6 +16,7 @@ from core.services.livekit_events import (
AuthenticationError,
InvalidPayloadError,
LiveKitEventsService,
UnsupportedEventTypeError,
api,
)
from core.services.lobby import LobbyService
@@ -664,27 +665,22 @@ def test_receive_missing_auth(service):
@mock.patch.object(api.WebhookReceiver, "receive")
def test_receive_unknown_event_is_acknowledged(mock_receive, service, caplog):
"""Unknown event types are logged and ignored, not rejected.
LiveKit adds event types over time and does not retry 4xx responses, so
raising here would silently drop the event.
"""
def test_receive_unsupported_event(mock_receive, service):
"""Should raise LiveKitWebhookError for unsupported events."""
mock_request = mock.MagicMock()
mock_request.headers = {"Authorization": "test_token"}
mock_request.body = b"{}"
# Mock returned data with unsupported event type
mock_data = mock.MagicMock()
mock_data.room.name = str(uuid.uuid4())
mock_data.event = "some_future_event"
mock_data.event = "unsupported_event"
mock_receive.return_value = mock_data
with caplog.at_level("WARNING", logger="core.services.livekit_events"):
service.receive(mock_request) # must not raise
assert "Ignoring unknown LiveKit webhook event type 'some_future_event'" in (
caplog.text
)
with pytest.raises(
UnsupportedEventTypeError, match="Unknown webhook type: unsupported_event"
):
service.receive(mock_request)
@mock.patch.object(api.WebhookReceiver, "receive")