✨(back) accept for a owner the request to access a document
Add the action accepting a request to access a document. It is possible to override the role from the request and also update an existing DocumentAccess
This commit is contained in:
@@ -665,10 +665,22 @@ class InvitationSerializer(serializers.ModelSerializer):
|
||||
return role
|
||||
|
||||
|
||||
class RoleSerializer(serializers.Serializer):
|
||||
"""Serializer validating role choices."""
|
||||
|
||||
role = serializers.ChoiceField(
|
||||
choices=models.RoleChoices.choices, required=False, allow_null=True
|
||||
)
|
||||
|
||||
|
||||
class DocumentAskForAccessCreateSerializer(serializers.Serializer):
|
||||
"""Serializer for creating a document ask for access."""
|
||||
|
||||
role = serializers.ChoiceField(choices=models.RoleChoices.choices, required=False, default=models.RoleChoices.READER)
|
||||
role = serializers.ChoiceField(
|
||||
choices=models.RoleChoices.choices,
|
||||
required=False,
|
||||
default=models.RoleChoices.READER,
|
||||
)
|
||||
|
||||
|
||||
class DocumentAskForAccessSerializer(serializers.ModelSerializer):
|
||||
@@ -695,7 +707,8 @@ class DocumentAskForAccessSerializer(serializers.ModelSerializer):
|
||||
if request:
|
||||
return invitation.get_abilities(request.user)
|
||||
return {}
|
||||
|
||||
|
||||
|
||||
class VersionFilterSerializer(serializers.Serializer):
|
||||
"""Validate version filters applied to the list endpoint."""
|
||||
|
||||
|
||||
@@ -1837,6 +1837,17 @@ class DocumentAskForAccessViewSet(
|
||||
|
||||
return drf.response.Response(status=drf.status.HTTP_201_CREATED)
|
||||
|
||||
@drf.decorators.action(detail=True, methods=["post"])
|
||||
def accept(self, request, *args, **kwargs):
|
||||
"""Accept a document ask for access resource."""
|
||||
document_ask_for_access = self.get_object()
|
||||
|
||||
serializer = serializers.RoleSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
document_ask_for_access.accept(role=serializer.validated_data.get("role"))
|
||||
return drf.response.Response(status=drf.status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
||||
class ConfigView(drf.views.APIView):
|
||||
"""API ViewSet for sharing some public settings."""
|
||||
|
||||
@@ -1205,8 +1205,22 @@ class DocumentAskForAccess(BaseModel):
|
||||
"update": is_admin_or_owner,
|
||||
"partial_update": is_admin_or_owner,
|
||||
"retrieve": is_admin_or_owner,
|
||||
"accept": is_admin_or_owner,
|
||||
}
|
||||
|
||||
def accept(self, role=None):
|
||||
"""Accept a document ask for access resource."""
|
||||
if role is None:
|
||||
role = self.role
|
||||
|
||||
DocumentAccess.objects.update_or_create(
|
||||
document=self.document,
|
||||
user=self.user,
|
||||
defaults={"role": role},
|
||||
create_defaults={"role": role},
|
||||
)
|
||||
self.delete()
|
||||
|
||||
|
||||
class Template(BaseModel):
|
||||
"""HTML and CSS code used for formatting the print around the MarkDown body."""
|
||||
|
||||
@@ -190,6 +190,7 @@ def test_api_documents_ask_for_access_list_authenticated_own_request():
|
||||
"+00:00", "Z"
|
||||
),
|
||||
"abilities": {
|
||||
"accept": False,
|
||||
"destroy": False,
|
||||
"update": False,
|
||||
"partial_update": False,
|
||||
@@ -277,6 +278,7 @@ def test_api_documents_ask_for_access_list_owner_or_admin(role):
|
||||
"+00:00", "Z"
|
||||
),
|
||||
"abilities": {
|
||||
"accept": True,
|
||||
"destroy": True,
|
||||
"update": True,
|
||||
"partial_update": True,
|
||||
@@ -365,6 +367,7 @@ def test_api_documents_ask_for_access_retrieve_owner_or_admin(role):
|
||||
"+00:00", "Z"
|
||||
),
|
||||
"abilities": {
|
||||
"accept": True,
|
||||
"destroy": True,
|
||||
"update": True,
|
||||
"partial_update": True,
|
||||
@@ -443,3 +446,172 @@ def test_api_documents_ask_for_access_delete_owner_or_admin(role):
|
||||
assert not DocumentAskForAccess.objects.filter(
|
||||
id=document_ask_for_access.id
|
||||
).exists()
|
||||
|
||||
|
||||
## Accept
|
||||
|
||||
|
||||
def test_api_documents_ask_for_access_accept_anonymous():
|
||||
"""Anonymous users should not be able to accept document ask for access."""
|
||||
document = DocumentFactory()
|
||||
document_ask_for_access = DocumentAskForAccessFactory(
|
||||
document=document, role=RoleChoices.READER
|
||||
)
|
||||
|
||||
client = APIClient()
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id}/ask-for-access/{document_ask_for_access.id}/accept/"
|
||||
)
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
def test_api_documents_ask_for_access_accept_authenticated():
|
||||
"""Authenticated users should not be able to accept document ask for access."""
|
||||
document = DocumentFactory()
|
||||
document_ask_for_access = DocumentAskForAccessFactory(
|
||||
document=document, role=RoleChoices.READER
|
||||
)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(UserFactory())
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id}/ask-for-access/{document_ask_for_access.id}/accept/"
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@pytest.mark.parametrize("role", [RoleChoices.READER, RoleChoices.EDITOR])
|
||||
def test_api_documents_ask_for_access_accept_authenticated_non_owner_or_admin(role):
|
||||
"""Non owner or admin users should not be able to accept document ask for access."""
|
||||
user = UserFactory()
|
||||
document = DocumentFactory(users=[(user, role)])
|
||||
document_ask_for_access = DocumentAskForAccessFactory(
|
||||
document=document, role=RoleChoices.READER
|
||||
)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id}/ask-for-access/{document_ask_for_access.id}/accept/"
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@pytest.mark.parametrize("role", [RoleChoices.OWNER, RoleChoices.ADMIN])
|
||||
def test_api_documents_ask_for_access_accept_owner_or_admin(role):
|
||||
"""Owner or admin users should be able to accept document ask for access."""
|
||||
user = UserFactory()
|
||||
document = DocumentFactory(users=[(user, role)])
|
||||
document_ask_for_access = DocumentAskForAccessFactory(
|
||||
document=document, role=RoleChoices.READER
|
||||
)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id}/ask-for-access/{document_ask_for_access.id}/accept/"
|
||||
)
|
||||
assert response.status_code == 204
|
||||
|
||||
assert not DocumentAskForAccess.objects.filter(
|
||||
id=document_ask_for_access.id
|
||||
).exists()
|
||||
assert DocumentAccess.objects.filter(
|
||||
document=document, user=document_ask_for_access.user, role=RoleChoices.READER
|
||||
).exists()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("role", [RoleChoices.OWNER, RoleChoices.ADMIN])
|
||||
def test_api_documents_ask_for_access_accept_authenticated_specific_role(role):
|
||||
"""
|
||||
Owner or admin users should be able to accept document ask for access with a specific role.
|
||||
"""
|
||||
user = UserFactory()
|
||||
document = DocumentFactory(users=[(user, role)])
|
||||
document_ask_for_access = DocumentAskForAccessFactory(
|
||||
document=document, role=RoleChoices.READER
|
||||
)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id}/ask-for-access/{document_ask_for_access.id}/accept/",
|
||||
data={"role": RoleChoices.EDITOR},
|
||||
)
|
||||
assert response.status_code == 204
|
||||
|
||||
assert not DocumentAskForAccess.objects.filter(
|
||||
id=document_ask_for_access.id
|
||||
).exists()
|
||||
assert DocumentAccess.objects.filter(
|
||||
document=document, user=document_ask_for_access.user, role=RoleChoices.EDITOR
|
||||
).exists()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("role", [RoleChoices.OWNER, RoleChoices.ADMIN])
|
||||
def test_api_documents_ask_for_access_accept_authenticated_owner_or_admin_update_access(
|
||||
role,
|
||||
):
|
||||
"""
|
||||
Owner or admin users should be able to accept document ask for access and update the access.
|
||||
"""
|
||||
user = UserFactory()
|
||||
document = DocumentFactory(users=[(user, role)])
|
||||
document_access = UserDocumentAccessFactory(
|
||||
document=document, role=RoleChoices.READER
|
||||
)
|
||||
document_ask_for_access = DocumentAskForAccessFactory(
|
||||
document=document, user=document_access.user, role=RoleChoices.EDITOR
|
||||
)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id}/ask-for-access/{document_ask_for_access.id}/accept/",
|
||||
data={"role": RoleChoices.EDITOR},
|
||||
)
|
||||
assert response.status_code == 204
|
||||
|
||||
assert not DocumentAskForAccess.objects.filter(
|
||||
id=document_ask_for_access.id
|
||||
).exists()
|
||||
document_access.refresh_from_db()
|
||||
assert document_access.role == RoleChoices.EDITOR
|
||||
|
||||
|
||||
@pytest.mark.parametrize("role", [RoleChoices.OWNER, RoleChoices.ADMIN])
|
||||
# pylint: disable=line-too-long
|
||||
def test_api_documents_ask_for_access_accept_authenticated_owner_or_admin_update_access_with_specific_role(
|
||||
role,
|
||||
):
|
||||
"""
|
||||
Owner or admin users should be able to accept document ask for access and update the access
|
||||
with a specific role.
|
||||
"""
|
||||
user = UserFactory()
|
||||
document = DocumentFactory(users=[(user, role)])
|
||||
document_access = UserDocumentAccessFactory(
|
||||
document=document, role=RoleChoices.READER
|
||||
)
|
||||
document_ask_for_access = DocumentAskForAccessFactory(
|
||||
document=document, user=document_access.user, role=RoleChoices.EDITOR
|
||||
)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id}/ask-for-access/{document_ask_for_access.id}/accept/",
|
||||
data={"role": RoleChoices.ADMIN},
|
||||
)
|
||||
assert response.status_code == 204
|
||||
|
||||
assert not DocumentAskForAccess.objects.filter(
|
||||
id=document_ask_for_access.id
|
||||
).exists()
|
||||
document_access.refresh_from_db()
|
||||
assert document_access.role == RoleChoices.ADMIN
|
||||
|
||||
Reference in New Issue
Block a user