From 11b6cc061c8084d44f5f5139cecfc1b413f4fb8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Thu, 17 Mar 2016 19:46:34 +0100 Subject: [PATCH] Transfer project ownership to no admin members too --- taiga/projects/api.py | 9 +- taiga/projects/permissions.py | 6 +- taiga/projects/services/transfer.py | 9 +- tests/factories.py | 8 +- tests/integration/test_projects.py | 343 +++++++++++++++------------- 5 files changed, 205 insertions(+), 170 deletions(-) diff --git a/taiga/projects/api.py b/taiga/projects/api.py index 43388afa..ee8aa50d 100644 --- a/taiga/projects/api.py +++ b/taiga/projects/api.py @@ -358,15 +358,12 @@ class ProjectViewSet(LikedResourceMixin, HistoryResourceMixin, user_model = apps.get_model("users", "User") try: user = user_model.objects.get(id=user_id) - except user_model.DoesNotExist: return response.BadRequest(_("The user doesn't exist")) - # Check the user is an admin membership from the project - try: - project.memberships.get(is_admin=True, user=user) - except apps.get_model("projects", "Membership").DoesNotExist: - return response.BadRequest(_("The user must be an admin member of the project")) + # Check the user is a membership from the project + if not project.memberships.filter(user=user).exists(): + return response.BadRequest(_("The user must be a member of the project")) reason = request.DATA.get('reason', None) transfer_token = services.start_project_transfer(project, user, reason) diff --git a/taiga/projects/permissions.py b/taiga/projects/permissions.py index 0db55117..de65cd69 100644 --- a/taiga/projects/permissions.py +++ b/taiga/projects/permissions.py @@ -77,11 +77,11 @@ class ProjectPermission(TaigaResourcePermission): unwatch_perms = IsAuthenticated() & HasProjectPerm('view_project') create_template_perms = IsSuperUser() leave_perms = CanLeaveProject() - transfer_validate_token_perms = IsProjectAdmin() + transfer_validate_token_perms = IsAuthenticated() & HasProjectPerm('view_project') transfer_request_perms = IsProjectAdmin() transfer_start_perms = IsMainOwner() - transfer_reject_perms = IsProjectAdmin() - transfer_accept_perms = IsProjectAdmin() + transfer_reject_perms = IsAuthenticated() & HasProjectPerm('view_project') + transfer_accept_perms = IsAuthenticated() & HasProjectPerm('view_project') class ProjectFansPermission(TaigaResourcePermission): diff --git a/taiga/projects/services/transfer.py b/taiga/projects/services/transfer.py index fcd73ef0..17b0bbb1 100644 --- a/taiga/projects/services/transfer.py +++ b/taiga/projects/services/transfer.py @@ -90,12 +90,19 @@ def reject_project_transfer(project, user, token, reason): def accept_project_transfer(project, user, token, reason): validate_project_transfer_token(token, project, user) - old_owner = project.owner + # Set new owner as project admin + membership = project.memberships.get(user=user) + if not membership.is_admin: + membership.is_admin = True + membership.save() + # Change the owner of the project + old_owner = project.owner project.transfer_token = None project.owner = user project.save() + # Send mail template = mail_builder.transfer_accept context = { "project": project, diff --git a/tests/factories.py b/tests/factories.py index d5d6d06b..71de1044 100644 --- a/tests/factories.py +++ b/tests/factories.py @@ -26,6 +26,9 @@ from .utils import DUMMY_BMP_DATA import factory +from taiga.permissions.permissions import MEMBERS_PERMISSIONS + + class Factory(factory.DjangoModelFactory): class Meta: @@ -555,8 +558,9 @@ def create_membership(**kwargs): defaults = { "project": project, - "user": project.owner, - "role": RoleFactory.create(project=project) + "user": UserFactory.create(), + "role": RoleFactory.create(project=project, + permissions=list(map(lambda x: x[0], MEMBERS_PERMISSIONS))) } defaults.update(kwargs) diff --git a/tests/integration/test_projects.py b/tests/integration/test_projects.py index 0a0be800..f467302b 100644 --- a/tests/integration/test_projects.py +++ b/tests/integration/test_projects.py @@ -739,6 +739,11 @@ def test_project_list_with_search_query_order_by_ranking(client): assert response.data[2]["id"] == project1.id +#################################################################################### +# Test transfer project ownership +#################################################################################### + + def test_transfer_request_from_not_anonimous(client): user = f.UserFactory.create() project = f.create_project(anon_permissions=["view_project"]) @@ -770,7 +775,7 @@ def test_transfer_request_from_not_admin_member(client): user = f.UserFactory.create() project = f.create_project() role = f.RoleFactory(project=project, permissions=["view_project"]) - f.MembershipFactory(user=user, project=project, role=role, is_admin=False) + f.create_membership(user=user, project=project, role=role, is_admin=False) url = reverse("projects-transfer-request", args=(project.id,)) @@ -786,7 +791,7 @@ def test_transfer_request_from_admin_member(client): user = f.UserFactory.create() project = f.create_project() role = f.RoleFactory(project=project, permissions=["view_project"]) - f.MembershipFactory(user=user, project=project, role=role, is_admin=True) + f.create_membership(user=user, project=project, role=role, is_admin=True) url = reverse("projects-transfer-request", args=(project.id,)) @@ -801,7 +806,7 @@ def test_transfer_request_from_admin_member(client): def test_project_transfer_start_to_not_a_membership(client): user_from = f.UserFactory.create() project = f.create_project(owner=user_from) - f.MembershipFactory(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) client.login(user_from) url = reverse("projects-transfer-start", kwargs={"pk": project.pk}) @@ -814,30 +819,12 @@ def test_project_transfer_start_to_not_a_membership(client): assert "The user doesn't exist" in response.data -def test_project_transfer_start_to_not_a_membership_admin(client): +def test_project_transfer_start_to_a_not_admin_member(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() project = f.create_project(owner=user_from) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project) - - client.login(user_from) - url = reverse("projects-transfer-start", kwargs={"pk": project.pk}) - - data = { - "user": user_to.id, - } - response = client.json.post(url, json.dumps(data)) - assert response.status_code == 400 - assert "The user must be" in response.data - - -def test_project_transfer_start_to_a_valid_user(client): - user_from = f.UserFactory.create() - user_to = f.UserFactory.create() - project = f.create_project(owner=user_from) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_from) url = reverse("projects-transfer-start", kwargs={"pk": project.pk}) @@ -855,7 +842,30 @@ def test_project_transfer_start_to_a_valid_user(client): assert len(mail.outbox) == 1 -def test_project_transfer_reject_from_admin_member_without_token(client): +def test_project_transfer_start_to_an_admin_member(client): + user_from = f.UserFactory.create() + user_to = f.UserFactory.create() + project = f.create_project(owner=user_from) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project, is_admin=True) + + client.login(user_from) + url = reverse("projects-transfer-start", kwargs={"pk": project.pk}) + + data = { + "user": user_to.id, + } + mail.outbox = [] + + assert project.transfer_token is None + response = client.json.post(url, json.dumps(data)) + assert response.status_code == 200 + project = Project.objects.get(id=project.id) + assert project.transfer_token is not None + assert len(mail.outbox) == 1 + + +def test_project_transfer_reject_from_member_without_token(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() @@ -863,8 +873,8 @@ def test_project_transfer_reject_from_admin_member_without_token(client): token = signer.sign(user_to.id) project = f.create_project(owner=user_from, transfer_token=token) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-reject", kwargs={"pk": project.pk}) @@ -878,39 +888,14 @@ def test_project_transfer_reject_from_admin_member_without_token(client): assert len(mail.outbox) == 0 -def test_project_transfer_reject_from_not_admin_member(client): - user_from = f.UserFactory.create() - user_to = f.UserFactory.create() - - signer = signing.TimestampSigner() - token = signer.sign(user_to.id) - project = f.create_project(owner=user_from, transfer_token=token, public_permissions=["view_project"]) - - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=False) - - client.login(user_to) - url = reverse("projects-transfer-reject", kwargs={"pk": project.pk}) - - data = { - "token": token, - } - mail.outbox = [] - - response = client.json.post(url, json.dumps(data)) - - assert response.status_code == 403 - assert len(mail.outbox) == 0 - - -def test_project_transfer_reject_from_admin_member_with_invalid_token(client): +def test_project_transfer_reject_from_member_with_invalid_token(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() project = f.create_project(owner=user_from, transfer_token="invalid-token") - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-reject", kwargs={"pk": project.pk}) @@ -927,7 +912,7 @@ def test_project_transfer_reject_from_admin_member_with_invalid_token(client): assert len(mail.outbox) == 0 -def test_project_transfer_reject_from_admin_member_with_other_user_token(client): +def test_project_transfer_reject_from_member_with_other_user_token(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() other_user = f.UserFactory.create() @@ -936,8 +921,8 @@ def test_project_transfer_reject_from_admin_member_with_other_user_token(client) token = signer.sign(other_user.id) project = f.create_project(owner=user_from, transfer_token=token) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-reject", kwargs={"pk": project.pk}) @@ -954,7 +939,7 @@ def test_project_transfer_reject_from_admin_member_with_other_user_token(client) assert len(mail.outbox) == 0 -def test_project_transfer_reject_from_admin_member_with_expired_token(client): +def test_project_transfer_reject_from_member_with_expired_token(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() @@ -962,8 +947,8 @@ def test_project_transfer_reject_from_admin_member_with_expired_token(client): token = signer.sign(user_to.id) project = f.create_project(owner=user_from, transfer_token=token) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-reject", kwargs={"pk": project.pk}) @@ -988,8 +973,8 @@ def test_project_transfer_reject_from_admin_member_with_valid_token(client): token = signer.sign(user_to.id) project = f.create_project(owner=user_from, transfer_token=token) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project, is_admin=True) client.login(user_to) url = reverse("projects-transfer-reject", kwargs={"pk": project.pk}) @@ -1004,9 +989,12 @@ def test_project_transfer_reject_from_admin_member_with_valid_token(client): assert response.status_code == 200 assert len(mail.outbox) == 1 assert mail.outbox[0].to == [user_from.email] + project = Project.objects.get(pk=project.pk) + assert project.owner.id == user_from.id + assert project.transfer_token is None -def test_project_transfer_accept_from_admin_member_without_token(client): +def test_project_transfer_reject_from_no_admin_member_with_valid_token(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() @@ -1014,8 +1002,40 @@ def test_project_transfer_accept_from_admin_member_without_token(client): token = signer.sign(user_to.id) project = f.create_project(owner=user_from, transfer_token=token) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + m = f.create_membership(user=user_to, project=project, is_admin=False) + + client.login(user_to) + url = reverse("projects-transfer-reject", kwargs={"pk": project.pk}) + + data = { + "token": token, + } + mail.outbox = [] + + response = client.json.post(url, json.dumps(data)) + + assert response.status_code == 200 + assert len(mail.outbox) == 1 + assert mail.outbox[0].to == [user_from.email] + assert m.is_admin == False + project = Project.objects.get(pk=project.pk) + m = project.memberships.get(user=user_to) + assert project.owner.id == user_from.id + assert project.transfer_token is None + assert m.is_admin == False + + +def test_project_transfer_accept_from_member_without_token(client): + user_from = f.UserFactory.create() + user_to = f.UserFactory.create() + + signer = signing.TimestampSigner() + token = signer.sign(user_to.id) + project = f.create_project(owner=user_from, transfer_token=token) + + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-accept", kwargs={"pk": project.pk}) @@ -1029,39 +1049,14 @@ def test_project_transfer_accept_from_admin_member_without_token(client): assert len(mail.outbox) == 0 -def test_project_transfer_accept_from_not_admin_member(client): - user_from = f.UserFactory.create() - user_to = f.UserFactory.create() - - signer = signing.TimestampSigner() - token = signer.sign(user_to.id) - project = f.create_project(owner=user_from, transfer_token=token, public_permissions=["view_project"]) - - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=False) - - client.login(user_to) - url = reverse("projects-transfer-accept", kwargs={"pk": project.pk}) - - data = { - "token": token, - } - mail.outbox = [] - - response = client.json.post(url, json.dumps(data)) - - assert response.status_code == 403 - assert len(mail.outbox) == 0 - - -def test_project_transfer_accept_from_admin_member_with_invalid_token(client): +def test_project_transfer_accept_from_member_with_invalid_token(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() project = f.create_project(owner=user_from, transfer_token="invalid-token") - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-accept", kwargs={"pk": project.pk}) @@ -1078,7 +1073,7 @@ def test_project_transfer_accept_from_admin_member_with_invalid_token(client): assert len(mail.outbox) == 0 -def test_project_transfer_accept_from_admin_member_with_other_user_token(client): +def test_project_transfer_accept_from_member_with_other_user_token(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() other_user = f.UserFactory.create() @@ -1087,8 +1082,8 @@ def test_project_transfer_accept_from_admin_member_with_other_user_token(client) token = signer.sign(other_user.id) project = f.create_project(owner=user_from, transfer_token=token) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-accept", kwargs={"pk": project.pk}) @@ -1105,7 +1100,7 @@ def test_project_transfer_accept_from_admin_member_with_other_user_token(client) assert len(mail.outbox) == 0 -def test_project_transfer_accept_from_admin_member_with_expired_token(client): +def test_project_transfer_accept_from_member_with_expired_token(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() @@ -1113,8 +1108,8 @@ def test_project_transfer_accept_from_admin_member_with_expired_token(client): token = signer.sign(user_to.id) project = f.create_project(owner=user_from, transfer_token=token) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-accept", kwargs={"pk": project.pk}) @@ -1131,7 +1126,7 @@ def test_project_transfer_accept_from_admin_member_with_expired_token(client): assert len(mail.outbox) == 0 -def test_project_transfer_accept_from_admin_member_with_valid_token_without_enough_slots(client): +def test_project_transfer_accept_from_member_with_valid_token_without_enough_slots(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create(max_private_projects=0) @@ -1139,8 +1134,8 @@ def test_project_transfer_accept_from_admin_member_with_valid_token_without_enou token = signer.sign(user_to.id) project = f.create_project(owner=user_from, transfer_token=token, is_private=True) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-accept", kwargs={"pk": project.pk}) @@ -1159,7 +1154,7 @@ def test_project_transfer_accept_from_admin_member_with_valid_token_without_enou assert project.transfer_token is not None -def test_project_transfer_accept_from_admin_member_with_valid_token_without_enough_memberships_public_project_slots(client): +def test_project_transfer_accept_from_member_with_valid_token_without_enough_memberships_public_project_slots(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create(max_memberships_public_projects=5) @@ -1167,14 +1162,14 @@ def test_project_transfer_accept_from_admin_member_with_valid_token_without_enou token = signer.sign(user_to.id) project = f.create_project(owner=user_from, transfer_token=token, is_private=False) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) - f.MembershipFactory(project=project) - f.MembershipFactory(project=project) - f.MembershipFactory(project=project) - f.MembershipFactory(project=project) - f.MembershipFactory(project=project) + f.create_membership(project=project) + f.create_membership(project=project) + f.create_membership(project=project) + f.create_membership(project=project) + f.create_membership(project=project) client.login(user_to) url = reverse("projects-transfer-accept", kwargs={"pk": project.pk}) @@ -1193,7 +1188,7 @@ def test_project_transfer_accept_from_admin_member_with_valid_token_without_enou assert project.transfer_token is not None -def test_project_transfer_accept_from_admin_member_with_valid_token_without_enough_memberships_private_project_slots(client): +def test_project_transfer_accept_from_member_with_valid_token_without_enough_memberships_private_project_slots(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create(max_memberships_private_projects=5) @@ -1201,14 +1196,14 @@ def test_project_transfer_accept_from_admin_member_with_valid_token_without_enou token = signer.sign(user_to.id) project = f.create_project(owner=user_from, transfer_token=token, is_private=True) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) - f.MembershipFactory(project=project) - f.MembershipFactory(project=project) - f.MembershipFactory(project=project) - f.MembershipFactory(project=project) - f.MembershipFactory(project=project) + f.create_membership(project=project) + f.create_membership(project=project) + f.create_membership(project=project) + f.create_membership(project=project) + f.create_membership(project=project) client.login(user_to) url = reverse("projects-transfer-accept", kwargs={"pk": project.pk}) @@ -1235,8 +1230,8 @@ def test_project_transfer_accept_from_admin_member_with_valid_token_with_enough_ token = signer.sign(user_to.id) project = f.create_project(owner=user_from, transfer_token=token, is_private=True) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project, is_admin=True) client.login(user_to) url = reverse("projects-transfer-accept", kwargs={"pk": project.pk}) @@ -1256,7 +1251,39 @@ def test_project_transfer_accept_from_admin_member_with_valid_token_with_enough_ assert project.transfer_token is None -def test_project_transfer_validate_token_from_admin_member_without_token(client): +def test_project_transfer_accept_from_no_admin_member_with_valid_token_with_enough_slots(client): + user_from = f.UserFactory.create() + user_to = f.UserFactory.create(max_private_projects=1) + + signer = signing.TimestampSigner() + token = signer.sign(user_to.id) + project = f.create_project(owner=user_from, transfer_token=token, is_private=True) + + f.create_membership(user=user_from, project=project, is_admin=True) + m = f.create_membership(user=user_to, project=project, is_admin=False) + + client.login(user_to) + url = reverse("projects-transfer-accept", kwargs={"pk": project.pk}) + + data = { + "token": token, + } + mail.outbox = [] + + response = client.json.post(url, json.dumps(data)) + + assert response.status_code == 200 + assert len(mail.outbox) == 1 + assert mail.outbox[0].to == [user_from.email] + assert m.is_admin == False + project = Project.objects.get(pk=project.pk) + m = project.memberships.get(user=user_to) + assert project.owner.id == user_to.id + assert project.transfer_token is None + assert m.is_admin == True + + +def test_project_transfer_validate_token_from_member_without_token(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() @@ -1264,8 +1291,8 @@ def test_project_transfer_validate_token_from_admin_member_without_token(client) token = signer.sign(user_to.id) project = f.create_project(owner=user_from, transfer_token=token) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-validate-token", kwargs={"pk": project.pk}) @@ -1277,37 +1304,14 @@ def test_project_transfer_validate_token_from_admin_member_without_token(client) assert response.status_code == 400 -def test_project_transfer_validate_token_from_not_admin_member(client): - user_from = f.UserFactory.create() - user_to = f.UserFactory.create() - - signer = signing.TimestampSigner() - token = signer.sign(user_to.id) - project = f.create_project(owner=user_from, transfer_token=token, public_permissions=["view_project"]) - - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=False) - - client.login(user_to) - url = reverse("projects-transfer-validate-token", kwargs={"pk": project.pk}) - - data = { - "token": token, - } - - response = client.json.post(url, json.dumps(data)) - - assert response.status_code == 403 - - -def test_project_transfer_validate_token_from_admin_member_with_invalid_token(client): +def test_project_transfer_validate_token_from_member_with_invalid_token(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() project = f.create_project(owner=user_from, transfer_token="invalid-token") - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-validate-token", kwargs={"pk": project.pk}) @@ -1322,7 +1326,7 @@ def test_project_transfer_validate_token_from_admin_member_with_invalid_token(cl assert "Token is invalid" == response.data["_error_message"] -def test_project_transfer_validate_token_from_admin_member_with_other_user_token(client): +def test_project_transfer_validate_token_from_member_with_other_user_token(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() other_user = f.UserFactory.create() @@ -1331,8 +1335,8 @@ def test_project_transfer_validate_token_from_admin_member_with_other_user_token token = signer.sign(other_user.id) project = f.create_project(owner=user_from, transfer_token=token) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-validate-token", kwargs={"pk": project.pk}) @@ -1347,7 +1351,7 @@ def test_project_transfer_validate_token_from_admin_member_with_other_user_token assert "Token is invalid" == response.data["_error_message"] -def test_project_transfer_validate_token_from_admin_member_with_expired_token(client): +def test_project_transfer_validate_token_from_member_with_expired_token(client): user_from = f.UserFactory.create() user_to = f.UserFactory.create() @@ -1355,8 +1359,8 @@ def test_project_transfer_validate_token_from_admin_member_with_expired_token(cl token = signer.sign(user_to.id) project = f.create_project(owner=user_from, transfer_token=token) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project) client.login(user_to) url = reverse("projects-transfer-validate-token", kwargs={"pk": project.pk}) @@ -1380,8 +1384,31 @@ def test_project_transfer_validate_token_from_admin_member_with_valid_token(clie token = signer.sign(user_to.id) project = f.create_project(owner=user_from, transfer_token=token, is_private=True) - f.MembershipFactory(user=user_from, project=project, is_admin=True) - f.MembershipFactory(user=user_to, project=project, is_admin=True) + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project, is_admin=True) + + client.login(user_to) + url = reverse("projects-transfer-validate-token", kwargs={"pk": project.pk}) + + data = { + "token": token, + } + + response = client.json.post(url, json.dumps(data)) + + assert response.status_code == 200 + + +def test_project_transfer_validate_token_from_no_admin_member_with_valid_token(client): + user_from = f.UserFactory.create() + user_to = f.UserFactory.create(max_private_projects=1) + + signer = signing.TimestampSigner() + token = signer.sign(user_to.id) + project = f.create_project(owner=user_from, transfer_token=token, is_private=True) + + f.create_membership(user=user_from, project=project, is_admin=True) + f.create_membership(user=user_to, project=project, is_admin=False) client.login(user_to) url = reverse("projects-transfer-validate-token", kwargs={"pk": project.pk})