mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-08-02 00:52:20 +00:00
feat: add include_deleted param to permitted_document_ids
Widens permitted_document_ids to accept an include_deleted keyword-only flag (default False, preserving current behavior) so later call sites that need visibility into soft-deleted documents (e.g. trash restore) can reuse this permission check instead of duplicating it.
This commit is contained in:
@@ -163,14 +163,20 @@ def set_permissions_for_object(
|
||||
)
|
||||
|
||||
|
||||
def permitted_document_ids(user):
|
||||
def permitted_document_ids(user, *, include_deleted: bool = False):
|
||||
"""
|
||||
Return a queryset of document IDs the user may view, limited to non-deleted
|
||||
documents. This intentionally avoids ``get_objects_for_user`` to keep the
|
||||
subquery small and index-friendly.
|
||||
Return a queryset of document IDs the user may view. By default limited
|
||||
to non-deleted documents; pass ``include_deleted=True`` for callers that
|
||||
need to check permission on soft-deleted documents (e.g. trash restore).
|
||||
This intentionally avoids ``get_objects_for_user`` to keep the subquery
|
||||
small and index-friendly.
|
||||
"""
|
||||
|
||||
base_docs = Document.objects.filter(deleted_at__isnull=True).only("id", "owner")
|
||||
manager = Document.global_objects if include_deleted else Document.objects
|
||||
base_docs = (
|
||||
manager.all() if include_deleted else manager.filter(deleted_at__isnull=True)
|
||||
)
|
||||
base_docs = base_docs.only("id", "owner")
|
||||
|
||||
if user is None or not getattr(user, "is_authenticated", False):
|
||||
# Just Anonymous user e.g. for drf-spectacular
|
||||
|
||||
@@ -119,3 +119,29 @@ class TestPermittedDocumentIdsSecurity:
|
||||
expected_visible=[unowned.pk],
|
||||
expected_hidden=[owned.pk],
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class TestPermittedDocumentIdsIncludeDeleted:
|
||||
def test_include_deleted_true_reveals_soft_deleted_owned_document(self):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
doc = DocumentFactory(owner=owner)
|
||||
doc.delete()
|
||||
|
||||
assert_visible_document_ids(
|
||||
permitted_document_ids(owner, include_deleted=True),
|
||||
expected_visible=[doc.pk],
|
||||
expected_hidden=[],
|
||||
)
|
||||
|
||||
def test_include_deleted_true_still_respects_permission_boundary(self):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
stranger = User.objects.create_user(username="mallory")
|
||||
doc = DocumentFactory(owner=owner)
|
||||
doc.delete()
|
||||
|
||||
assert_visible_document_ids(
|
||||
permitted_document_ids(stranger, include_deleted=True),
|
||||
expected_visible=[],
|
||||
expected_hidden=[doc.pk],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user