From bfac39f1bc94a7450868386ee666adfe6b071886 Mon Sep 17 00:00:00 2001 From: pablohashescobar <118773738+pablohashescobar@users.noreply.github.com> Date: Thu, 22 Jun 2023 19:48:04 +0530 Subject: [PATCH] chore: inbox issue permissions (#1341) * chore: inbox issue permissions * dev: update delete endpoint --- apiserver/plane/api/views/inbox.py | 109 ++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 34 deletions(-) diff --git a/apiserver/plane/api/views/inbox.py b/apiserver/plane/api/views/inbox.py index 738c6ef9f..0e4c1603e 100644 --- a/apiserver/plane/api/views/inbox.py +++ b/apiserver/plane/api/views/inbox.py @@ -22,7 +22,7 @@ from plane.db.models import ( State, IssueLink, IssueAttachment, - IssueActivity, + ProjectMember, ) from plane.api.serializers import ( IssueSerializer, @@ -246,13 +246,28 @@ class InboxIssueViewSet(BaseViewSet): inbox_issue = InboxIssue.objects.get( pk=pk, workspace__slug=slug, project_id=project_id, inbox_id=inbox_id ) + # Get the project member + project_member = ProjectMember.objects.get(workspace__slug=slug, project_id=project_id, member=request.user) + # Only project members admins and created_by users can access this endpoint + if project_member.role <= 10 and str(inbox_issue.created_by_id) != str(request.user.id): + return Response({"error": "You cannot edit inbox issues"}, status=status.HTTP_400_BAD_REQUEST) + # Get issue data issue_data = request.data.pop("issue", False) if bool(issue_data): issue = Issue.objects.get( pk=inbox_issue.issue_id, workspace__slug=slug, project_id=project_id ) + # Only allow guests and viewers to edit name and description + if project_member <= 10: + # viewers and guests since only viewers and guests + issue_data = { + "name": issue_data.get("name", issue.name), + "description_html": issue_data.get("description_html", issue.description_html), + "description": issue_data.get("description", issue.description) + } + issue_serializer = IssueCreateSerializer( issue, data=issue_data, partial=True ) @@ -279,46 +294,50 @@ class InboxIssueViewSet(BaseViewSet): issue_serializer.errors, status=status.HTTP_400_BAD_REQUEST ) - serializer = InboxIssueSerializer( - inbox_issue, data=request.data, partial=True - ) + # Only project admins and members can edit inbox issue attributes + if project_member.role > 10: + serializer = InboxIssueSerializer( + inbox_issue, data=request.data, partial=True + ) - if serializer.is_valid(): - serializer.save() - # Update the issue state if the issue is rejected or marked as duplicate - if serializer.data["status"] in [-1, 2]: - issue = Issue.objects.get( - pk=inbox_issue.issue_id, - workspace__slug=slug, - project_id=project_id, - ) - state = State.objects.filter( - group="cancelled", workspace__slug=slug, project_id=project_id - ).first() - if state is not None: - issue.state = state - issue.save() - - # Update the issue state if it is accepted - if serializer.data["status"] in [1]: - issue = Issue.objects.get( - pk=inbox_issue.issue_id, - workspace__slug=slug, - project_id=project_id, - ) - - # Update the issue state only if it is in triage state - if issue.state.name == "Triage": - # Move to default state + if serializer.is_valid(): + serializer.save() + # Update the issue state if the issue is rejected or marked as duplicate + if serializer.data["status"] in [-1, 2]: + issue = Issue.objects.get( + pk=inbox_issue.issue_id, + workspace__slug=slug, + project_id=project_id, + ) state = State.objects.filter( - workspace__slug=slug, project_id=project_id, default=True + group="cancelled", workspace__slug=slug, project_id=project_id ).first() if state is not None: issue.state = state issue.save() - return Response(serializer.data, status=status.HTTP_200_OK) - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + # Update the issue state if it is accepted + if serializer.data["status"] in [1]: + issue = Issue.objects.get( + pk=inbox_issue.issue_id, + workspace__slug=slug, + project_id=project_id, + ) + + # Update the issue state only if it is in triage state + if issue.state.name == "Triage": + # Move to default state + state = State.objects.filter( + workspace__slug=slug, project_id=project_id, default=True + ).first() + if state is not None: + issue.state = state + issue.save() + + return Response(serializer.data, status=status.HTTP_200_OK) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + else: + return Response(InboxIssueSerializer(inbox_issue).data, status=status.HTTP_200_OK) except InboxIssue.DoesNotExist: return Response( {"error": "Inbox Issue does not exist"}, @@ -347,3 +366,25 @@ class InboxIssueViewSet(BaseViewSet): {"error": "Something went wrong please try again later"}, status=status.HTTP_400_BAD_REQUEST, ) + + def destroy(self, request, slug, project_id, inbox_id, pk): + try: + inbox_issue = InboxIssue.objects.get( + pk=pk, workspace__slug=slug, project_id=project_id, inbox_id=inbox_id + ) + # Get the project member + project_member = ProjectMember.objects.get(workspace__slug=slug, project_id=project_id, member=request.user) + + if project_member.role <= 10 and str(inbox_issue.created_by_id) != str(request.user.id): + return Response({"error": "You cannot delete inbox issue"}, status=status.HTTP_400_BAD_REQUEST) + + inbox_issue.delete() + return Response(status=status.HTTP_204_NO_CONTENT) + except InboxIssue.DoesNotExist: + return Response({"error": "Inbox Issue does not exists"}, status=status.HTTP_400_BAD_REQUEST) + except Exception as e: + capture_exception(e) + return Response( + {"error": "Something went wrong please try again later"}, + status=status.HTTP_400_BAD_REQUEST, + ) \ No newline at end of file