Skip to content

Commit 65c2ddf

Browse files
committed
✨(backend) add is_masked to document list view
We added the `is_masked` annotation to the document list view to indicate whether a document is masked for the current user. This will allow the frontend to handle masked documents appropriately in the UI.
1 parent 67a195f commit 65c2ddf

File tree

4 files changed

+32
-1
lines changed

4 files changed

+32
-1
lines changed

src/backend/core/api/serializers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class ListDocumentSerializer(serializers.ModelSerializer):
6666
"""Serialize documents with limited fields for display in lists."""
6767

6868
is_favorite = serializers.BooleanField(read_only=True)
69+
is_masked = serializers.BooleanField(read_only=True)
6970
nb_accesses_ancestors = serializers.IntegerField(read_only=True)
7071
nb_accesses_direct = serializers.IntegerField(read_only=True)
7172
user_role = serializers.SerializerMethodField(read_only=True)
@@ -85,6 +86,7 @@ class Meta:
8586
"depth",
8687
"excerpt",
8788
"is_favorite",
89+
"is_masked",
8890
"link_role",
8991
"link_reach",
9092
"nb_accesses_ancestors",
@@ -107,6 +109,7 @@ class Meta:
107109
"depth",
108110
"excerpt",
109111
"is_favorite",
112+
"is_masked",
110113
"link_role",
111114
"link_reach",
112115
"nb_accesses_ancestors",

src/backend/core/api/viewsets.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ def filter_queryset(self, queryset):
405405
queryset = super().filter_queryset(queryset)
406406
user = self.request.user
407407
queryset = queryset.annotate_is_favorite(user)
408+
queryset = queryset.annotate_is_masked(user)
408409
queryset = queryset.annotate_user_roles(user)
409410
return queryset
410411

@@ -453,8 +454,9 @@ def list(self, request, *args, **kwargs):
453454
)
454455
queryset = queryset.filter(path__in=root_paths)
455456

456-
# Annotate favorite status and filter if applicable as late as possible
457+
# Annotate favorite and masked status and filter if applicable as late as possible
457458
queryset = queryset.annotate_is_favorite(user)
459+
queryset = queryset.annotate_is_masked(user)
458460
for field in ["is_favorite", "is_masked"]:
459461
queryset = filterset.filters[field].filter(queryset, filter_data[field])
460462

src/backend/core/models.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,18 @@ def annotate_is_favorite(self, user):
326326

327327
return self.annotate(is_favorite=models.Value(False))
328328

