fix: workspace and project member user deletion (#1241)

* fix: workspace and project member user deletion

* fix: workspace member deletion

* dev: add comments
This commit is contained in:
pablohashescobar 2023-06-08 00:14:41 +05:30 committed by GitHub
parent 42fceb4dcd
commit 754142afa2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 103 additions and 33 deletions

View File

@ -46,7 +46,7 @@ from plane.db.models import (
IssueViewFavorite, IssueViewFavorite,
Page, Page,
IssueAssignee, IssueAssignee,
ModuleMember ModuleMember,
) )
@ -104,15 +104,13 @@ class ProjectViewSet(BaseViewSet):
.values("count") .values("count")
) )
.annotate( .annotate(
total_cycles=Cycle.objects.filter( total_cycles=Cycle.objects.filter(project_id=OuterRef("id"))
project_id=OuterRef("id"))
.order_by() .order_by()
.annotate(count=Func(F("id"), function="Count")) .annotate(count=Func(F("id"), function="Count"))
.values("count") .values("count")
) )
.annotate( .annotate(
total_modules=Module.objects.filter( total_modules=Module.objects.filter(project_id=OuterRef("id"))
project_id=OuterRef("id"))
.order_by() .order_by()
.annotate(count=Func(F("id"), function="Count")) .annotate(count=Func(F("id"), function="Count"))
.values("count") .values("count")
@ -322,8 +320,7 @@ class InviteProjectEndpoint(BaseAPIView):
) )
return Response( return Response(
ProjectMemberSerializer( ProjectMemberSerializer(project_member).data, status=status.HTTP_200_OK
project_member).data, status=status.HTTP_200_OK
) )
except ValidationError: except ValidationError:
@ -416,15 +413,22 @@ class ProjectMemberViewSet(BaseViewSet):
def partial_update(self, request, slug, project_id, pk): def partial_update(self, request, slug, project_id, pk):
try: try:
project_member = ProjectMember.objects.get( project_member = ProjectMember.objects.get(
pk=pk, workspace__slug=slug, project_id=project_id) pk=pk, workspace__slug=slug, project_id=project_id
)
if request.user.id == project_member.member_id: if request.user.id == project_member.member_id:
return Response( return Response(
{"error": "You cannot update your own role"}, {"error": "You cannot update your own role"},
status=status.HTTP_400_BAD_REQUEST, status=status.HTTP_400_BAD_REQUEST,
) )
# Check while updating user roles # Check while updating user roles
requested_project_member = ProjectMember.objects.get(project_id=project_id, workspace__slug=slug, member=request.user) requested_project_member = ProjectMember.objects.get(
if "role" in request.data and int(request.data.get("role", project_member.role)) > requested_project_member.role: project_id=project_id, workspace__slug=slug, member=request.user
)
if (
"role" in request.data
and int(request.data.get("role", project_member.role))
> requested_project_member.role
):
return Response( return Response(
{ {
"error": "You cannot update a role that is higher than your own role" "error": "You cannot update a role that is higher than your own role"
@ -447,36 +451,72 @@ class ProjectMemberViewSet(BaseViewSet):
) )
except Exception as e: except Exception as e:
capture_exception(e) capture_exception(e)
return Response({"error": "Something went wrong please try again later"}, status=status.HTTP_400_BAD_REQUEST) return Response(
{"error": "Something went wrong please try again later"},
status=status.HTTP_400_BAD_REQUEST,
)
def destroy(self, request, slug, project_id, pk): def destroy(self, request, slug, project_id, pk):
try: try:
project_member = ProjectMember.objects.get( project_member = ProjectMember.objects.get(
workspace__slug=slug, project_id=project_id, pk=pk workspace__slug=slug, project_id=project_id, pk=pk
) )
# check requesting user role
requesting_project_member = ProjectMember.objects.get(
workspace__slug=slug, member=request.user, project_id=project_id
)
if requesting_project_member.role < project_member.role:
return Response(
{"error": "You cannot remove a user having role higher than yourself"},
status=status.HTTP_400_BAD_REQUEST,
)
# Remove all favorites # Remove all favorites
ProjectFavorite.objects.filter(workspace__slug=slug, project_id=project_id, user=project_member.member).delete() ProjectFavorite.objects.filter(
CycleFavorite.objects.filter(workspace__slug=slug, project_id=project_id, user=project_member.member).delete() workspace__slug=slug, project_id=project_id, user=project_member.member
ModuleFavorite.objects.filter(workspace__slug=slug, project_id=project_id, user=project_member.member).delete() ).delete()
PageFavorite.objects.filter(workspace__slug=slug, project_id=project_id, user=project_member.member).delete() CycleFavorite.objects.filter(
IssueViewFavorite.objects.filter(workspace__slug=slug, project_id=project_id, user=project_member.member).delete() workspace__slug=slug, project_id=project_id, user=project_member.member
).delete()
ModuleFavorite.objects.filter(
workspace__slug=slug, project_id=project_id, user=project_member.member
).delete()
PageFavorite.objects.filter(
workspace__slug=slug, project_id=project_id, user=project_member.member
).delete()
IssueViewFavorite.objects.filter(
workspace__slug=slug, project_id=project_id, user=project_member.member
).delete()
# Also remove issue from issue assigned # Also remove issue from issue assigned
IssueAssignee.objects.filter( IssueAssignee.objects.filter(
workspace__slug=slug, project_id=project_id, assignee=project_member.member workspace__slug=slug,
project_id=project_id,
assignee=project_member.member,
).delete() ).delete()
# Remove if module member # Remove if module member
ModuleMember.objects.filter(workspace__slug=slug, project_id=project_id, member=project_member.member).delete() ModuleMember.objects.filter(
workspace__slug=slug,
project_id=project_id,
member=project_member.member,
).delete()
# Delete owned Pages # Delete owned Pages
Page.objects.filter(workspace__slug=slug, project_id=project_id, owned_by=project_member.member).delete() Page.objects.filter(
workspace__slug=slug,
project_id=project_id,
owned_by=project_member.member,
).delete()
project_member.delete() project_member.delete()
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
except ProjectMember.DoesNotExist: except ProjectMember.DoesNotExist:
return Response({"error": "Project Member does not exist"}, status=status.HTTP_400) return Response(
{"error": "Project Member does not exist"}, status=status.HTTP_400
)
except Exception as e: except Exception as e:
capture_exception(e) capture_exception(e)
return Response({"error": "Something went wrong please try again later"}) return Response({"error": "Something went wrong please try again later"})
class AddMemberToProjectEndpoint(BaseAPIView): class AddMemberToProjectEndpoint(BaseAPIView):
permission_classes = [ permission_classes = [
ProjectBasePermission, ProjectBasePermission,
@ -669,8 +709,7 @@ class ProjectIdentifierEndpoint(BaseAPIView):
status=status.HTTP_400_BAD_REQUEST, status=status.HTTP_400_BAD_REQUEST,
) )
ProjectIdentifier.objects.filter( ProjectIdentifier.objects.filter(name=name, workspace__slug=slug).delete()
name=name, workspace__slug=slug).delete()
return Response( return Response(
status=status.HTTP_204_NO_CONTENT, status=status.HTTP_204_NO_CONTENT,
@ -746,8 +785,7 @@ class ProjectUserViewsEndpoint(BaseAPIView):
view_props = project_member.view_props view_props = project_member.view_props
default_props = project_member.default_props default_props = project_member.default_props
project_member.view_props = request.data.get( project_member.view_props = request.data.get("view_props", view_props)
"view_props", view_props)
project_member.default_props = request.data.get( project_member.default_props = request.data.get(
"default_props", default_props "default_props", default_props
) )

View File

@ -442,10 +442,16 @@ class WorkSpaceMemberViewSet(BaseViewSet):
) )
# Get the requested user role # Get the requested user role
requested_workspace_member = WorkspaceMember.objects.get(workspace__slug=slug, member=request.user) requested_workspace_member = WorkspaceMember.objects.get(
workspace__slug=slug, member=request.user
)
# Check if role is being updated # Check if role is being updated
# One cannot update role higher than his own role # One cannot update role higher than his own role
if "role" in request.data and int(request.data.get("role", workspace_member.role)) > requested_workspace_member.role: if (
"role" in request.data
and int(request.data.get("role", workspace_member.role))
> requested_workspace_member.role
):
return Response( return Response(
{ {
"error": "You cannot update a role that is higher than your own role" "error": "You cannot update a role that is higher than your own role"
@ -475,26 +481,52 @@ class WorkSpaceMemberViewSet(BaseViewSet):
def destroy(self, request, slug, pk): def destroy(self, request, slug, pk):
try: try:
# Check the user role who is deleting the user
workspace_member = WorkspaceMember.objects.get(workspace__slug=slug, pk=pk) workspace_member = WorkspaceMember.objects.get(workspace__slug=slug, pk=pk)
# check requesting user role
requesting_workspace_member = WorkspaceMember.objects.get(
workspace__slug=slug, member=request.user
)
if requesting_workspace_member.role < workspace_member.role:
return Response(
{"error": "You cannot remove a user having role higher than you"},
status=status.HTTP_400_BAD_REQUEST,
)
# Delete the user also from all the projects # Delete the user also from all the projects
ProjectMember.objects.filter( ProjectMember.objects.filter(
workspace__slug=slug, member=workspace_member.member workspace__slug=slug, member=workspace_member.member
).delete() ).delete()
# Remove all favorites # Remove all favorites
ProjectFavorite.objects.filter(workspace__slug=slug, user=workspace_member.member).delete() ProjectFavorite.objects.filter(
CycleFavorite.objects.filter(workspace__slug=slug, user=workspace_member.member).delete() workspace__slug=slug, user=workspace_member.member
ModuleFavorite.objects.filter(workspace__slug=slug, user=workspace_member.member).delete() ).delete()
PageFavorite.objects.filter(workspace__slug=slug, user=workspace_member.member).delete() CycleFavorite.objects.filter(
IssueViewFavorite.objects.filter(workspace__slug=slug, user=workspace_member.member).delete() workspace__slug=slug, user=workspace_member.member
).delete()
ModuleFavorite.objects.filter(
workspace__slug=slug, user=workspace_member.member
).delete()
PageFavorite.objects.filter(
workspace__slug=slug, user=workspace_member.member
).delete()
IssueViewFavorite.objects.filter(
workspace__slug=slug, user=workspace_member.member
).delete()
# Also remove issue from issue assigned # Also remove issue from issue assigned
IssueAssignee.objects.filter( IssueAssignee.objects.filter(
workspace__slug=slug, assignee=workspace_member.member workspace__slug=slug, assignee=workspace_member.member
).delete() ).delete()
# Remove if module member # Remove if module member
ModuleMember.objects.filter(workspace__slug=slug, member=workspace_member.member).delete() ModuleMember.objects.filter(
workspace__slug=slug, member=workspace_member.member
).delete()
# Delete owned Pages # Delete owned Pages
Page.objects.filter(workspace__slug=slug, owned_by=workspace_member.member).delete() Page.objects.filter(
workspace__slug=slug, owned_by=workspace_member.member
).delete()
workspace_member.delete() workspace_member.delete()
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)