feat: add include_deleted param to permitted_document_ids (#13506)

* 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.

* refactor: remove redundant deleted_at filter in permitted_document_ids

Document.objects already applies filter(deleted_at__isnull=True) internally
via SoftDeleteManager.get_queryset(), so the conditional filter was redundant.
Simplify to just use manager.all() in both branches — manager selection alone
ensures correct behavior (Document.objects excludes deleted, Document.global_objects
includes all).

Co-Authored-By: Claude Haiku <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session

---------

Co-authored-by: Claude Haiku <noreply@anthropic.com>
This commit is contained in:
Trenton H
2026-08-04 08:01:23 -07:00
committed by GitHub
co-authored by Claude Haiku
parent 3a484a3ff2
commit 5e54259db9
2 changed files with 35 additions and 5 deletions
@@ -125,3 +125,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],
)