[WIKI-811] fix: ensure only non-deleted project pages are retrieved in page queries (#8182)

* fix: ensure soft delete handling for pages in PageViewSet methods

* refactor: streamline query for project IDs in PageDuplicateEndpoint

* refactor: remove soft delete condition from ProjectPage queries in PageViewSet and PageDuplicateEndpoint

* refactor: simplify ProjectPage query in PageViewSet for improved readability

* refactor: replace filter with get for Page queries in PageViewSet and PageDuplicateEndpoint to enhance clarity

* refactor: replace filter with get for Page queries in PagesDescriptionViewSet to improve efficiency
This commit is contained in:
Vipin Chaudhary 2025-11-27 20:55:50 +05:30 committed by GitHub
parent 3c84e75350
commit a4de486cf7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -149,14 +149,24 @@ class PageViewSet(BaseViewSet):
def partial_update(self, request, slug, project_id, page_id): def partial_update(self, request, slug, project_id, page_id):
try: try:
page = Page.objects.get(pk=page_id, workspace__slug=slug, projects__id=project_id) page = Page.objects.get(
pk=page_id,
workspace__slug=slug,
projects__id=project_id,
project_pages__deleted_at__isnull=True,
)
if page.is_locked: if page.is_locked:
return Response({"error": "Page is locked"}, status=status.HTTP_400_BAD_REQUEST) return Response({"error": "Page is locked"}, status=status.HTTP_400_BAD_REQUEST)
parent = request.data.get("parent", None) parent = request.data.get("parent", None)
if parent: if parent:
_ = Page.objects.get(pk=parent, workspace__slug=slug, projects__id=project_id) _ = Page.objects.get(
pk=parent,
workspace__slug=slug,
projects__id=project_id,
project_pages__deleted_at__isnull=True,
)
# Only update access if the page owner is the requesting user # Only update access if the page owner is the requesting user
if page.access != request.data.get("access", page.access) and page.owned_by_id != request.user.id: if page.access != request.data.get("access", page.access) and page.owned_by_id != request.user.id:
@ -230,14 +240,24 @@ class PageViewSet(BaseViewSet):
return Response(data, status=status.HTTP_200_OK) return Response(data, status=status.HTTP_200_OK)
def lock(self, request, slug, project_id, page_id): def lock(self, request, slug, project_id, page_id):
page = Page.objects.filter(pk=page_id, workspace__slug=slug, projects__id=project_id).first() page = Page.objects.get(
pk=page_id,
workspace__slug=slug,
projects__id=project_id,
project_pages__deleted_at__isnull=True,
)
page.is_locked = True page.is_locked = True
page.save() page.save()
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
def unlock(self, request, slug, project_id, page_id): def unlock(self, request, slug, project_id, page_id):
page = Page.objects.filter(pk=page_id, workspace__slug=slug, projects__id=project_id).first() page = Page.objects.get(
pk=page_id,
workspace__slug=slug,
projects__id=project_id,
project_pages__deleted_at__isnull=True,
)
page.is_locked = False page.is_locked = False
page.save() page.save()
@ -246,7 +266,12 @@ class PageViewSet(BaseViewSet):
def access(self, request, slug, project_id, page_id): def access(self, request, slug, project_id, page_id):
access = request.data.get("access", 0) access = request.data.get("access", 0)
page = Page.objects.filter(pk=page_id, workspace__slug=slug, projects__id=project_id).first() page = Page.objects.get(
pk=page_id,
workspace__slug=slug,
projects__id=project_id,
project_pages__deleted_at__isnull=True,
)
# Only update access if the page owner is the requesting user # Only update access if the page owner is the requesting user
if page.access != request.data.get("access", page.access) and page.owned_by_id != request.user.id: if page.access != request.data.get("access", page.access) and page.owned_by_id != request.user.id:
@ -277,7 +302,12 @@ class PageViewSet(BaseViewSet):
return Response(pages, status=status.HTTP_200_OK) return Response(pages, status=status.HTTP_200_OK)
def archive(self, request, slug, project_id, page_id): def archive(self, request, slug, project_id, page_id):
page = Page.objects.get(pk=page_id, workspace__slug=slug, projects__id=project_id) page = Page.objects.get(
pk=page_id,
workspace__slug=slug,
projects__id=project_id,
project_pages__deleted_at__isnull=True,
)
# only the owner or admin can archive the page # only the owner or admin can archive the page
if ( if (
@ -303,7 +333,12 @@ class PageViewSet(BaseViewSet):
return Response({"archived_at": str(datetime.now())}, status=status.HTTP_200_OK) return Response({"archived_at": str(datetime.now())}, status=status.HTTP_200_OK)
def unarchive(self, request, slug, project_id, page_id): def unarchive(self, request, slug, project_id, page_id):
page = Page.objects.get(pk=page_id, workspace__slug=slug, projects__id=project_id) page = Page.objects.get(
pk=page_id,
workspace__slug=slug,
projects__id=project_id,
project_pages__deleted_at__isnull=True,
)
# only the owner or admin can un archive the page # only the owner or admin can un archive the page
if ( if (
@ -327,7 +362,12 @@ class PageViewSet(BaseViewSet):
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
def destroy(self, request, slug, project_id, page_id): def destroy(self, request, slug, project_id, page_id):
page = Page.objects.get(pk=page_id, workspace__slug=slug, projects__id=project_id) page = Page.objects.get(
pk=page_id,
workspace__slug=slug,
projects__id=project_id,
project_pages__deleted_at__isnull=True,
)
if page.archived_at is None: if page.archived_at is None:
return Response( return Response(
@ -350,7 +390,12 @@ class PageViewSet(BaseViewSet):
) )
# remove parent from all the children # remove parent from all the children
_ = Page.objects.filter(parent_id=page_id, projects__id=project_id, workspace__slug=slug).update(parent=None) _ = Page.objects.filter(
parent_id=page_id,
projects__id=project_id,
workspace__slug=slug,
project_pages__deleted_at__isnull=True,
).update(parent=None)
page.delete() page.delete()
# Delete the user favorite page # Delete the user favorite page
@ -451,12 +496,14 @@ class PagesDescriptionViewSet(BaseViewSet):
def retrieve(self, request, slug, project_id, page_id): def retrieve(self, request, slug, project_id, page_id):
page = ( page = (
Page.objects.filter(pk=page_id, workspace__slug=slug, projects__id=project_id) Page.objects.get(
.filter(Q(owned_by=self.request.user) | Q(access=0)) Q(owned_by=self.request.user) | Q(access=0),
.first() pk=page_id,
workspace__slug=slug,
projects__id=project_id,
project_pages__deleted_at__isnull=True,
)
) )
if page is None:
return Response({"error": "Page not found"}, status=404)
binary_data = page.description_binary binary_data = page.description_binary
def stream_data(): def stream_data():
@ -471,13 +518,14 @@ class PagesDescriptionViewSet(BaseViewSet):
def partial_update(self, request, slug, project_id, page_id): def partial_update(self, request, slug, project_id, page_id):
page = ( page = (
Page.objects.filter(pk=page_id, workspace__slug=slug, projects__id=project_id) Page.objects.get(
.filter(Q(owned_by=self.request.user) | Q(access=0)) Q(owned_by=self.request.user) | Q(access=0),
.first() pk=page_id,
workspace__slug=slug,
projects__id=project_id,
project_pages__deleted_at__isnull=True,
)
) )
if page is None:
return Response({"error": "Page not found"}, status=404)
if page.is_locked: if page.is_locked:
return Response( return Response(
@ -529,7 +577,12 @@ class PageDuplicateEndpoint(BaseAPIView):
permission_classes = [ProjectPagePermission] permission_classes = [ProjectPagePermission]
def post(self, request, slug, project_id, page_id): def post(self, request, slug, project_id, page_id):
page = Page.objects.filter(pk=page_id, workspace__slug=slug, projects__id=project_id).first() page = Page.objects.get(
pk=page_id,
workspace__slug=slug,
projects__id=project_id,
project_pages__deleted_at__isnull=True,
)
# check for permission # check for permission
if page.access == Page.PRIVATE_ACCESS and page.owned_by_id != request.user.id: if page.access == Page.PRIVATE_ACCESS and page.owned_by_id != request.user.id: