diff --git a/taiga/projects/contact/permissions.py b/taiga/projects/contact/permissions.py index 678aede9..2898e347 100644 --- a/taiga/projects/contact/permissions.py +++ b/taiga/projects/contact/permissions.py @@ -22,7 +22,13 @@ from taiga.base.api.permissions import TaigaResourcePermission class IsContactActivated(PermissionComponent): def check_permissions(self, request, view, obj=None): - return request.user.is_authenticated() and obj.project.is_contact_activated + if not request.user.is_authenticated() or not obj.project.is_contact_activated: + return False + + if obj.project.is_private: + return obj.project.cached_memberships_for_user(request.user) + + return True class ContactPermission(TaigaResourcePermission): diff --git a/tests/integration/resources_permissions/test_contact.py b/tests/integration/resources_permissions/test_contact.py index 7b5a1bec..c21adbc8 100644 --- a/tests/integration/resources_permissions/test_contact.py +++ b/tests/integration/resources_permissions/test_contact.py @@ -32,7 +32,7 @@ pytestmark = pytest.mark.django_db def data(): m = type("Models", (object,), {}) m.user = f.UserFactory.create() - m.project = f.ProjectFactory.create() + m.project = f.ProjectFactory.create(is_private=False) f.MembershipFactory(user=m.project.owner, project=m.project, is_admin=True) return m diff --git a/tests/integration/test_contact.py b/tests/integration/test_contact.py index 600b40f7..cb774afa 100644 --- a/tests/integration/test_contact.py +++ b/tests/integration/test_contact.py @@ -28,12 +28,15 @@ import pytest pytestmark = pytest.mark.django_db -def test_create_comment(client): +# Members can comment on a private project +# if the project has the contact activated +def test_member_create_comment_on_private_project(client): user = f.UserFactory.create() - project = f.ProjectFactory.create() + project = f.ProjectFactory.create(is_private=True) + project.is_contact_activated = True m1 = f.MembershipFactory(user=project.owner, project=project) m2 = f.MembershipFactory(project=project, is_admin=True) - m3 = f.MembershipFactory(project=project, is_admin=False) + m3 = f.MembershipFactory(user=user, project=project, is_admin=False) url = reverse("contact-list") @@ -51,7 +54,53 @@ def test_create_comment(client): assert set(mail.outbox[0].to[0].split(", ")) == set([project.owner.email, m2.user.email]) +# Non members user cannot comment on a private project +# even if the project has the contact activated +def test_guest_create_comment_on_private_project(client): + user = f.UserFactory.create() + project = f.ProjectFactory.create(is_private=True) + project.is_contact_activated = True + url = reverse("contact-list") + + contact_data = json.dumps({ + "project": project.id, + "comment": "Testing comment" + }) + + client.login(user) + + response = client.post(url, contact_data, content_type="application/json") + assert response.status_code == 403 + assert len(mail.outbox) == 0 + + +# All user can comment on a public project +# if the project has the contact activated +def test_create_comment_on_public_project(client): + user = f.UserFactory.create() + project = f.ProjectFactory.create(is_private=False) + project.is_contact_activated = True + m1 = f.MembershipFactory(user=project.owner, project=project) + m2 = f.MembershipFactory(project=project, is_admin=True) + url = reverse("contact-list") + + contact_data = json.dumps({ + "project": project.id, + "comment": "Testing comment" + }) + + client.login(user) + + assert len(mail.outbox) == 0 + response = client.post(url, contact_data, content_type="application/json") + assert response.status_code == 201 + assert len(mail.outbox) == 1 + assert set(mail.outbox[0].to[0].split(", ")) == set([project.owner.email, m2.user.email]) + + +# No user can comment on a project +# if the project does not have the contact activated def test_create_comment_disabled(client): user = f.UserFactory.create() project = f.ProjectFactory.create()