diff --git a/src/documents/matching.py b/src/documents/matching.py index 63534ffe3..ad80ee0ad 100644 --- a/src/documents/matching.py +++ b/src/documents/matching.py @@ -6,6 +6,7 @@ from documents.models import DocumentType from documents.models import MatchingModel from documents.models import StoragePath from documents.models import Tag +from documents.permissions import get_objects_for_user_owner_aware logger = logging.getLogger("paperless.matching") @@ -19,40 +20,64 @@ def log_reason(matching_model, document, reason): ) -def match_correspondents(document, classifier): +def match_correspondents(document, classifier, user=None): pred_id = classifier.predict_correspondent(document.content) if classifier else None - correspondents = Correspondent.objects.all() + if user is not None: + correspondents = get_objects_for_user_owner_aware( + user, + "documents.view_correspondent", + Correspondent, + ) + else: + correspondents = Correspondent.objects.all() return list( filter(lambda o: matches(o, document) or o.pk == pred_id, correspondents), ) -def match_document_types(document, classifier): +def match_document_types(document, classifier, user=None): pred_id = classifier.predict_document_type(document.content) if classifier else None - document_types = DocumentType.objects.all() + if user is not None: + document_types = get_objects_for_user_owner_aware( + user, + "documents.view_documenttype", + DocumentType, + ) + else: + document_types = DocumentType.objects.all() return list( filter(lambda o: matches(o, document) or o.pk == pred_id, document_types), ) -def match_tags(document, classifier): +def match_tags(document, classifier, user=None): predicted_tag_ids = classifier.predict_tags(document.content) if classifier else [] - tags = Tag.objects.all() + if user is not None: + tags = get_objects_for_user_owner_aware(user, "documents.view_tag", Tag) + else: + tags = Tag.objects.all() return list( filter(lambda o: matches(o, document) or o.pk in predicted_tag_ids, tags), ) -def match_storage_paths(document, classifier): +def match_storage_paths(document, classifier, user=None): pred_id = classifier.predict_storage_path(document.content) if classifier else None - storage_paths = StoragePath.objects.all() + if user is not None: + storage_paths = get_objects_for_user_owner_aware( + user, + "documents.view_storagepath", + StoragePath, + ) + else: + storage_paths = StoragePath.objects.all() return list( filter( diff --git a/src/documents/permissions.py b/src/documents/permissions.py index 4af0ebae5..d4114e488 100644 --- a/src/documents/permissions.py +++ b/src/documents/permissions.py @@ -4,6 +4,7 @@ from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from guardian.models import GroupObjectPermission from guardian.shortcuts import assign_perm +from guardian.shortcuts import get_objects_for_user from guardian.shortcuts import get_users_with_perms from guardian.shortcuts import remove_perm from rest_framework.permissions import BasePermission @@ -101,3 +102,15 @@ def set_permissions_for_object(permissions, object): group, object, ) + + +def get_objects_for_user_owner_aware(user, perms, Model): + objects_owned = Model.objects.filter(owner=user) + objects_unowned = Model.objects.filter(owner__isnull=True) + objects_with_perms = get_objects_for_user( + user=user, + perms=perms, + klass=Model, + accept_global_perms=False, + ) + return objects_owned | objects_unowned | objects_with_perms diff --git a/src/documents/views.py b/src/documents/views.py index 597555be9..1edbdccc3 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -401,12 +401,16 @@ class DocumentViewSet( return Response( { - "correspondents": [c.id for c in match_correspondents(doc, classifier)], - "tags": [t.id for t in match_tags(doc, classifier)], - "document_types": [ - dt.id for dt in match_document_types(doc, classifier) + "correspondents": [ + c.id for c in match_correspondents(doc, classifier, request.user) + ], + "tags": [t.id for t in match_tags(doc, classifier, request.user)], + "document_types": [ + dt.id for dt in match_document_types(doc, classifier, request.user) + ], + "storage_paths": [ + dt.id for dt in match_storage_paths(doc, classifier, request.user) ], - "storage_paths": [dt.id for dt in match_storage_paths(doc, classifier)], "dates": [ date.strftime("%Y-%m-%d") for date in dates if date is not None ],