diff --git a/src/backend/core/api/serializers.py b/src/backend/core/api/serializers.py index 525f2873..5894fa88 100644 --- a/src/backend/core/api/serializers.py +++ b/src/backend/core/api/serializers.py @@ -122,10 +122,14 @@ class RoomSerializer(serializers.ModelSerializer): if role is not None or instance.is_public: slug = f"{instance.id!s}".replace("-", "") + username = request.GET.get("username", None) + output["livekit"] = { "url": settings.LIVEKIT_CONFIGURATION["url"], "room": slug, - "token": utils.generate_token(room=slug, user=request.user), + "token": utils.generate_token( + room=slug, user=request.user, username=username + ), } output["is_administrable"] = is_admin diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py index add59be3..e02bc63d 100644 --- a/src/backend/core/api/viewsets.py +++ b/src/backend/core/api/viewsets.py @@ -188,12 +188,15 @@ class RoomViewSet( if not settings.ALLOW_UNREGISTERED_ROOMS: raise slug = slugify(self.kwargs["pk"]) + username = request.query_params.get("username", None) data = { "id": None, "livekit": { "url": settings.LIVEKIT_CONFIGURATION["url"], "room": slug, - "token": utils.generate_token(room=slug, user=request.user), + "token": utils.generate_token( + room=slug, user=request.user, username=username + ), }, } else: diff --git a/src/backend/core/tests/rooms/test_api_rooms_retrieve.py b/src/backend/core/tests/rooms/test_api_rooms_retrieve.py index 6e21c86d..26c4ac54 100644 --- a/src/backend/core/tests/rooms/test_api_rooms_retrieve.py +++ b/src/backend/core/tests/rooms/test_api_rooms_retrieve.py @@ -111,7 +111,9 @@ def test_api_rooms_retrieve_anonymous_unregistered_allowed(mock_token): }, } - mock_token.assert_called_once_with(room="unregistered-room", user=AnonymousUser()) + mock_token.assert_called_once_with( + room="unregistered-room", user=AnonymousUser(), username=None + ) @override_settings(ALLOW_UNREGISTERED_ROOMS=True) @@ -141,7 +143,9 @@ def test_api_rooms_retrieve_anonymous_unregistered_allowed_not_normalized(mock_t }, } - mock_token.assert_called_once_with(room="reunion", user=AnonymousUser()) + mock_token.assert_called_once_with( + room="reunion", user=AnonymousUser(), username=None + ) @override_settings(ALLOW_UNREGISTERED_ROOMS=False) @@ -229,7 +233,7 @@ def test_api_rooms_retrieve_authenticated_public(mock_token): "slug": room.slug, } - mock_token.assert_called_once_with(room=expected_name, user=user) + mock_token.assert_called_once_with(room=expected_name, user=user, username=None) def test_api_rooms_retrieve_authenticated(): @@ -327,7 +331,7 @@ def test_api_rooms_retrieve_members(mock_token, django_assert_num_queries): "slug": room.slug, } - mock_token.assert_called_once_with(room=expected_name, user=user) + mock_token.assert_called_once_with(room=expected_name, user=user, username=None) @mock.patch("core.utils.generate_token", return_value="foo") @@ -400,4 +404,4 @@ def test_api_rooms_retrieve_administrators(mock_token, django_assert_num_queries "slug": room.slug, } - mock_token.assert_called_once_with(room=expected_name, user=user) + mock_token.assert_called_once_with(room=expected_name, user=user, username=None) diff --git a/src/backend/core/utils.py b/src/backend/core/utils.py index 24921687..7055eae6 100644 --- a/src/backend/core/utils.py +++ b/src/backend/core/utils.py @@ -1,7 +1,7 @@ """ Utils functions used in the core app """ -import string +from typing import Optional from uuid import uuid4 from django.conf import settings @@ -9,12 +9,14 @@ from django.conf import settings from livekit.api import AccessToken, VideoGrants -def generate_token(room: string, user) -> str: +def generate_token(room: str, user, username: Optional[str] = None) -> str: """Generate a Livekit access token for a user in a specific room. Args: room (str): The name of the room. user (User): The user which request the access token. + username (Optional[str]): The username to be displayed in the room. + If none, a default value will be used. Returns: str: The LiveKit JWT access token. @@ -38,10 +40,12 @@ def generate_token(room: string, user) -> str: ).with_grants(video_grants) if user.is_anonymous: - # todo - allow passing a proper name for not logged-in user token.with_identity(str(uuid4())) + default_username = "Anonymous" else: - # todo - use user's fullname instead of its email for the displayed name - token.with_identity(user.sub).with_name(f"{user!s}") + token.with_identity(user.sub) + default_username = str(user) + + token.with_name(username or default_username) return token.to_jwt()