Fix: make document count lists for objects permissions-aware (#6019)

This commit is contained in:
shamoon 2024-03-07 07:15:46 -08:00 committed by GitHub
parent 1eff4b306f
commit 7b7b257725
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -24,6 +24,7 @@ from django.db.models import Case
from django.db.models import Count from django.db.models import Count
from django.db.models import IntegerField from django.db.models import IntegerField
from django.db.models import Max from django.db.models import Max
from django.db.models import Q
from django.db.models import Sum from django.db.models import Sum
from django.db.models import When from django.db.models import When
from django.db.models.functions import Length from django.db.models.functions import Length
@ -213,12 +214,37 @@ class PassUserMixin(CreateModelMixin):
return super().get_serializer(*args, **kwargs) return super().get_serializer(*args, **kwargs)
class CorrespondentViewSet(ModelViewSet, PassUserMixin): class PermissionsAwareDocumentCountMixin(PassUserMixin):
"""
Mixin to add document count to queryset, permissions-aware if needed
"""
def get_queryset(self):
filter = (
None
if self.request.user is None or self.request.user.is_superuser
else (
Q(
documents__id__in=get_objects_for_user_owner_aware(
self.request.user,
"documents.view_document",
Document,
).values_list("id", flat=True),
)
)
)
return (
super()
.get_queryset()
.annotate(document_count=Count("documents", filter=filter))
)
class CorrespondentViewSet(ModelViewSet, PermissionsAwareDocumentCountMixin):
model = Correspondent model = Correspondent
queryset = ( queryset = (
Correspondent.objects.annotate( Correspondent.objects.annotate(
document_count=Count("documents"),
last_correspondence=Max("documents__created"), last_correspondence=Max("documents__created"),
) )
.select_related("owner") .select_related("owner")
@ -243,16 +269,12 @@ class CorrespondentViewSet(ModelViewSet, PassUserMixin):
) )
class TagViewSet(ModelViewSet, PassUserMixin): class TagViewSet(ModelViewSet, PermissionsAwareDocumentCountMixin):
model = Tag model = Tag
queryset = ( queryset = Tag.objects.select_related("owner").order_by(
Tag.objects.annotate(document_count=Count("documents"))
.select_related("owner")
.order_by(
Lower("name"), Lower("name"),
) )
)
def get_serializer_class(self, *args, **kwargs): def get_serializer_class(self, *args, **kwargs):
if int(self.request.version) == 1: if int(self.request.version) == 1:
@ -271,16 +293,10 @@ class TagViewSet(ModelViewSet, PassUserMixin):
ordering_fields = ("color", "name", "matching_algorithm", "match", "document_count") ordering_fields = ("color", "name", "matching_algorithm", "match", "document_count")
class DocumentTypeViewSet(ModelViewSet, PassUserMixin): class DocumentTypeViewSet(ModelViewSet, PermissionsAwareDocumentCountMixin):
model = DocumentType model = DocumentType
queryset = ( queryset = DocumentType.objects.select_related("owner").order_by(Lower("name"))
DocumentType.objects.annotate(
document_count=Count("documents"),
)
.select_related("owner")
.order_by(Lower("name"))
)
serializer_class = DocumentTypeSerializer serializer_class = DocumentTypeSerializer
pagination_class = StandardPagination pagination_class = StandardPagination
@ -1177,16 +1193,12 @@ class BulkDownloadView(GenericAPIView):
return response return response
class StoragePathViewSet(ModelViewSet, PassUserMixin): class StoragePathViewSet(ModelViewSet, PermissionsAwareDocumentCountMixin):
model = StoragePath model = StoragePath
queryset = ( queryset = StoragePath.objects.select_related("owner").order_by(
StoragePath.objects.annotate(document_count=Count("documents"))
.select_related("owner")
.order_by(
Lower("name"), Lower("name"),
) )
)
serializer_class = StoragePathSerializer serializer_class = StoragePathSerializer
pagination_class = StandardPagination pagination_class = StandardPagination