diff --git a/taiga/projects/api.py b/taiga/projects/api.py index 26878824..614245b1 100644 --- a/taiga/projects/api.py +++ b/taiga/projects/api.py @@ -153,9 +153,14 @@ class MembershipViewSet(ModelCrudViewSet): serializer = self.get_serializer(data=data, files=request.FILES) if serializer.is_valid(): - qs = self.model.objects.filter(Q(project_id=serializer.data["project"], + project_id = serializer.data["project"] + project = get_object_or_404(models.Project, id=project_id) + + self.check_permissions(request, 'create', project) + + qs = self.model.objects.filter(Q(project_id=project_id, user__email=serializer.data["email"]) | - Q(project_id=serializer.data["project"], + Q(project_id=project_id, email=serializer.data["email"])) if qs.count() > 0: raise exc.WrongArguments(_("Email address is already taken.")) diff --git a/taiga/projects/serializers.py b/taiga/projects/serializers.py index 5eab582a..33ead541 100644 --- a/taiga/projects/serializers.py +++ b/taiga/projects/serializers.py @@ -87,9 +87,9 @@ class IssueTypeSerializer(serializers.ModelSerializer): # Projects class MembershipSerializer(serializers.ModelSerializer): - role_name = serializers.CharField(source='role.name', required=False) - full_name = serializers.CharField(source='user.get_full_name', required=False) - color = serializers.CharField(source='user.color', required=False) + role_name = serializers.CharField(source='role.name', required=False, read_only=True) + full_name = serializers.CharField(source='user.get_full_name', required=False, read_only=True) + color = serializers.CharField(source='user.color', required=False, read_only=True) photo = serializers.SerializerMethodField("get_photo") invited_by = serializers.SerializerMethodField("get_invited_by") project_name = serializers.SerializerMethodField("get_project_name") diff --git a/tests/integration/resources_permissions/test_projects_choices_resources.py b/tests/integration/resources_permissions/test_projects_choices_resources.py index ca4b1611..b2d9a33e 100644 --- a/tests/integration/resources_permissions/test_projects_choices_resources.py +++ b/tests/integration/resources_permissions/test_projects_choices_resources.py @@ -1473,6 +1473,38 @@ def test_membership_patch(client, data): results = helper_test_http_method(client, 'patch', private2_url, '{"name": "Test"}', users) assert results == [401, 403, 403, 403, 200] +def test_membership_create(client, data): + url = reverse('memberships-list') + + users = [ + None, + data.registered_user, + data.project_member_without_perms, + data.project_member_with_perms, + data.project_owner + ] + + membership_data = serializers.MembershipSerializer(data.public_membership).data + membership_data["id"] = None + membership_data["email"] = "test1@test.com" + membership_data = JSONRenderer().render(membership_data) + results = helper_test_http_method(client, 'post', url, membership_data, users) + assert results == [401, 403, 403, 403, 201] + + membership_data = serializers.MembershipSerializer(data.private_membership1).data + membership_data["id"] = None + membership_data["email"] = "test2@test.com" + membership_data = JSONRenderer().render(membership_data) + results = helper_test_http_method(client, 'post', url, membership_data, users) + assert results == [401, 403, 403, 403, 201] + + membership_data = serializers.MembershipSerializer(data.private_membership2).data + membership_data["id"] = None + membership_data["email"] = "test3@test.com" + membership_data = JSONRenderer().render(membership_data) + results = helper_test_http_method(client, 'post', url, membership_data, users) + assert results == [401, 403, 403, 403, 201] + def test_project_template_retrieve(client, data): url = reverse('project-templates-detail', kwargs={"pk": data.project_template.pk})