From 13d30304691aa40eb22e9a3e1e2b0a160069b7eb Mon Sep 17 00:00:00 2001 From: sangeethailango Date: Tue, 16 Sep 2025 17:53:58 +0530 Subject: [PATCH 1/8] fix: permission check on viewset --- apps/api/plane/app/views/cycle/base.py | 13 ------------- apps/api/plane/app/views/intake/base.py | 14 +++++++++++--- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/apps/api/plane/app/views/cycle/base.py b/apps/api/plane/app/views/cycle/base.py index bcce69bf85f..cb07d76c420 100644 --- a/apps/api/plane/app/views/cycle/base.py +++ b/apps/api/plane/app/views/cycle/base.py @@ -504,19 +504,6 @@ def retrieve(self, request, slug, project_id, pk): @allow_permission([ROLE.ADMIN], creator=True, model=Cycle) def destroy(self, request, slug, project_id, pk): cycle = Cycle.objects.get(workspace__slug=slug, project_id=project_id, pk=pk) - if cycle.owned_by_id != request.user.id and not ( - ProjectMember.objects.filter( - workspace__slug=slug, - member=request.user, - role=20, - project_id=project_id, - is_active=True, - ).exists() - ): - return Response( - {"error": "Only admin or owner can delete the cycle"}, - status=status.HTTP_403_FORBIDDEN, - ) cycle_issues = list( CycleIssue.objects.filter(cycle_id=self.kwargs.get("pk")).values_list( diff --git a/apps/api/plane/app/views/intake/base.py b/apps/api/plane/app/views/intake/base.py index 1ca9e39705d..46be24a051d 100644 --- a/apps/api/plane/app/views/intake/base.py +++ b/apps/api/plane/app/views/intake/base.py @@ -28,6 +28,7 @@ ProjectMember, CycleIssue, IssueDescriptionVersion, + WorkspaceMember, ) from plane.app.serializers import ( IssueCreateSerializer, @@ -348,13 +349,20 @@ def partial_update(self, request, slug, project_id, pk): project_id=project_id, intake_id=intake_id, ) - # Get the project member - project_member = ProjectMember.objects.get( + + project_member = ProjectMember.objects.filter( workspace__slug=slug, project_id=project_id, member=request.user, is_active=True, - ) + ).first() + + if project_member is None: + project_member = WorkspaceMember.objects.get( + workspace__slug=slug, + is_active=True, + member=request.user, + ) # Only project members admins and created_by users can access this endpoint if project_member.role <= 5 and str(intake_issue.created_by_id) != str( request.user.id From ea21cf02671b927307740953d3f0437e4ddebd04 Mon Sep 17 00:00:00 2001 From: sangeethailango Date: Tue, 16 Sep 2025 18:48:52 +0530 Subject: [PATCH 2/8] chore: check workspace admin --- apps/api/plane/app/views/intake/base.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/apps/api/plane/app/views/intake/base.py b/apps/api/plane/app/views/intake/base.py index 46be24a051d..6e9bfb0108b 100644 --- a/apps/api/plane/app/views/intake/base.py +++ b/apps/api/plane/app/views/intake/base.py @@ -357,16 +357,24 @@ def partial_update(self, request, slug, project_id, pk): is_active=True, ).first() - if project_member is None: - project_member = WorkspaceMember.objects.get( + if not project_member: + is_workspace_admin = WorkspaceMember.objects.filter( workspace__slug=slug, is_active=True, member=request.user, + role=ROLE.ADMIN.value, + ).exists() + + if not project_member or not is_workspace_admin: + return Response( + {"error": "Only admin or creator can update the intake work items"}, + status=status.HTTP_403_FORBIDDEN, ) + # Only project members admins and created_by users can access this endpoint - if project_member.role <= 5 and str(intake_issue.created_by_id) != str( - request.user.id - ): + if (project_member.role <= 5 or not is_workspace_admin) and str( + intake_issue.created_by_id + ) != str(request.user.id): return Response( {"error": "You cannot edit intake issues"}, status=status.HTTP_400_BAD_REQUEST, @@ -400,7 +408,7 @@ def partial_update(self, request, slug, project_id, pk): ), ).get(pk=intake_issue.issue_id, workspace__slug=slug, project_id=project_id) # Only allow guests to edit name and description - if project_member.role <= 5: + if project_member.role <= 5 or is_workspace_admin: issue_data = { "name": issue_data.get("name", issue.name), "description_html": issue_data.get( @@ -444,8 +452,8 @@ def partial_update(self, request, slug, project_id, pk): issue_serializer.errors, status=status.HTTP_400_BAD_REQUEST ) - # Only project admins and members can edit intake issue attributes - if project_member.role > 15: + # Only project admins can edit intake issue attributes + if project_member.role > 15 or is_workspace_admin: serializer = IntakeIssueSerializer( intake_issue, data=request.data, partial=True ) From 47e4b93354d323c48851cfb5b8b5c065acecb045 Mon Sep 17 00:00:00 2001 From: sangeethailango Date: Tue, 16 Sep 2025 18:53:59 +0530 Subject: [PATCH 3/8] chore: initiative is_workspace_admin before if condition --- apps/api/plane/app/views/intake/base.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/api/plane/app/views/intake/base.py b/apps/api/plane/app/views/intake/base.py index 6e9bfb0108b..5a759ce2ea3 100644 --- a/apps/api/plane/app/views/intake/base.py +++ b/apps/api/plane/app/views/intake/base.py @@ -357,6 +357,8 @@ def partial_update(self, request, slug, project_id, pk): is_active=True, ).first() + is_workspace_admin = False + if not project_member: is_workspace_admin = WorkspaceMember.objects.filter( workspace__slug=slug, From d2f72d85307002a87dbddfac9c351271638864a7 Mon Sep 17 00:00:00 2001 From: sangeethailango Date: Tue, 16 Sep 2025 20:11:28 +0530 Subject: [PATCH 4/8] chore: project member check --- apps/api/plane/app/views/intake/base.py | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/apps/api/plane/app/views/intake/base.py b/apps/api/plane/app/views/intake/base.py index 5a759ce2ea3..033416cb48d 100644 --- a/apps/api/plane/app/views/intake/base.py +++ b/apps/api/plane/app/views/intake/base.py @@ -374,9 +374,9 @@ def partial_update(self, request, slug, project_id, pk): ) # Only project members admins and created_by users can access this endpoint - if (project_member.role <= 5 or not is_workspace_admin) and str( - intake_issue.created_by_id - ) != str(request.user.id): + if ( + (project_member and project_member.role <= 5) or not is_workspace_admin + ) and str(intake_issue.created_by_id) != str(request.user.id): return Response( {"error": "You cannot edit intake issues"}, status=status.HTTP_400_BAD_REQUEST, @@ -409,15 +409,15 @@ def partial_update(self, request, slug, project_id, pk): Value([], output_field=ArrayField(UUIDField())), ), ).get(pk=intake_issue.issue_id, workspace__slug=slug, project_id=project_id) - # Only allow guests to edit name and description - if project_member.role <= 5 or is_workspace_admin: - 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_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), + } + current_instance = json.dumps( IssueDetailSerializer(issue).data, cls=DjangoJSONEncoder ) @@ -455,7 +455,7 @@ def partial_update(self, request, slug, project_id, pk): ) # Only project admins can edit intake issue attributes - if project_member.role > 15 or is_workspace_admin: + if (project_member and project_member.role > 15) or is_workspace_admin: serializer = IntakeIssueSerializer( intake_issue, data=request.data, partial=True ) From f0138ff5f75c08718bc922857291b311ccb106d9 Mon Sep 17 00:00:00 2001 From: sangeethailango Date: Tue, 16 Sep 2025 20:25:39 +0530 Subject: [PATCH 5/8] fix: if conditions --- apps/api/plane/app/views/intake/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/api/plane/app/views/intake/base.py b/apps/api/plane/app/views/intake/base.py index 033416cb48d..4a5684cb1de 100644 --- a/apps/api/plane/app/views/intake/base.py +++ b/apps/api/plane/app/views/intake/base.py @@ -367,7 +367,7 @@ def partial_update(self, request, slug, project_id, pk): role=ROLE.ADMIN.value, ).exists() - if not project_member or not is_workspace_admin: + if not project_member and not is_workspace_admin: return Response( {"error": "Only admin or creator can update the intake work items"}, status=status.HTTP_403_FORBIDDEN, @@ -375,7 +375,7 @@ def partial_update(self, request, slug, project_id, pk): # Only project members admins and created_by users can access this endpoint if ( - (project_member and project_member.role <= 5) or not is_workspace_admin + (project_member and project_member.role <= 5) and not is_workspace_admin ) and str(intake_issue.created_by_id) != str(request.user.id): return Response( {"error": "You cannot edit intake issues"}, From 5cd05da3cb1242f451b7a74b6cc5d27fef75f2b3 Mon Sep 17 00:00:00 2001 From: sangeethailango Date: Tue, 16 Sep 2025 20:35:46 +0530 Subject: [PATCH 6/8] chore: add condition for guests to only edit description and name --- apps/api/plane/app/views/intake/base.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/api/plane/app/views/intake/base.py b/apps/api/plane/app/views/intake/base.py index 4a5684cb1de..269a1018e47 100644 --- a/apps/api/plane/app/views/intake/base.py +++ b/apps/api/plane/app/views/intake/base.py @@ -410,13 +410,14 @@ def partial_update(self, request, slug, project_id, pk): ), ).get(pk=intake_issue.issue_id, workspace__slug=slug, project_id=project_id) - 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), - } + if project_member and project_member.role <= 5: + 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), + } current_instance = json.dumps( IssueDetailSerializer(issue).data, cls=DjangoJSONEncoder From 5bb84de49723625d688ebdde544ccdf76d658978 Mon Sep 17 00:00:00 2001 From: sangeethailango Date: Tue, 16 Sep 2025 20:49:32 +0530 Subject: [PATCH 7/8] fix: use ROLE enum instead of magic numbers --- apps/api/plane/app/views/intake/base.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/api/plane/app/views/intake/base.py b/apps/api/plane/app/views/intake/base.py index 269a1018e47..2073935729d 100644 --- a/apps/api/plane/app/views/intake/base.py +++ b/apps/api/plane/app/views/intake/base.py @@ -375,7 +375,8 @@ def partial_update(self, request, slug, project_id, pk): # Only project members admins and created_by users can access this endpoint if ( - (project_member and project_member.role <= 5) and not is_workspace_admin + (project_member and project_member.role <= ROLE.GUEST.value) + and not is_workspace_admin ) and str(intake_issue.created_by_id) != str(request.user.id): return Response( {"error": "You cannot edit intake issues"}, @@ -410,7 +411,7 @@ def partial_update(self, request, slug, project_id, pk): ), ).get(pk=intake_issue.issue_id, workspace__slug=slug, project_id=project_id) - if project_member and project_member.role <= 5: + if project_member and project_member.role <= ROLE.GUEST.value: issue_data = { "name": issue_data.get("name", issue.name), "description_html": issue_data.get( @@ -456,7 +457,9 @@ def partial_update(self, request, slug, project_id, pk): ) # Only project admins can edit intake issue attributes - if (project_member and project_member.role > 15) or is_workspace_admin: + if ( + project_member and project_member.role > ROLE.MEMBER.value + ) or is_workspace_admin: serializer = IntakeIssueSerializer( intake_issue, data=request.data, partial=True ) From d3dda2bef007824e87b87c71b3f9da4dc73be19d Mon Sep 17 00:00:00 2001 From: sangeethailango Date: Wed, 17 Sep 2025 16:05:50 +0530 Subject: [PATCH 8/8] chore: remove if condition --- apps/api/plane/app/views/intake/base.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/apps/api/plane/app/views/intake/base.py b/apps/api/plane/app/views/intake/base.py index 2073935729d..a55b40a7ca3 100644 --- a/apps/api/plane/app/views/intake/base.py +++ b/apps/api/plane/app/views/intake/base.py @@ -357,15 +357,12 @@ def partial_update(self, request, slug, project_id, pk): is_active=True, ).first() - is_workspace_admin = False - - if not project_member: - is_workspace_admin = WorkspaceMember.objects.filter( - workspace__slug=slug, - is_active=True, - member=request.user, - role=ROLE.ADMIN.value, - ).exists() + is_workspace_admin = WorkspaceMember.objects.filter( + workspace__slug=slug, + is_active=True, + member=request.user, + role=ROLE.ADMIN.value, + ).exists() if not project_member and not is_workspace_admin: return Response(