[WEB-1790] chore: delete view permission change (#4981)

* chore: preventing race condition

* chore: added delete view validation
This commit is contained in:
Bavisetti Narayan 2024-07-01 15:41:28 +05:30 committed by GitHub
parent 830d4045be
commit e824c37f36
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -14,6 +14,7 @@ from django.db.models.functions import Coalesce
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.decorators.gzip import gzip_page from django.views.decorators.gzip import gzip_page
from rest_framework import status from rest_framework import status
from django.db import transaction
# Third party imports # Third party imports
from rest_framework.response import Response from rest_framework.response import Response
@ -31,6 +32,8 @@ from plane.db.models import (
IssueLink, IssueLink,
IssueView, IssueView,
Workspace, Workspace,
WorkspaceMember,
ProjectMember,
) )
from plane.utils.grouper import ( from plane.utils.grouper import (
issue_group_values, issue_group_values,
@ -76,32 +79,60 @@ class WorkspaceViewViewSet(BaseViewSet):
) )
def partial_update(self, request, slug, pk): def partial_update(self, request, slug, pk):
with transaction.atomic():
workspace_view = IssueView.objects.select_for_update().get(
pk=pk,
workspace__slug=slug,
)
if workspace_view.is_locked:
return Response(
{"error": "view is locked"},
status=status.HTTP_400_BAD_REQUEST,
)
# Only update the view if owner is updating
if workspace_view.owned_by_id != request.user.id:
return Response(
{
"error": "Only the owner of the view can update the view"
},
status=status.HTTP_400_BAD_REQUEST,
)
serializer = IssueViewSerializer(
workspace_view, data=request.data, partial=True
)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(
serializer.errors, status=status.HTTP_400_BAD_REQUEST
)
def destroy(self, request, slug, pk):
workspace_view = IssueView.objects.get( workspace_view = IssueView.objects.get(
pk=pk, pk=pk,
workspace__slug=slug, workspace__slug=slug,
) )
workspace_member = WorkspaceMember.objects.filter(
if workspace_view.is_locked: workspace__slug=slug,
return Response( member=request.user,
{"error": "view is locked"}, role=20,
status=status.HTTP_400_BAD_REQUEST, is_active=True,
)
# Only update the view if owner is updating
if workspace_view.owned_by_id != request.user.id:
return Response(
{"error": "Only the owner of the view can update the view"},
status=status.HTTP_400_BAD_REQUEST,
)
serializer = IssueViewSerializer(
workspace_view, data=request.data, partial=True
) )
if (
if serializer.is_valid(): workspace_member.exists()
serializer.save() or workspace_view.owned_by == request.user
return Response(serializer.data, status=status.HTTP_200_OK) ):
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) workspace_view.delete()
else:
return Response(
{"error": "Only admin or owner can delete the view"},
status=status.HTTP_400_BAD_REQUEST,
)
return Response(status=status.HTTP_204_NO_CONTENT)
class WorkspaceViewIssuesViewSet(BaseViewSet): class WorkspaceViewIssuesViewSet(BaseViewSet):
@ -344,31 +375,58 @@ class IssueViewViewSet(BaseViewSet):
return Response(views, status=status.HTTP_200_OK) return Response(views, status=status.HTTP_200_OK)
def partial_update(self, request, slug, project_id, pk): def partial_update(self, request, slug, project_id, pk):
issue_view = IssueView.objects.get( with transaction.atomic():
pk=pk, workspace__slug=slug, project_id=project_id issue_view = IssueView.objects.select_for_update().get(
) pk=pk, workspace__slug=slug, project_id=project_id
if issue_view.is_locked:
return Response(
{"error": "view is locked"},
status=status.HTTP_400_BAD_REQUEST,
) )
# Only update the view if owner is updating if issue_view.is_locked:
if issue_view.owned_by_id != request.user.id: return Response(
return Response( {"error": "view is locked"},
{"error": "Only the owner of the view can update the view"}, status=status.HTTP_400_BAD_REQUEST,
status=status.HTTP_400_BAD_REQUEST, )
# Only update the view if owner is updating
if issue_view.owned_by_id != request.user.id:
return Response(
{
"error": "Only the owner of the view can update the view"
},
status=status.HTTP_400_BAD_REQUEST,
)
serializer = IssueViewSerializer(
issue_view, data=request.data, partial=True
) )
serializer = IssueViewSerializer( if serializer.is_valid():
issue_view, data=request.data, partial=True serializer.save()
) return Response(serializer.data, status=status.HTTP_200_OK)
return Response(
serializer.errors, status=status.HTTP_400_BAD_REQUEST
)
if serializer.is_valid(): def destroy(self, request, slug, project_id, pk):
serializer.save() project_view = IssueView.objects.get(
return Response(serializer.data, status=status.HTTP_200_OK) pk=pk,
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) project_id=project_id,
workspace__slug=slug,
)
project_member = ProjectMember.objects.filter(
workspace__slug=slug,
project_id=project_id,
member=request.user,
role=20,
is_active=True,
)
if project_member.exists() or project_view.owned_by == request.user:
project_view.delete()
else:
return Response(
{"error": "Only admin or owner can delete the view"},
status=status.HTTP_400_BAD_REQUEST,
)
return Response(status=status.HTTP_204_NO_CONTENT)
class IssueViewFavoriteViewSet(BaseViewSet): class IssueViewFavoriteViewSet(BaseViewSet):