329+
def annotate_is_masked(self, user):
330+
"""
331+
Annotate document queryset with the masked status for the current user.
332+
"""
333+
if user.is_authenticated:
334+
masked_exists_subquery = LinkTrace.objects.filter(
335+
document_id=models.OuterRef("pk"), user=user, is_masked=True
336+
)
337+
return self.annotate(is_masked=models.Exists(masked_exists_subquery))
338+
339+
return self.annotate(is_masked=models.Value(False))
340+
329341
def annotate_user_roles(self, user):
330342
"""
331343
Annotate document queryset with the roles of the current user

src/backend/core/tests/documents/test_api_documents_children_list.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def test_api_documents_children_list_anonymous_public_standalone(
4545
"excerpt": child1.excerpt,
4646
"id": str(child1.id),
4747
"is_favorite": False,
48+
"is_masked": False,
4849
"link_reach": child1.link_reach,
4950
"link_role": child1.link_role,
5051
"numchild": 0,
@@ -67,6 +68,7 @@ def test_api_documents_children_list_anonymous_public_standalone(
6768
"excerpt": child2.excerpt,
6869
"id": str(child2.id),
6970
"is_favorite": False,
71+
"is_masked": False,
7072
"link_reach": child2.link_reach,
7173
"link_role": child2.link_role,
7274
"numchild": 0,
@@ -119,6 +121,7 @@ def test_api_documents_children_list_anonymous_public_parent(django_assert_num_q
119121
"excerpt": child1.excerpt,
120122
"id": str(child1.id),
121123
"is_favorite": False,
124+
"is_masked": False,
122125
"link_reach": child1.link_reach,
123126
"link_role": child1.link_role,
124127
"numchild": 0,
@@ -141,6 +144,7 @@ def test_api_documents_children_list_anonymous_public_parent(django_assert_num_q
141144
"excerpt": child2.excerpt,
142145
"id": str(child2.id),
143146
"is_favorite": False,
147+
"is_masked": False,
144148
"link_reach": child2.link_reach,
145149
"link_role": child2.link_role,
146150
"numchild": 0,
@@ -212,6 +216,7 @@ def test_api_documents_children_list_authenticated_unrelated_public_or_authentic
212216
"excerpt": child1.excerpt,
213217
"id": str(child1.id),
214218
"is_favorite": False,
219+
"is_masked": False,
215220
"link_reach": child1.link_reach,
216221
"link_role": child1.link_role,
217222
"numchild": 0,
@@ -234,6 +239,7 @@ def test_api_documents_children_list_authenticated_unrelated_public_or_authentic
234239
"excerpt": child2.excerpt,
235240
"id": str(child2.id),
236241
"is_favorite": False,
242+
"is_masked": False,
237243
"link_reach": child2.link_reach,
238244
"link_role": child2.link_role,
239245
"numchild": 0,
@@ -291,6 +297,7 @@ def test_api_documents_children_list_authenticated_public_or_authenticated_paren
291297
"excerpt": child1.excerpt,
292298
"id": str(child1.id),
293299
"is_favorite": False,
300+
"is_masked": False,
294301
"link_reach": child1.link_reach,
295302
"link_role": child1.link_role,
296303
"numchild": 0,
@@ -313,6 +320,7 @@ def test_api_documents_children_list_authenticated_public_or_authenticated_paren
313320
"excerpt": child2.excerpt,
314321
"id": str(child2.id),
315322
"is_favorite": False,
323+
"is_masked": False,
316324
"link_reach": child2.link_reach,
317325
"link_role": child2.link_role,
318326
"numchild": 0,
@@ -397,6 +405,7 @@ def test_api_documents_children_list_authenticated_related_direct(
397405
"excerpt": child1.excerpt,
398406
"id": str(child1.id),
399407
"is_favorite": False,
408+
"is_masked": False,
400409
"link_reach": child1.link_reach,
401410
"link_role": child1.link_role,
402411
"numchild": 0,
@@ -419,6 +428,7 @@ def test_api_documents_children_list_authenticated_related_direct(
419428
"excerpt": child2.excerpt,
420429
"id": str(child2.id),
421430
"is_favorite": False,
431+
"is_masked": False,
422432
"link_reach": child2.link_reach,
423433
"link_role": child2.link_role,
424434
"numchild": 0,
@@ -479,6 +489,7 @@ def test_api_documents_children_list_authenticated_related_parent(
479489
"excerpt": child1.excerpt,
480490
"id": str(child1.id),
481491
"is_favorite": False,
492+
"is_masked": False,
482493
"link_reach": child1.link_reach,
483494
"link_role": child1.link_role,
484495
"numchild": 0,
@@ -501,6 +512,7 @@ def test_api_documents_children_list_authenticated_related_parent(
501512
"excerpt": child2.excerpt,
502513
"id": str(child2.id),
503514
"is_favorite": False,
515+
"is_masked": False,
504516
"link_reach": child2.link_reach,
505517
"link_role": child2.link_role,
506518
"numchild": 0,
@@ -613,6 +625,7 @@ def test_api_documents_children_list_authenticated_related_team_members(
613625
"excerpt": child1.excerpt,
614626
"id": str(child1.id),
615627
"is_favorite": False,
628+
"is_masked": False,
616629
"link_reach": child1.link_reach,
617630
"link_role": child1.link_role,
618631
"numchild": 0,
@@ -635,6 +648,7 @@ def test_api_documents_children_list_authenticated_related_team_members(
635648
"excerpt": child2.excerpt,
636649
"id": str(child2.id),
637650
"is_favorite": False,
651+
"is_masked": False,
638652
"link_reach": child2.link_reach,
639653
"link_role": child2.link_role,
640654
"numchild": 0,

0 commit comments

Comments
 (0)