Adding leave project API
parent
e7b963a674
commit
c9fc2268d0
|
@ -154,6 +154,13 @@ class ProjectViewSet(ModelCrudViewSet):
|
|||
template.save()
|
||||
return Response(serializers.ProjectTemplateSerializer(template).data, status=201)
|
||||
|
||||
@detail_route(methods=['post'])
|
||||
def leave(self, request, pk=None):
|
||||
project = self.get_object()
|
||||
self.check_permissions(request, 'leave', project)
|
||||
services.remove_member(project, user=request.user)
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
|
||||
def pre_save(self, obj):
|
||||
if not obj.id:
|
||||
obj.owner = self.request.user
|
||||
|
|
|
@ -13,10 +13,35 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from taiga.base.api.permissions import (TaigaResourcePermission, HasProjectPerm,
|
||||
IsAuthenticated, IsProjectOwner,
|
||||
AllowAny, IsSuperUser)
|
||||
AllowAny, IsSuperUser, PermissionComponent)
|
||||
|
||||
from taiga.base import exceptions as exc
|
||||
from taiga.projects.models import Membership
|
||||
|
||||
|
||||
class CanLeaveProject(PermissionComponent):
|
||||
def check_permissions(self, request, view, obj=None):
|
||||
if not obj or not request.user.is_authenticated():
|
||||
return False
|
||||
|
||||
try:
|
||||
membership = Membership.objects.get(user=request.user, project=obj)
|
||||
other_admin_memberships_count = Membership.objects\
|
||||
.exclude(id=membership.id)\
|
||||
.filter(project=obj, is_owner=True)\
|
||||
.count()
|
||||
|
||||
# The project need at least one owner
|
||||
if membership.is_owner and other_admin_memberships_count == 0:
|
||||
raise exc.PermissionDenied(_("You can't leave the project if there are no more owners"))
|
||||
|
||||
return True
|
||||
except Membership.DoesNotExist:
|
||||
return False
|
||||
|
||||
|
||||
class ProjectPermission(TaigaResourcePermission):
|
||||
|
@ -37,6 +62,7 @@ class ProjectPermission(TaigaResourcePermission):
|
|||
tags_colors_perms = HasProjectPerm('view_project')
|
||||
fans_perms = HasProjectPerm('view_project')
|
||||
create_template_perms = IsSuperUser()
|
||||
leave_perms = CanLeaveProject()
|
||||
|
||||
|
||||
class MembershipPermission(TaigaResourcePermission):
|
||||
|
|
|
@ -34,6 +34,7 @@ from .stats import get_member_stats_for_project
|
|||
|
||||
from .members import create_members_in_bulk
|
||||
from .members import get_members_from_bulk
|
||||
from .members import remove_member
|
||||
|
||||
from .invitations import send_invitation
|
||||
from .invitations import find_invited_user
|
||||
|
|
|
@ -2,7 +2,6 @@ from taiga.base.utils import db, text
|
|||
|
||||
from .. import models
|
||||
|
||||
|
||||
def get_members_from_bulk(bulk_data, **additional_fields):
|
||||
"""Convert `bulk_data` into a list of members.
|
||||
|
||||
|
@ -31,3 +30,7 @@ def create_members_in_bulk(bulk_data, callback=None, precall=None, **additional_
|
|||
members = get_members_from_bulk(bulk_data, **additional_fields)
|
||||
db.save_in_bulk(members, callback, precall)
|
||||
return members
|
||||
|
||||
|
||||
def remove_member(project, user):
|
||||
models.Membership.objects.get(project=project, user=user).delete()
|
||||
|
|
|
@ -160,3 +160,35 @@ def test_get_closed_bugs_per_member_stats():
|
|||
|
||||
assert stats["closed_tasks"][membership_1.user.id] == 1
|
||||
assert stats["closed_tasks"][membership_2.user.id] == 0
|
||||
|
||||
|
||||
def test_leave_project_valid_membership(client):
|
||||
user = f.UserFactory.create()
|
||||
project = f.ProjectFactory.create()
|
||||
role = f.RoleFactory.create(project=project, permissions=["view_project"])
|
||||
f.MembershipFactory.create(project=project, user=user, role=role)
|
||||
client.login(user)
|
||||
url = reverse("projects-leave", args=(project.id,))
|
||||
response = client.post(url)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_leave_project_valid_membership_only_owner(client):
|
||||
user = f.UserFactory.create()
|
||||
project = f.ProjectFactory.create()
|
||||
role = f.RoleFactory.create(project=project, permissions=["view_project"])
|
||||
f.MembershipFactory.create(project=project, user=user, role=role, is_owner=True)
|
||||
client.login(user)
|
||||
url = reverse("projects-leave", args=(project.id,))
|
||||
response = client.post(url)
|
||||
assert response.status_code == 403
|
||||
assert json.loads(response.content)["_error_message"] == "You can't leave the project if there are no more owners"
|
||||
|
||||
|
||||
def test_leave_project_invalid_membership(client):
|
||||
user = f.UserFactory.create()
|
||||
project = f.ProjectFactory()
|
||||
client.login(user)
|
||||
url = reverse("projects-leave", args=(project.id,))
|
||||
response = client.post(url)
|
||||
assert response.status_code == 404
|
||||
|
|
Loading…
Reference in New Issue