diff --git a/CHANGELOG.md b/CHANGELOG.md index d7d96174..38637535 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to ## [Unreleased] +### Fixed + +- 🔒️(backend) enforce display name setting on rename API + ## [1.31.0] - 2026-09-08 ### Added diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py index 9cd7f49a..0a4ab1d6 100644 --- a/src/backend/core/api/viewsets.py +++ b/src/backend/core/api/viewsets.py @@ -909,6 +909,15 @@ class RoomViewSet( """Rename the current participant in the room.""" room = self.get_object() + if ( + not settings.AUTHENTICATED_PARTICIPANTS_CAN_EDIT_DISPLAY_NAME + and request.user.is_authenticated + ): + return drf_response.Response( + {"error": "Authenticated participants cannot edit their display name"}, + status=drf_status.HTTP_403_FORBIDDEN, + ) + serializer = serializers.RenameParticipantSerializer(data=request.data) serializer.is_valid(raise_exception=True) diff --git a/src/backend/core/tests/rooms/test_api_rooms_rename_toggle.py b/src/backend/core/tests/rooms/test_api_rooms_rename_toggle.py index 72511926..f8d7916c 100644 --- a/src/backend/core/tests/rooms/test_api_rooms_rename_toggle.py +++ b/src/backend/core/tests/rooms/test_api_rooms_rename_toggle.py @@ -372,6 +372,67 @@ def test_rename_participant_unexpected_twirp_error(mock_livekit_client, room, to mock_livekit_client.aclose.assert_called_once() +@pytest.mark.parametrize("name", ["John Doe", "Admin", "Room Owner"]) +def test_rename_participant_forbidden_when_display_name_edit_disabled( + mock_livekit_client, settings, room, token, name +): + """ + Test rename is rejected for authenticated users when the self-hoster + disables AUTHENTICATED_PARTICIPANTS_CAN_EDIT_DISPLAY_NAME. + """ + settings.AUTHENTICATED_PARTICIPANTS_CAN_EDIT_DISPLAY_NAME = False + + client = APIClient() + url = reverse("rooms-rename", kwargs={"pk": room.id}) + response = client.post( + url, {"name": name}, format="json", HTTP_AUTHORIZATION=f"Bearer {token}" + ) + + assert response.status_code == status.HTTP_403_FORBIDDEN + assert response.data == { + "error": "Authenticated participants cannot edit their display name" + } + mock_livekit_client.room.update_participant.assert_not_called() + + +def test_rename_participant_allowed_when_display_name_edit_enabled( + mock_livekit_client, settings, room, token +): + """Test rename still works for authenticated users when the setting is enabled.""" + settings.AUTHENTICATED_PARTICIPANTS_CAN_EDIT_DISPLAY_NAME = True + + client = APIClient() + url = reverse("rooms-rename", kwargs={"pk": room.id}) + response = client.post( + url, {"name": "John Doe"}, format="json", HTTP_AUTHORIZATION=f"Bearer {token}" + ) + + assert response.status_code == status.HTTP_200_OK + mock_livekit_client.room.update_participant.assert_called_once() + + +def test_rename_participant_anonymous_allowed_when_display_name_edit_disabled( + mock_livekit_client, settings, room, anonymous_token +): + """ + Test the setting only restricts authenticated users: anonymous participants + have no account name to fall back on and can still rename themselves. + """ + settings.AUTHENTICATED_PARTICIPANTS_CAN_EDIT_DISPLAY_NAME = False + + client = APIClient() + url = reverse("rooms-rename", kwargs={"pk": room.id}) + response = client.post( + url, + {"name": "Guest User"}, + format="json", + HTTP_AUTHORIZATION=f"Bearer {anonymous_token}", + ) + + assert response.status_code == status.HTTP_200_OK + mock_livekit_client.room.update_participant.assert_called_once() + + def test_rename_participant_success_anonymous( mock_livekit_client, room, anonymous_token ):