Adding leave project API

remotes/origin/enhancement/email-actions
Alejandro Alonso 2014-11-20 09:26:46 +01:00 committed by Jesús Espino
parent e7b963a674
commit c9fc2268d0
5 changed files with 72 additions and 3 deletions

View File

@ -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

View File

@ -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):
@ -28,7 +53,7 @@ class ProjectPermission(TaigaResourcePermission):
modules_perms = IsProjectOwner()
list_perms = AllowAny()
stats_perms = AllowAny()
member_stats_perms = HasProjectPerm('view_project')
member_stats_perms = HasProjectPerm('view_project')
star_perms = IsAuthenticated()
unstar_perms = IsAuthenticated()
issues_stats_perms = AllowAny()
@ -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):

View File

@ -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

View File

@ -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()

View File

@ -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