(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.
This commit is contained in:
Samuel Paccoud - DINUM
2025-05-13 17:58:45 +02:00
committed by Anthony LC
parent d232654c55
commit 04b8400766
3 changed files with 49 additions and 22 deletions

View File

@@ -306,6 +306,7 @@ class DocumentAccessSerializer(serializers.ModelSerializer):
team = serializers.CharField(required=False, allow_blank=True)
abilities = serializers.SerializerMethodField(read_only=True)
max_ancestors_role = serializers.SerializerMethodField(read_only=True)
max_role = serializers.SerializerMethodField(read_only=True)
class Meta:
model = models.DocumentAccess
@@ -319,8 +320,15 @@ class DocumentAccessSerializer(serializers.ModelSerializer):
"role",
"abilities",
"max_ancestors_role",
"max_role",
]
read_only_fields = [
"id",
"document",
"abilities",
"max_ancestors_role",
"max_role",
]
read_only_fields = ["id", "document", "abilities", "max_ancestors_role"]
def get_abilities(self, instance) -> dict:
"""Return abilities of the logged-in user on the instance."""
@@ -333,6 +341,13 @@ class DocumentAccessSerializer(serializers.ModelSerializer):
"""Return max_ancestors_role if annotated; else None."""
return getattr(instance, "max_ancestors_role", None)
def get_max_role(self, instance):
"""Return max_ancestors_role if annotated; else None."""
return choices.RoleChoices.max(
getattr(instance, "max_ancestors_role", None),
instance.role,
)
def update(self, instance, validated_data):
"""Make "user" field readonly but only on update."""
validated_data.pop("team", None)
@@ -356,6 +371,7 @@ class DocumentAccessLightSerializer(DocumentAccessSerializer):
"role",
"abilities",
"max_ancestors_role",
"max_role",
]
read_only_fields = [
"id",
@@ -364,6 +380,7 @@ class DocumentAccessLightSerializer(DocumentAccessSerializer):
"role",
"abilities",
"max_ancestors_role",
"max_role",
]

View File

@@ -153,6 +153,7 @@ def test_api_document_accesses_list_authenticated_related_non_privileged(
"team": access.team,
"role": access.role,
"max_ancestors_role": None,
"max_role": access.role,
"abilities": {
"destroy": False,
"partial_update": False,
@@ -253,6 +254,7 @@ def test_api_document_accesses_list_authenticated_related_privileged(
if access.user
else None,
"max_ancestors_role": None,
"max_role": access.role,
"team": access.team,
"role": access.role,
"abilities": access.get_abilities(user),
@@ -617,6 +619,7 @@ def test_api_document_accesses_retrieve_authenticated_related(
"team": "",
"role": access.role,
"max_ancestors_role": None,
"max_role": access.role,
"abilities": access.get_abilities(user),
}
@@ -775,10 +778,11 @@ def test_api_document_accesses_update_administrator_except_owner(
access.refresh_from_db()
updated_values = serializers.DocumentAccessSerializer(instance=access).data
if field == "role":
if field in ["role", "max_role"]:
assert updated_values == {
**old_values,
"role": new_values["role"],
"max_role": new_values["role"],
}
else:
assert updated_values == old_values
@@ -951,10 +955,11 @@ def test_api_document_accesses_update_owner(
access.refresh_from_db()
updated_values = serializers.DocumentAccessSerializer(instance=access).data
if field == "role":
if field in ["role", "max_role"]:
assert updated_values == {
**old_values,
"role": new_values["role"],
"max_role": new_values["role"],
}
else:
assert updated_values == old_values

View File

@@ -176,10 +176,11 @@ def test_api_document_accesses_create_authenticated_administrator_share_to_user(
"path": new_document_access.document.path,
},
"id": str(new_document_access.id),
"user": other_user,
"team": "",
"role": role,
"max_ancestors_role": None,
"max_role": role,
"role": role,
"team": "",
"user": other_user,
}
assert len(mail.outbox) == 1
email = mail.outbox[0]
@@ -266,10 +267,11 @@ def test_api_document_accesses_create_authenticated_administrator_share_to_team(
"path": new_document_access.document.path,
},
"id": str(new_document_access.id),
"user": None,
"team": "new-team",
"role": role,
"max_ancestors_role": None,
"max_role": role,
"role": role,
"team": "new-team",
"user": None,
}
assert len(mail.outbox) == 0
@@ -323,17 +325,18 @@ def test_api_document_accesses_create_authenticated_owner_share_to_user(
new_document_access = models.DocumentAccess.objects.filter(user=other_user).get()
other_user = serializers.UserSerializer(instance=other_user).data
assert response.json() == {
"abilities": new_document_access.get_abilities(user),
"document": {
"id": str(new_document_access.document_id),
"path": new_document_access.document.path,
"depth": new_document_access.document.depth,
"path": new_document_access.document.path,
},
"id": str(new_document_access.id),
"user": other_user,
"team": "",
"role": role,
"max_ancestors_role": None,
"abilities": new_document_access.get_abilities(user),
"max_role": role,
"role": role,
"team": "",
"user": other_user,
}
assert len(mail.outbox) == 1
email = mail.outbox[0]
@@ -396,17 +399,18 @@ def test_api_document_accesses_create_authenticated_owner_share_to_team(
new_document_access = models.DocumentAccess.objects.filter(team="new-team").get()
other_user = serializers.UserSerializer(instance=other_user).data
assert response.json() == {
"abilities": new_document_access.get_abilities(user),
"document": {
"id": str(new_document_access.document_id),
"path": new_document_access.document.path,
"depth": new_document_access.document.depth,
},
"id": str(new_document_access.id),
"user": None,
"team": "new-team",
"role": role,
"max_ancestors_role": None,
"abilities": new_document_access.get_abilities(user),
"max_role": role,
"role": role,
"team": "new-team",
"user": None,
}
assert len(mail.outbox) == 0
@@ -457,17 +461,18 @@ def test_api_document_accesses_create_email_in_receivers_language(via, mock_user
).get()
other_user_data = serializers.UserSerializer(instance=other_user).data
assert response.json() == {
"abilities": new_document_access.get_abilities(user),
"document": {
"id": str(new_document_access.document_id),
"path": new_document_access.document.path,
"depth": new_document_access.document.depth,
},
"id": str(new_document_access.id),
"user": other_user_data,
"team": "",
"role": role,
"max_ancestors_role": None,
"abilities": new_document_access.get_abilities(user),
"max_role": role,
"role": role,
"team": "",
"user": other_user_data,
}
assert len(mail.outbox) == index + 1
email = mail.outbox[index]