🛂(backend) stop to list public doc to everyone

Everybody could see the full list of public docs.
Now only members can see their public docs.
They can still access to any specific public doc.
This commit is contained in:
Anthony LC
2024-09-06 16:12:02 +02:00
committed by Samuel Paccoud
parent b716881d50
commit 140a630a6e
22 changed files with 290 additions and 291 deletions

View File

@@ -66,9 +66,8 @@ class BaseAccessSerializer(serializers.ModelSerializer):
"You must set a resource ID in kwargs to create a new access."
) from exc
teams = user.get_teams()
if not self.Meta.model.objects.filter( # pylint: disable=no-member
Q(user=user) | Q(team__in=teams),
Q(user=user) | Q(team__in=user.teams),
role__in=[models.RoleChoices.OWNER, models.RoleChoices.ADMIN],
).exists():
raise exceptions.PermissionDenied(
@@ -78,7 +77,7 @@ class BaseAccessSerializer(serializers.ModelSerializer):
if (
role == models.RoleChoices.OWNER
and not self.Meta.model.objects.filter( # pylint: disable=no-member
Q(user=user) | Q(team__in=teams),
Q(user=user) | Q(team__in=user.teams),
role=models.RoleChoices.OWNER,
**{self.Meta.resource_field_name: resource_id}, # pylint: disable=no-member
).exists()
@@ -272,9 +271,8 @@ class InvitationSerializer(serializers.ModelSerializer):
"Anonymous users are not allowed to create invitations."
)
teams = user.get_teams()
if not models.DocumentAccess.objects.filter(
Q(user=user) | Q(team__in=teams),
Q(user=user) | Q(team__in=user.teams),
document=document_id,
role__in=[models.RoleChoices.OWNER, models.RoleChoices.ADMIN],
).exists():
@@ -285,7 +283,7 @@ class InvitationSerializer(serializers.ModelSerializer):
if (
role == models.RoleChoices.OWNER
and not models.DocumentAccess.objects.filter(
Q(user=user) | Q(team__in=teams),
Q(user=user) | Q(team__in=user.teams),
document=document_id,
role=models.RoleChoices.OWNER,
).exists()

View File

@@ -189,24 +189,35 @@ class ResourceViewsetMixin:
return queryset.filter(is_public=True)
user = self.request.user
teams = user.get_teams()
user_roles_query = (
self.access_model_class.objects.filter(
Q(user=user) | Q(team__in=teams),
Q(user=user) | Q(team__in=user.teams),
**{self.resource_field_name: OuterRef("pk")},
)
.values(self.resource_field_name)
.annotate(roles_array=ArrayAgg("role"))
.values("roles_array")
)
return (
queryset.filter(
Q(accesses__user=user) | Q(accesses__team__in=teams) | Q(is_public=True)
return queryset.annotate(user_roles=Subquery(user_roles_query)).distinct()
def list(self, request, *args, **kwargs):
"""Restrict resources returned by the list endpoint"""
queryset = self.filter_queryset(self.get_queryset())
if self.request.user.is_authenticated:
user = self.request.user
queryset = queryset.filter(
Q(accesses__user=user) | Q(accesses__team__in=user.teams)
)
.annotate(user_roles=Subquery(user_roles_query))
.distinct()
)
else:
queryset = queryset.none()
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return drf_response.Response(serializer.data)
def perform_create(self, serializer):
"""Set the current user as owner of the newly created object."""
@@ -245,8 +256,7 @@ class ResourceAccessViewsetMixin:
if self.action == "list":
user = self.request.user
teams = user.get_teams()
teams = user.teams
user_roles_query = (
queryset.filter(
Q(user=user) | Q(team__in=teams),
@@ -314,7 +324,6 @@ class DocumentViewSet(
ResourceViewsetMixin,
mixins.CreateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
viewsets.GenericViewSet,
@@ -351,10 +360,11 @@ class DocumentViewSet(
to the document
"""
document = self.get_object()
user = request.user
from_datetime = min(
access.created_at
for access in document.accesses.filter(
Q(user=request.user) | Q(team__in=request.user.get_teams()),
Q(user=user) | Q(team__in=user.teams),
)
)
@@ -386,10 +396,11 @@ class DocumentViewSet(
# Don't let users access versions that were created before they were given access
# to the document
user = request.user
from_datetime = min(
access.created_at
for access in document.accesses.filter(
Q(user=request.user) | Q(team__in=request.user.get_teams()),
Q(user=user) | Q(team__in=user.teams),
)
)
if response["LastModified"] < from_datetime:
@@ -529,7 +540,6 @@ class TemplateViewSet(
ResourceViewsetMixin,
mixins.CreateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
viewsets.GenericViewSet,
@@ -671,7 +681,7 @@ class InvitationViewset(
if self.action == "list":
user = self.request.user
teams = user.get_teams()
teams = user.teams
# Determine which role the logged-in user has in the document
user_roles_query = (