Skip to content

Commit 066c26f

Browse files
committed
🔒️(backend) role in ask_for_access must be lower than user role
We check that the role set in a ask_for_access is not higher than the user's role accepting the request. We prevent case where ad min will grant a user owner in order to take control of the document. Only owner can accept an owner role.
1 parent 3d45c7c commit 066c26f

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

src/backend/core/api/viewsets.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2162,7 +2162,19 @@ def accept(self, request, *args, **kwargs):
21622162
serializer = serializers.RoleSerializer(data=request.data)
21632163
serializer.is_valid(raise_exception=True)
21642164

2165-
document_ask_for_access.accept(role=serializer.validated_data.get("role"))
2165+
document = self.get_document_or_404()
2166+
user_role = document.get_role(request.user)
2167+
target_role = serializer.validated_data.get("role")
2168+
2169+
if models.RoleChoices.get_priority(user_role) < models.RoleChoices.get_priority(
2170+
target_role
2171+
):
2172+
return drf.response.Response(
2173+
{"detail": "You cannot accept a role higher than your own."},
2174+
status=drf.status.HTTP_400_BAD_REQUEST,
2175+
)
2176+
2177+
document_ask_for_access.accept(role=target_role)
21662178
return drf.response.Response(status=drf.status.HTTP_204_NO_CONTENT)
21672179

21682180

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,53 @@ def test_api_documents_ask_for_access_accept_authenticated_owner_or_admin_update
749749
assert document_access.role == RoleChoices.ADMIN
750750

751751

752+
def test_api_documents_ask_for_access_accept_admin_cannot_accept_owner_role():
753+
"""
754+
Admin users should not be able to accept document ask for access with the owner role.
755+
"""
756+
user = UserFactory()
757+
document = DocumentFactory(users=[(user, RoleChoices.ADMIN)])
758+
document_ask_for_access = DocumentAskForAccessFactory(
759+
document=document, role=RoleChoices.READER
760+
)
761+
762+
client = APIClient()
763+
client.force_login(user)
764+
765+
response = client.post(
766+
f"/api/v1.0/documents/{document.id}/ask-for-access/{document_ask_for_access.id}/accept/",
767+
data={"role": RoleChoices.OWNER},
768+
)
769+
assert response.status_code == 400
770+
assert response.json() == {
771+
"detail": "You cannot accept a role higher than your own."
772+
}
773+
774+
775+
def test_api_documents_ask_for_access_accept_owner_can_accept_owner_role():
776+
"""
777+
Owner users should be able to accept document ask for access with the owner role.
778+
"""
779+
user = UserFactory()
780+
document = DocumentFactory(users=[(user, RoleChoices.OWNER)])
781+
document_ask_for_access = DocumentAskForAccessFactory(
782+
document=document, role=RoleChoices.READER
783+
)
784+
785+
client = APIClient()
786+
client.force_login(user)
787+
788+
response = client.post(
789+
f"/api/v1.0/documents/{document.id}/ask-for-access/{document_ask_for_access.id}/accept/",
790+
data={"role": RoleChoices.OWNER},
791+
)
792+
assert response.status_code == 204
793+
794+
assert not DocumentAskForAccess.objects.filter(
795+
id=document_ask_for_access.id
796+
).exists()
797+
798+
752799
@pytest.mark.parametrize("role", [RoleChoices.OWNER, RoleChoices.ADMIN])
753800
def test_api_documents_ask_for_access_accept_authenticated_non_root_document(role):
754801
"""

0 commit comments

Comments
 (0)