Skip to content

Commit 04b8400

Browse files
sampaccoudAntoLC
authored andcommitted
✨(backend) add max_role field to the document access API endpoint
The frontend needs to know what to display on an access. The maximum role between the access role and the role equivalent to all accesses on the document's ancestors should be computed on the backend.
1 parent d232654 commit 04b8400

File tree

3 files changed

+49
-22
lines changed

3 files changed

+49
-22
lines changed

src/backend/core/api/serializers.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ class DocumentAccessSerializer(serializers.ModelSerializer):
306306
team = serializers.CharField(required=False, allow_blank=True)
307307
abilities = serializers.SerializerMethodField(read_only=True)
308308
max_ancestors_role = serializers.SerializerMethodField(read_only=True)
309+
max_role = serializers.SerializerMethodField(read_only=True)
309310

310311
class Meta:
311312
model = models.DocumentAccess
@@ -319,8 +320,15 @@ class Meta:
319320
"role",
320321
"abilities",
321322
"max_ancestors_role",
323+
"max_role",
324+
]
325+
read_only_fields = [
326+
"id",
327+
"document",
328+
"abilities",
329+
"max_ancestors_role",
330+
"max_role",
322331
]
323-
read_only_fields = ["id", "document", "abilities", "max_ancestors_role"]
324332

325333
def get_abilities(self, instance) -> dict:
326334
"""Return abilities of the logged-in user on the instance."""
@@ -333,6 +341,13 @@ def get_max_ancestors_role(self, instance):
333341
"""Return max_ancestors_role if annotated; else None."""
334342
return getattr(instance, "max_ancestors_role", None)
335343

344+
def get_max_role(self, instance):
345+
"""Return max_ancestors_role if annotated; else None."""
346+
return choices.RoleChoices.max(
347+
getattr(instance, "max_ancestors_role", None),
348+
instance.role,
349+
)
350+
336351
def update(self, instance, validated_data):
337352
"""Make "user" field readonly but only on update."""
338353
validated_data.pop("team", None)
@@ -356,6 +371,7 @@ class Meta:
356371
"role",
357372
"abilities",
358373
"max_ancestors_role",
374+
"max_role",
359375
]
360376
read_only_fields = [
361377
"id",
@@ -364,6 +380,7 @@ class Meta:
364380
"role",
365381
"abilities",
366382
"max_ancestors_role",
383+
"max_role",
367384
]
368385

