🐛(backend) fix dysfunctional permissions on document create
When creating a document access, users were benefitting on the targeted document from the highest access right they have among all documents. This is because we forgot to filter on the document ID when retrieving the role of the user. We improved all tests to secure this issue.
This commit is contained in:
committed by
Samuel Paccoud
parent
bbcb5e0cf1
commit
1fc3029d12
@@ -23,6 +23,9 @@ and this project adheres to
|
||||
|
||||
- 🐛(frontend) invalidate queries after removing user #336
|
||||
|
||||
## Fixed
|
||||
|
||||
- 🐛(backend) Fix dysfunctional permissions on document create #329
|
||||
|
||||
## [1.5.1] - 2024-10-10
|
||||
|
||||
@@ -30,7 +33,6 @@ and this project adheres to
|
||||
|
||||
- 🐛(db) fix users duplicate #316
|
||||
|
||||
|
||||
## [1.5.0] - 2024-10-09
|
||||
|
||||
## Added
|
||||
|
||||
@@ -69,6 +69,7 @@ class BaseAccessSerializer(serializers.ModelSerializer):
|
||||
if not self.Meta.model.objects.filter( # pylint: disable=no-member
|
||||
Q(user=user) | Q(team__in=user.teams),
|
||||
role__in=[models.RoleChoices.OWNER, models.RoleChoices.ADMIN],
|
||||
**{self.Meta.resource_field_name: resource_id}, # pylint: disable=no-member
|
||||
).exists():
|
||||
raise exceptions.PermissionDenied(
|
||||
"You are not allowed to manage accesses for this resource."
|
||||
|
||||
@@ -27,6 +27,24 @@ class UserFactory(factory.django.DjangoModelFactory):
|
||||
language = factory.fuzzy.FuzzyChoice([lang[0] for lang in settings.LANGUAGES])
|
||||
password = make_password("password")
|
||||
|
||||
@factory.post_generation
|
||||
def with_owned_document(self, create, extracted, **kwargs):
|
||||
"""
|
||||
Create a document for which the user is owner to check
|
||||
that there is no interference
|
||||
"""
|
||||
if create and (extracted is True):
|
||||
UserDocumentAccessFactory(user=self, role="owner")
|
||||
|
||||
@factory.post_generation
|
||||
def with_owned_template(self, create, extracted, **kwargs):
|
||||
"""
|
||||
Create a template for which the user is owner to check
|
||||
that there is no interference
|
||||
"""
|
||||
if create and (extracted is True):
|
||||
UserTemplateAccessFactory(user=self, role="owner")
|
||||
|
||||
|
||||
class DocumentFactory(factory.django.DjangoModelFactory):
|
||||
"""A factory to create documents"""
|
||||
|
||||
@@ -149,7 +149,7 @@ def test_api_document_accesses_retrieve_authenticated_unrelated():
|
||||
Authenticated users should not be allowed to retrieve a document access for
|
||||
a document to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -246,7 +246,7 @@ def test_api_document_accesses_update_authenticated_unrelated():
|
||||
Authenticated users should not be allowed to update a document access for a document to which
|
||||
they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -279,7 +279,7 @@ def test_api_document_accesses_update_authenticated_reader_or_editor(
|
||||
via, role, mock_user_teams
|
||||
):
|
||||
"""Readers or editors of a document should not be allowed to update its accesses."""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -321,7 +321,7 @@ def test_api_document_accesses_update_administrator_except_owner(via, mock_user_
|
||||
A user who is a direct administrator in a document should be allowed to update a user
|
||||
access for this document, as long as they don't try to set the role to owner.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -378,7 +378,7 @@ def test_api_document_accesses_update_administrator_from_owner(via, mock_user_te
|
||||
A user who is an administrator in a document, should not be allowed to update
|
||||
the user access of an "owner" for this document.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -425,7 +425,7 @@ def test_api_document_accesses_update_administrator_to_owner(via, mock_user_team
|
||||
A user who is an administrator in a document, should not be allowed to update
|
||||
the user access of another user to grant document ownership.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -479,7 +479,7 @@ def test_api_document_accesses_update_owner(via, mock_user_teams):
|
||||
A user who is an owner in a document should be allowed to update
|
||||
a user access for this document whatever the role.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -535,7 +535,7 @@ def test_api_document_accesses_update_owner_self(via, mock_user_teams):
|
||||
A user who is owner of a document should be allowed to update
|
||||
their own user access provided there are other owners in the document.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -605,7 +605,7 @@ def test_api_document_accesses_delete_authenticated():
|
||||
Authenticated users should not be allowed to delete a document access for a
|
||||
document to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -617,7 +617,7 @@ def test_api_document_accesses_delete_authenticated():
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert models.DocumentAccess.objects.count() == 1
|
||||
assert models.DocumentAccess.objects.count() == 2
|
||||
|
||||
|
||||
@pytest.mark.parametrize("role", ["reader", "editor"])
|
||||
@@ -627,7 +627,7 @@ def test_api_document_accesses_delete_reader_or_editor(via, role, mock_user_team
|
||||
Authenticated users should not be allowed to delete a document access for a
|
||||
document in which they are a simple reader or editor.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -643,7 +643,7 @@ def test_api_document_accesses_delete_reader_or_editor(via, role, mock_user_team
|
||||
|
||||
access = factories.UserDocumentAccessFactory(document=document)
|
||||
|
||||
assert models.DocumentAccess.objects.count() == 2
|
||||
assert models.DocumentAccess.objects.count() == 3
|
||||
assert models.DocumentAccess.objects.filter(user=access.user).exists()
|
||||
|
||||
response = client.delete(
|
||||
@@ -651,7 +651,7 @@ def test_api_document_accesses_delete_reader_or_editor(via, role, mock_user_team
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert models.DocumentAccess.objects.count() == 2
|
||||
assert models.DocumentAccess.objects.count() == 3
|
||||
|
||||
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
@@ -699,7 +699,7 @@ def test_api_document_accesses_delete_administrator_on_owners(via, mock_user_tea
|
||||
Users who are administrators in a document should not be allowed to delete an ownership
|
||||
access from the document.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -717,7 +717,7 @@ def test_api_document_accesses_delete_administrator_on_owners(via, mock_user_tea
|
||||
|
||||
access = factories.UserDocumentAccessFactory(document=document, role="owner")
|
||||
|
||||
assert models.DocumentAccess.objects.count() == 2
|
||||
assert models.DocumentAccess.objects.count() == 3
|
||||
assert models.DocumentAccess.objects.filter(user=access.user).exists()
|
||||
|
||||
response = client.delete(
|
||||
@@ -725,7 +725,7 @@ def test_api_document_accesses_delete_administrator_on_owners(via, mock_user_tea
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert models.DocumentAccess.objects.count() == 2
|
||||
assert models.DocumentAccess.objects.count() == 3
|
||||
|
||||
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
@@ -766,7 +766,7 @@ def test_api_document_accesses_delete_owners_last_owner(via, mock_user_teams):
|
||||
"""
|
||||
It should not be possible to delete the last owner access from a document
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -783,10 +783,10 @@ def test_api_document_accesses_delete_owners_last_owner(via, mock_user_teams):
|
||||
document=document, team="lasuite", role="owner"
|
||||
)
|
||||
|
||||
assert models.DocumentAccess.objects.count() == 1
|
||||
assert models.DocumentAccess.objects.count() == 2
|
||||
response = client.delete(
|
||||
f"/api/v1.0/documents/{document.id!s}/accesses/{access.id!s}/",
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert models.DocumentAccess.objects.count() == 1
|
||||
assert models.DocumentAccess.objects.count() == 2
|
||||
|
||||
@@ -18,13 +18,13 @@ pytestmark = pytest.mark.django_db
|
||||
|
||||
def test_api_document_accesses_create_anonymous():
|
||||
"""Anonymous users should not be allowed to create document accesses."""
|
||||
user = factories.UserFactory()
|
||||
document = factories.DocumentFactory()
|
||||
|
||||
other_user = factories.UserFactory()
|
||||
response = APIClient().post(
|
||||
f"/api/v1.0/documents/{document.id!s}/accesses/",
|
||||
{
|
||||
"user": str(user.id),
|
||||
"user_id": str(other_user.id),
|
||||
"document": str(document.id),
|
||||
"role": random.choice(models.RoleChoices.choices)[0],
|
||||
},
|
||||
@@ -43,7 +43,7 @@ def test_api_document_accesses_create_authenticated_unrelated():
|
||||
Authenticated users should not be allowed to create document accesses for a document to
|
||||
which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -54,7 +54,7 @@ def test_api_document_accesses_create_authenticated_unrelated():
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id!s}/accesses/",
|
||||
{
|
||||
"user": str(other_user.id),
|
||||
"user_id": str(other_user.id),
|
||||
},
|
||||
format="json",
|
||||
)
|
||||
@@ -69,7 +69,7 @@ def test_api_document_accesses_create_authenticated_reader_or_editor(
|
||||
via, role, mock_user_teams
|
||||
):
|
||||
"""Readers or editors of a document should not be allowed to create document accesses."""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -89,7 +89,7 @@ def test_api_document_accesses_create_authenticated_reader_or_editor(
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id!s}/accesses/",
|
||||
{
|
||||
"user": str(other_user.id),
|
||||
"user_id": str(other_user.id),
|
||||
"role": new_role,
|
||||
},
|
||||
format="json",
|
||||
@@ -107,7 +107,7 @@ def test_api_document_accesses_create_authenticated_administrator(via, mock_user
|
||||
except for the "owner" role.
|
||||
An email should be sent to the accesses to notify them of the adding.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -129,7 +129,7 @@ def test_api_document_accesses_create_authenticated_administrator(via, mock_user
|
||||
response = client.post(
|
||||
f"/api/v1.0/documents/{document.id!s}/accesses/",
|
||||
{
|
||||
"user": str(other_user.id),
|
||||
"user_id": str(other_user.id),
|
||||
"role": "owner",
|
||||
},
|
||||
format="json",
|
||||
|
||||
@@ -601,7 +601,7 @@ def test_api_document_invitations__update__forbidden__not_authenticated(
|
||||
"""
|
||||
Update of invitations is currently forbidden.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
invitation = factories.InvitationFactory()
|
||||
if via == USER:
|
||||
factories.UserDocumentAccessFactory(
|
||||
@@ -641,7 +641,7 @@ def test_api_document_invitations__delete__anonymous():
|
||||
|
||||
def test_api_document_invitations__delete__authenticated_outsider():
|
||||
"""Members unrelated to a document should not be allowed to cancel invitations."""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
document = factories.DocumentFactory()
|
||||
invitation = factories.InvitationFactory(document=document)
|
||||
@@ -684,7 +684,7 @@ def test_api_document_invitations__delete__privileged_members(
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
def test_api_document_invitations_delete_readers_or_editors(via, role, mock_user_teams):
|
||||
"""Readers or editors should not be able to cancel invitation."""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
document = factories.DocumentFactory()
|
||||
if via == USER:
|
||||
factories.UserDocumentAccessFactory(document=document, user=user, role=role)
|
||||
|
||||
@@ -39,7 +39,7 @@ def test_api_document_versions_list_authenticated_unrelated(reach):
|
||||
Authenticated users should not be allowed to list document versions for a document
|
||||
to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -231,7 +231,7 @@ def test_api_document_versions_retrieve_authenticated_unrelated(reach):
|
||||
Authenticated users should not be allowed to retrieve specific versions for a
|
||||
document to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -475,7 +475,7 @@ def test_api_document_versions_delete_authenticated(reach):
|
||||
Authenticated users should not be allowed to delete a document version for a
|
||||
public document to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -500,7 +500,7 @@ def test_api_document_versions_delete_reader_or_editor(via, role, mock_user_team
|
||||
Authenticated users should not be allowed to delete a document version for a
|
||||
document in which they are a simple reader or editor.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
@@ -79,7 +79,7 @@ def test_api_documents_attachment_upload_authenticated_forbidden(reach, role):
|
||||
Users who are not related to a document can't upload attachments if the
|
||||
link reach and role don't allow it.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -134,7 +134,7 @@ def test_api_documents_attachment_upload_reader(via, mock_user_teams):
|
||||
"""
|
||||
Users who are simple readers on a document should not be allowed to upload an attachment.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
@@ -30,7 +30,7 @@ def test_api_documents_delete_authenticated_unrelated(reach, role):
|
||||
Authenticated users should not be allowed to delete a document to which
|
||||
they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -42,7 +42,7 @@ def test_api_documents_delete_authenticated_unrelated(reach, role):
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert models.Document.objects.count() == 1
|
||||
assert models.Document.objects.count() == 2
|
||||
|
||||
|
||||
@pytest.mark.parametrize("role", ["reader", "editor", "administrator"])
|
||||
@@ -52,7 +52,7 @@ def test_api_documents_delete_authenticated_not_owner(via, role, mock_user_teams
|
||||
Authenticated users should not be allowed to delete a document for which they are
|
||||
only a reader, editor or administrator.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -74,7 +74,7 @@ def test_api_documents_delete_authenticated_not_owner(via, role, mock_user_teams
|
||||
assert response.json() == {
|
||||
"detail": "You do not have permission to perform this action."
|
||||
}
|
||||
assert models.Document.objects.count() == 1
|
||||
assert models.Document.objects.count() == 2
|
||||
|
||||
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
|
||||
@@ -42,7 +42,7 @@ def test_api_documents_link_configuration_update_authenticated_unrelated(reach,
|
||||
Authenticated users should not be allowed to update the link configuration for
|
||||
a document to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -78,7 +78,7 @@ def test_api_documents_link_configuration_update_authenticated_related_forbidden
|
||||
Users who are readers or editors of a document should not be allowed to update
|
||||
the link configuration.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
@@ -133,7 +133,7 @@ def test_api_documents_retrieve_authenticated_unrelated_restricted():
|
||||
Authenticated users should not be allowed to retrieve a document that is restricted and
|
||||
to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -208,7 +208,7 @@ def test_api_documents_retrieve_authenticated_related_team_none(mock_user_teams)
|
||||
"""
|
||||
mock_user_teams.return_value = []
|
||||
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
@@ -142,7 +142,7 @@ def test_api_documents_retrieve_auth_authenticated_restricted():
|
||||
"""
|
||||
document = factories.DocumentFactory(link_reach="restricted")
|
||||
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
|
||||
@@ -66,14 +66,14 @@ def test_api_documents_update_authenticated_unrelated_forbidden(reach, role):
|
||||
Authenticated users should not be allowed to update a document to which
|
||||
they are not related if the link configuration does not allow it.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
document = factories.DocumentFactory(link_reach=reach, link_role=role)
|
||||
old_document_values = serializers.DocumentSerializer(instance=document).data
|
||||
|
||||
old_document_values = serializers.DocumentSerializer(instance=document).data
|
||||
new_document_values = serializers.DocumentSerializer(
|
||||
instance=factories.DocumentFactory()
|
||||
).data
|
||||
@@ -111,14 +111,14 @@ def test_api_documents_update_anonymous_or_authenticated_unrelated(
|
||||
client = APIClient()
|
||||
|
||||
if is_authenticated:
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
client.force_login(user)
|
||||
else:
|
||||
user = AnonymousUser()
|
||||
|
||||
document = factories.DocumentFactory(link_reach=reach, link_role=role)
|
||||
old_document_values = serializers.DocumentSerializer(instance=document).data
|
||||
|
||||
old_document_values = serializers.DocumentSerializer(instance=document).data
|
||||
new_document_values = serializers.DocumentSerializer(
|
||||
instance=factories.DocumentFactory()
|
||||
).data
|
||||
@@ -146,7 +146,7 @@ def test_api_documents_update_authenticated_reader(via, mock_user_teams):
|
||||
Users who are reader of a document but not administrators should
|
||||
not be allowed to update it.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -187,7 +187,7 @@ def test_api_documents_update_authenticated_editor_administrator_or_owner(
|
||||
via, role, mock_user_teams
|
||||
):
|
||||
"""A user who is editor, administrator or owner of a document should be allowed to update it."""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -227,7 +227,7 @@ def test_api_documents_update_authenticated_editor_administrator_or_owner(
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
def test_api_documents_update_authenticated_owners(via, mock_user_teams):
|
||||
"""Administrators of a document should be allowed to update it."""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -269,7 +269,7 @@ def test_api_documents_update_administrator_or_owner_of_another(via, mock_user_t
|
||||
Being administrator or owner of a document should not grant authorization to update
|
||||
another document.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_document=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""
|
||||
Test template accesses API endpoints for users in impress's core app.
|
||||
"""
|
||||
# pylint: disable=too-many-lines
|
||||
|
||||
import random
|
||||
from uuid import uuid4
|
||||
@@ -32,7 +33,7 @@ def test_api_template_accesses_list_authenticated_unrelated():
|
||||
Authenticated users should not be allowed to list template accesses for a template
|
||||
to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -62,7 +63,7 @@ def test_api_template_accesses_list_authenticated_related(via, mock_user_teams):
|
||||
Authenticated users should be able to list template accesses for a template
|
||||
to which they are directly related, whatever their role in the template.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -146,7 +147,7 @@ def test_api_template_accesses_retrieve_authenticated_unrelated():
|
||||
Authenticated users should not be allowed to retrieve a template access for
|
||||
a template to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -183,7 +184,7 @@ def test_api_template_accesses_retrieve_authenticated_related(via, mock_user_tea
|
||||
A user who is related to a template should be allowed to retrieve the
|
||||
associated template user accesses.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -213,13 +214,13 @@ def test_api_template_accesses_retrieve_authenticated_related(via, mock_user_tea
|
||||
|
||||
def test_api_template_accesses_create_anonymous():
|
||||
"""Anonymous users should not be allowed to create template accesses."""
|
||||
user = factories.UserFactory()
|
||||
template = factories.TemplateFactory()
|
||||
|
||||
other_user = factories.UserFactory()
|
||||
response = APIClient().post(
|
||||
f"/api/v1.0/templates/{template.id!s}/accesses/",
|
||||
{
|
||||
"user": str(user.id),
|
||||
"user": str(other_user.id),
|
||||
"template": str(template.id),
|
||||
"role": random.choice(models.RoleChoices.choices)[0],
|
||||
},
|
||||
@@ -238,7 +239,7 @@ def test_api_template_accesses_create_authenticated_unrelated():
|
||||
Authenticated users should not be allowed to create template accesses for a template to
|
||||
which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -264,7 +265,7 @@ def test_api_template_accesses_create_authenticated_editor_or_reader(
|
||||
via, role, mock_user_teams
|
||||
):
|
||||
"""Editors or readers of a template should not be allowed to create template accesses."""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -301,7 +302,7 @@ def test_api_template_accesses_create_authenticated_administrator(via, mock_user
|
||||
Administrators of a template should be able to create template accesses
|
||||
except for the "owner" role.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -365,7 +366,7 @@ def test_api_template_accesses_create_authenticated_owner(via, mock_user_teams):
|
||||
"""
|
||||
Owners of a template should be able to create template accesses whatever the role.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -434,14 +435,14 @@ def test_api_template_accesses_update_authenticated_unrelated():
|
||||
Authenticated users should not be allowed to update a template access for a template to which
|
||||
they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
access = factories.UserTemplateAccessFactory()
|
||||
old_values = serializers.TemplateAccessSerializer(instance=access).data
|
||||
|
||||
old_values = serializers.TemplateAccessSerializer(instance=access).data
|
||||
new_values = {
|
||||
"id": uuid4(),
|
||||
"user": factories.UserFactory().id,
|
||||
@@ -467,7 +468,7 @@ def test_api_template_accesses_update_authenticated_editor_or_reader(
|
||||
via, role, mock_user_teams
|
||||
):
|
||||
"""Editors or readers of a template should not be allowed to update its accesses."""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -509,7 +510,7 @@ def test_api_template_accesses_update_administrator_except_owner(via, mock_user_
|
||||
A user who is a direct administrator in a template should be allowed to update a user
|
||||
access for this template, as long as they don't try to set the role to owner.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -529,8 +530,8 @@ def test_api_template_accesses_update_administrator_except_owner(via, mock_user_
|
||||
template=template,
|
||||
role=random.choice(["administrator", "editor", "reader"]),
|
||||
)
|
||||
old_values = serializers.TemplateAccessSerializer(instance=access).data
|
||||
|
||||
old_values = serializers.TemplateAccessSerializer(instance=access).data
|
||||
new_values = {
|
||||
"id": uuid4(),
|
||||
"user_id": factories.UserFactory().id,
|
||||
@@ -566,7 +567,7 @@ def test_api_template_accesses_update_administrator_from_owner(via, mock_user_te
|
||||
A user who is an administrator in a template, should not be allowed to update
|
||||
the user access of an "owner" for this template.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -586,8 +587,8 @@ def test_api_template_accesses_update_administrator_from_owner(via, mock_user_te
|
||||
access = factories.UserTemplateAccessFactory(
|
||||
template=template, user=other_user, role="owner"
|
||||
)
|
||||
old_values = serializers.TemplateAccessSerializer(instance=access).data
|
||||
|
||||
old_values = serializers.TemplateAccessSerializer(instance=access).data
|
||||
new_values = {
|
||||
"id": uuid4(),
|
||||
"user_id": factories.UserFactory().id,
|
||||
@@ -613,7 +614,7 @@ def test_api_template_accesses_update_administrator_to_owner(via, mock_user_team
|
||||
A user who is an administrator in a template, should not be allowed to update
|
||||
the user access of another user to grant template ownership.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -635,8 +636,8 @@ def test_api_template_accesses_update_administrator_to_owner(via, mock_user_team
|
||||
user=other_user,
|
||||
role=random.choice(["administrator", "editor", "reader"]),
|
||||
)
|
||||
old_values = serializers.TemplateAccessSerializer(instance=access).data
|
||||
|
||||
old_values = serializers.TemplateAccessSerializer(instance=access).data
|
||||
new_values = {
|
||||
"id": uuid4(),
|
||||
"user_id": factories.UserFactory().id,
|
||||
@@ -667,7 +668,7 @@ def test_api_template_accesses_update_owner(via, mock_user_teams):
|
||||
A user who is an owner in a template should be allowed to update
|
||||
a user access for this template whatever the role.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -685,8 +686,8 @@ def test_api_template_accesses_update_owner(via, mock_user_teams):
|
||||
access = factories.UserTemplateAccessFactory(
|
||||
template=template,
|
||||
)
|
||||
old_values = serializers.TemplateAccessSerializer(instance=access).data
|
||||
|
||||
old_values = serializers.TemplateAccessSerializer(instance=access).data
|
||||
new_values = {
|
||||
"id": uuid4(),
|
||||
"user_id": factories.UserFactory().id,
|
||||
@@ -723,22 +724,21 @@ def test_api_template_accesses_update_owner_self(via, mock_user_teams):
|
||||
A user who is owner of a template should be allowed to update
|
||||
their own user access provided there are other owners in the template.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
template = factories.TemplateFactory()
|
||||
access = None
|
||||
if via == USER:
|
||||
access = factories.UserTemplateAccessFactory(
|
||||
template=template, user=user, role="owner"
|
||||
)
|
||||
elif via == TEAM:
|
||||
if via == TEAM:
|
||||
mock_user_teams.return_value = ["lasuite", "unknown"]
|
||||
access = factories.TeamTemplateAccessFactory(
|
||||
template=template, team="lasuite", role="owner"
|
||||
)
|
||||
else:
|
||||
access = factories.UserTemplateAccessFactory(
|
||||
template=template, user=user, role="owner"
|
||||
)
|
||||
|
||||
old_values = serializers.TemplateAccessSerializer(instance=access).data
|
||||
new_role = random.choice(["administrator", "editor", "reader"])
|
||||
@@ -787,7 +787,7 @@ def test_api_template_accesses_delete_authenticated():
|
||||
Authenticated users should not be allowed to delete a template access for a
|
||||
template to which they are not related.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -799,7 +799,7 @@ def test_api_template_accesses_delete_authenticated():
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert models.TemplateAccess.objects.count() == 1
|
||||
assert models.TemplateAccess.objects.count() == 2
|
||||
|
||||
|
||||
@pytest.mark.parametrize("role", ["reader", "editor"])
|
||||
@@ -809,7 +809,7 @@ def test_api_template_accesses_delete_editor_or_reader(via, role, mock_user_team
|
||||
Authenticated users should not be allowed to delete a template access for a
|
||||
template in which they are a simple editor or reader.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -825,7 +825,7 @@ def test_api_template_accesses_delete_editor_or_reader(via, role, mock_user_team
|
||||
|
||||
access = factories.UserTemplateAccessFactory(template=template)
|
||||
|
||||
assert models.TemplateAccess.objects.count() == 2
|
||||
assert models.TemplateAccess.objects.count() == 3
|
||||
assert models.TemplateAccess.objects.filter(user=access.user).exists()
|
||||
|
||||
response = client.delete(
|
||||
@@ -833,7 +833,7 @@ def test_api_template_accesses_delete_editor_or_reader(via, role, mock_user_team
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert models.TemplateAccess.objects.count() == 2
|
||||
assert models.TemplateAccess.objects.count() == 3
|
||||
|
||||
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
@@ -881,7 +881,7 @@ def test_api_template_accesses_delete_administrator_on_owners(via, mock_user_tea
|
||||
Users who are administrators in a template should not be allowed to delete an ownership
|
||||
access from the template.
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -899,7 +899,7 @@ def test_api_template_accesses_delete_administrator_on_owners(via, mock_user_tea
|
||||
|
||||
access = factories.UserTemplateAccessFactory(template=template, role="owner")
|
||||
|
||||
assert models.TemplateAccess.objects.count() == 2
|
||||
assert models.TemplateAccess.objects.count() == 3
|
||||
assert models.TemplateAccess.objects.filter(user=access.user).exists()
|
||||
|
||||
response = client.delete(
|
||||
@@ -907,7 +907,7 @@ def test_api_template_accesses_delete_administrator_on_owners(via, mock_user_tea
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert models.TemplateAccess.objects.count() == 2
|
||||
assert models.TemplateAccess.objects.count() == 3
|
||||
|
||||
|
||||
@pytest.mark.parametrize("via", VIA)
|
||||
@@ -948,7 +948,7 @@ def test_api_template_accesses_delete_owners_last_owner(via, mock_user_teams):
|
||||
"""
|
||||
It should not be possible to delete the last owner access from a template
|
||||
"""
|
||||
user = factories.UserFactory()
|
||||
user = factories.UserFactory(with_owned_template=True)
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
@@ -965,10 +965,10 @@ def test_api_template_accesses_delete_owners_last_owner(via, mock_user_teams):
|
||||
template=template, team="lasuite", role="owner"
|
||||
)
|
||||
|
||||
assert models.TemplateAccess.objects.count() == 1
|
||||
assert models.TemplateAccess.objects.count() == 2
|
||||
response = client.delete(
|
||||
f"/api/v1.0/templates/{template.id!s}/accesses/{access.id!s}/",
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
assert models.TemplateAccess.objects.count() == 1
|
||||
assert models.TemplateAccess.objects.count() == 2
|
||||
Reference in New Issue
Block a user