diff --git a/CHANGELOG.md b/CHANGELOG.md index 48e8fe0b..66450106 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/backend/core/api/serializers.py b/src/backend/core/api/serializers.py index 6154ced3..d98049f2 100644 --- a/src/backend/core/api/serializers.py +++ b/src/backend/core/api/serializers.py @@ -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." diff --git a/src/backend/core/factories.py b/src/backend/core/factories.py index c410615f..2ca7d17a 100644 --- a/src/backend/core/factories.py +++ b/src/backend/core/factories.py @@ -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""" diff --git a/src/backend/core/tests/documents/test_api_document_accesses.py b/src/backend/core/tests/documents/test_api_document_accesses.py index 6431b850..9d04d924 100644 --- a/src/backend/core/tests/documents/test_api_document_accesses.py +++ b/src/backend/core/tests/documents/test_api_document_accesses.py @@ -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 diff --git a/src/backend/core/tests/documents/test_api_document_accesses_create.py b/src/backend/core/tests/documents/test_api_document_accesses_create.py index 9c453073..bd96d04d 100644 --- a/src/backend/core/tests/documents/test_api_document_accesses_create.py +++ b/src/backend/core/tests/documents/test_api_document_accesses_create.py @@ -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", diff --git a/src/backend/core/tests/documents/test_api_document_invitations.py b/src/backend/core/tests/documents/test_api_document_invitations.py index c9d0ecd6..f103b4f8 100644 --- a/src/backend/core/tests/documents/test_api_document_invitations.py +++ b/src/backend/core/tests/documents/test_api_document_invitations.py @@ -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) diff --git a/src/backend/core/tests/documents/test_api_document_versions.py b/src/backend/core/tests/documents/test_api_document_versions.py index 69181218..e91012b2 100644 --- a/src/backend/core/tests/documents/test_api_document_versions.py +++ b/src/backend/core/tests/documents/test_api_document_versions.py @@ -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) diff --git a/src/backend/core/tests/documents/test_api_documents_attachment_upload.py b/src/backend/core/tests/documents/test_api_documents_attachment_upload.py index fab6f65c..064d0c1f 100644 --- a/src/backend/core/tests/documents/test_api_documents_attachment_upload.py +++ b/src/backend/core/tests/documents/test_api_documents_attachment_upload.py @@ -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) diff --git a/src/backend/core/tests/documents/test_api_documents_delete.py b/src/backend/core/tests/documents/test_api_documents_delete.py index 9ce6e226..ba12c8ff 100644 --- a/src/backend/core/tests/documents/test_api_documents_delete.py +++ b/src/backend/core/tests/documents/test_api_documents_delete.py @@ -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) diff --git a/src/backend/core/tests/documents/test_api_documents_link_configuration.py b/src/backend/core/tests/documents/test_api_documents_link_configuration.py index 4f8340d3..91f4d7e6 100644 --- a/src/backend/core/tests/documents/test_api_documents_link_configuration.py +++ b/src/backend/core/tests/documents/test_api_documents_link_configuration.py @@ -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) diff --git a/src/backend/core/tests/documents/test_api_documents_retrieve.py b/src/backend/core/tests/documents/test_api_documents_retrieve.py index f37339f6..6d32ef08 100644 --- a/src/backend/core/tests/documents/test_api_documents_retrieve.py +++ b/src/backend/core/tests/documents/test_api_documents_retrieve.py @@ -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) diff --git a/src/backend/core/tests/documents/test_api_documents_retrieve_auth.py b/src/backend/core/tests/documents/test_api_documents_retrieve_auth.py index 9e02e17c..6de7cb39 100644 --- a/src/backend/core/tests/documents/test_api_documents_retrieve_auth.py +++ b/src/backend/core/tests/documents/test_api_documents_retrieve_auth.py @@ -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) diff --git a/src/backend/core/tests/documents/test_api_documents_update.py b/src/backend/core/tests/documents/test_api_documents_update.py index 5d400754..d0c1ae32 100644 --- a/src/backend/core/tests/documents/test_api_documents_update.py +++ b/src/backend/core/tests/documents/test_api_documents_update.py @@ -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) diff --git a/src/backend/core/tests/test_api_template_accesses.py b/src/backend/core/tests/templates/test_api_template_accesses.py similarity index 95% rename from src/backend/core/tests/test_api_template_accesses.py rename to src/backend/core/tests/templates/test_api_template_accesses.py index 734fa8b8..cca8deef 100644 --- a/src/backend/core/tests/test_api_template_accesses.py +++ b/src/backend/core/tests/templates/test_api_template_accesses.py @@ -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