369386

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ def test_api_document_accesses_list_authenticated_related_non_privileged(
153153
"team": access.team,
154154
"role": access.role,
155155
"max_ancestors_role": None,
156+
"max_role": access.role,
156157
"abilities": {
157158
"destroy": False,
158159
"partial_update": False,
@@ -253,6 +254,7 @@ def test_api_document_accesses_list_authenticated_related_privileged(
253254
if access.user
254255
else None,
255256
"max_ancestors_role": None,
257+
"max_role": access.role,
256258
"team": access.team,
257259
"role": access.role,
258260
"abilities": access.get_abilities(user),
@@ -617,6 +619,7 @@ def test_api_document_accesses_retrieve_authenticated_related(
617619
"team": "",
618620
"role": access.role,
619621
"max_ancestors_role": None,
622+
"max_role": access.role,
620623
"abilities": access.get_abilities(user),
621624
}
622625

@@ -775,10 +778,11 @@ def test_api_document_accesses_update_administrator_except_owner(
775778

776779
access.refresh_from_db()
777780
updated_values = serializers.DocumentAccessSerializer(instance=access).data
778-
if field == "role":
781+
if field in ["role", "max_role"]:
779782
assert updated_values == {
780783
**old_values,
781784
"role": new_values["role"],
785+
"max_role": new_values["role"],
782786
}
783787
else:
784788
assert updated_values == old_values
@@ -951,10 +955,11 @@ def test_api_document_accesses_update_owner(
951955
access.refresh_from_db()
952956
updated_values = serializers.DocumentAccessSerializer(instance=access).data
953957

954-
if field == "role":
958+
if field in ["role", "max_role"]:
955959
assert updated_values == {
956960
**old_values,
957961
"role": new_values["role"],
962+
"max_role": new_values["role"],
958963
}
959964
else:
960965
assert updated_values == old_values

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

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,11 @@ def test_api_document_accesses_create_authenticated_administrator_share_to_user(
176176
"path": new_document_access.document.path,
177177
},
178178
"id": str(new_document_access.id),
179-
"user": other_user,
180-
"team": "",
181-
"role": role,
182179
"max_ancestors_role": None,
180+
"max_role": role,
181+
"role": role,
182+
"team": "",
183+
"user": other_user,
183184
}
184185
assert len(mail.outbox) == 1
185186
email = mail.outbox[0]
@@ -266,10 +267,11 @@ def test_api_document_accesses_create_authenticated_administrator_share_to_team(
266267
"path": new_document_access.document.path,
267268
},
268269
"id": str(new_document_access.id),
269-
"user": None,
270-
"team": "new-team",
271-
"role": role,
272270
"max_ancestors_role": None,
271+
"max_role": role,
272+
"role": role,
273+
"team": "new-team",
274+
"user": None,
273275
}
274276
assert len(mail.outbox) == 0
275277

@@ -323,17 +325,18 @@ def test_api_document_accesses_create_authenticated_owner_share_to_user(
323325
new_document_access = models.DocumentAccess.objects.filter(user=other_user).get()
324326
other_user = serializers.UserSerializer(instance=other_user).data
325327
assert response.json() == {
328+
"abilities": new_document_access.get_abilities(user),
326329
"document": {
327330
"id": str(new_document_access.document_id),
328-
"path": new_document_access.document.path,
329331
"depth": new_document_access.document.depth,
332+
"path": new_document_access.document.path,
330333
},
331334
"id": str(new_document_access.id),
332-
"user": other_user,
333-
"team": "",
334-
"role": role,
335335
"max_ancestors_role": None,
336-
"abilities": new_document_access.get_abilities(user),
336+
"max_role": role,
337+
"role": role,
338+
"team": "",
339+
"user": other_user,
337340
}
338341
assert len(mail.outbox) == 1
339342
email = mail.outbox[0]
@@ -396,17 +399,18 @@ def test_api_document_accesses_create_authenticated_owner_share_to_team(
396399
new_document_access = models.DocumentAccess.objects.filter(team="new-team").get()
397400
other_user = serializers.UserSerializer(instance=other_user).data
398401
assert response.json() == {
402+
"abilities": new_document_access.get_abilities(user),
399403
"document": {
400404
"id": str(new_document_access.document_id),
401405
"path": new_document_access.document.path,
402406
"depth": new_document_access.document.depth,
403407
},
404408
"id": str(new_document_access.id),
405-
"user": None,
406-
"team": "new-team",
407-
"role": role,
408409
"max_ancestors_role": None,
409-
"abilities": new_document_access.get_abilities(user),
410+
"max_role": role,
411+
"role": role,
412+
"team": "new-team",
413+
"user": None,
410414
}
411415
assert len(mail.outbox) == 0
412416

@@ -457,17 +461,18 @@ def test_api_document_accesses_create_email_in_receivers_language(via, mock_user
457461
).get()
458462
other_user_data = serializers.UserSerializer(instance=other_user).data
459463
assert response.json() == {
464+
"abilities": new_document_access.get_abilities(user),
460465
"document": {
461466
"id": str(new_document_access.document_id),
462467
"path": new_document_access.document.path,
463468
"depth": new_document_access.document.depth,
464469
},
465470
"id": str(new_document_access.id),
466-
"user": other_user_data,
467-
"team": "",
468-
"role": role,
469471
"max_ancestors_role": None,
470-
"abilities": new_document_access.get_abilities(user),
472+
"max_role": role,
473+
"role": role,
474+
"team": "",
475+
"user": other_user_data,
471476
}
472477
assert len(mail.outbox) == index + 1
473478
email = mail.outbox[index]

0 commit comments

Comments
 (0)