Compare commits

...

1 Commits

Author SHA1 Message Date
lebaudantoine eb345610a7 🐛(backend) allow muting when everyone_can_mute is stored as null
A stored null was read as disabled by CanMuteParticipant, since
`.get(key, True)` only defaults when the key is missing, while the
frontend reads null as enabled. Only an explicit `false` now
disables participant muting.

Fixes #1942
Supersedes #1944
2026-11-13 01:31:33 +01:00
3 changed files with 27 additions and 3 deletions
+1
View File
@@ -41,6 +41,7 @@ and this project adheres to
- ♿️(frontend) close the invite dialog with the Escape key #1916
- 🔒️(docker) move frontend to nginx/nginx-unprivileged image
- 🐛(frontend) accept meeting links with query params in join dialog
- 🐛(backend) allow muting when everyone_can_mute is stored as null #1942
## [1.37.0] - 2026-11-01
+2 -3
View File
@@ -137,7 +137,7 @@ class CanMuteParticipant(permissions.BasePermission):
- Admins and owners can always mute.
- When `everyone_can_mute` is enabled on the room, any participant
currently in the room (proven by a valid LiveKit token for that room)
can mute.
can mute. It is enabled unless explicitly set to `False`.
"""
def has_object_permission(self, request, view, obj):
@@ -149,8 +149,7 @@ class CanMuteParticipant(permissions.BasePermission):
if not is_livekit_token_auth and obj.is_administrator_or_owner(request.user):
return True
everyone_can_mute = obj.configuration.get("everyone_can_mute", True)
if not everyone_can_mute:
if obj.configuration.get("everyone_can_mute") is False:
return False
if not is_livekit_token_auth:
@@ -166,6 +166,30 @@ def test_mute_participant_everyone_can_mute_disabled_blocks_non_admin(
mock_livekit_client.room.mute_published_track.assert_not_called()
def test_mute_participant_everyone_can_mute_null_allows_non_admin(
mock_livekit_client,
):
"""Should treat a stored null everyone_can_mute as unset, hence enabled."""
client = APIClient()
room = RoomFactory(configuration={"everyone_can_mute": None})
user = AnonymousUser()
token = utils.generate_token(str(room.id), user)
url = reverse("rooms-mute-participant", kwargs={"pk": room.id})
response = client.post(
url,
{"participant_identity": str(uuid4()), "track_sid": "test-track-sid"},
format="json",
HTTP_AUTHORIZATION=f"X-LiveKit-Token {token}",
)
assert response.status_code == status.HTTP_200_OK
assert response.data == {"status": "success"}
mock_livekit_client.room.mute_published_track.assert_called_once()
def test_mute_participant_everyone_can_mute_disabled_allows_admin(mock_livekit_client):
"""Should allow admins and owners to mute when everyone_can_mute is False."""
client = APIClient()