✨(backend) add minimal Recording viewset for room recordings
Implements routes to manage recordings within rooms, following the patterns established in Impress. The viewset exposes targeted endpoints rather than full CRUD operations, with recordings being created (soon) through room-specific routes (e.g. room/123/start-recording). The implementation draws from @sampaccoud's initial work and advices. Review focus areas: - Permission implementation choices - Serializer design and structure Credit: Initial work by @sampaccoud
This commit is contained in:
@@ -65,15 +65,11 @@ class RoomPermissions(permissions.BasePermission):
|
||||
return obj.is_administrator(user)
|
||||
|
||||
|
||||
class ResourceAccessPermission(permissions.BasePermission):
|
||||
class ResourceAccessPermission(IsAuthenticated):
|
||||
"""
|
||||
Permissions for a room that can only be updated by room administrators.
|
||||
"""
|
||||
|
||||
def has_permission(self, request, view):
|
||||
"""Only allow authenticated users."""
|
||||
return request.user.is_authenticated
|
||||
|
||||
def has_object_permission(self, request, view, obj):
|
||||
"""
|
||||
Check that the logged-in user is administrator of the linked room.
|
||||
@@ -83,3 +79,11 @@ class ResourceAccessPermission(permissions.BasePermission):
|
||||
return obj.user == user
|
||||
|
||||
return obj.resource.is_administrator(user)
|
||||
|
||||
|
||||
class HasAbilityPermission(IsAuthenticated):
|
||||
"""Permission class for access objects."""
|
||||
|
||||
def has_object_permission(self, request, view, obj):
|
||||
"""Check permission for a given object."""
|
||||
return obj.get_abilities(request.user).get(view.action, False)
|
||||
|
||||
@@ -87,6 +87,15 @@ class NestedResourceAccessSerializer(ResourceAccessSerializer):
|
||||
user = UserSerializer(read_only=True)
|
||||
|
||||
|
||||
class ListRoomSerializer(serializers.ModelSerializer):
|
||||
"""Serialize Room model for a list API endpoint."""
|
||||
|
||||
class Meta:
|
||||
model = models.Room
|
||||
fields = ["id", "name", "slug", "is_public"]
|
||||
read_only_fields = ["id", "slug"]
|
||||
|
||||
|
||||
class RoomSerializer(serializers.ModelSerializer):
|
||||
"""Serialize Room model for the API."""
|
||||
|
||||
@@ -136,3 +145,14 @@ class RoomSerializer(serializers.ModelSerializer):
|
||||
output["is_administrable"] = is_admin
|
||||
|
||||
return output
|
||||
|
||||
|
||||
class RecordingSerializer(serializers.ModelSerializer):
|
||||
"""Serialize Recording for the API."""
|
||||
|
||||
room = ListRoomSerializer(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = models.Recording
|
||||
fields = ["id", "room", "created_at", "updated_at", "status"]
|
||||
read_only_fields = fields
|
||||
|
||||
@@ -277,3 +277,27 @@ class ResourceAccessViewSet(
|
||||
permission_classes = [permissions.ResourceAccessPermission]
|
||||
queryset = models.ResourceAccess.objects.all()
|
||||
serializer_class = serializers.ResourceAccessSerializer
|
||||
|
||||
|
||||
class RecordingViewSet(
|
||||
mixins.DestroyModelMixin,
|
||||
mixins.ListModelMixin,
|
||||
viewsets.GenericViewSet,
|
||||
):
|
||||
"""
|
||||
API endpoints to access and perform actions on recordings.
|
||||
"""
|
||||
|
||||
pagination_class = Pagination
|
||||
permission_classes = [permissions.HasAbilityPermission]
|
||||
queryset = models.Recording.objects.all()
|
||||
serializer_class = serializers.RecordingSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
"""Restrict recordings to the user's ones."""
|
||||
user = self.request.user
|
||||
return (
|
||||
super()
|
||||
.get_queryset()
|
||||
.filter(Q(accesses__user=user) | Q(accesses__team__in=user.get_teams()))
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user