mirror of
https://github.com/makeplane/plane.git
synced 2026-09-01 19:48:42 +02:00
fix: 404 instead of a hollow 200 when a global view does not exist
Review catch, verified before fixing. WorkspaceViewViewSet.retrieve resolves the
view with .first() and serialized the result unconditionally, so a member asking
for an id that does not exist got 200 with every field null or empty
(`{"name": "", "description": "", "filters": null, ...}`) and a recent-visit
enqueued for a nonexistent entity. Because get_queryset() is scoped to the URL
workspace, the same happened for a real view id belonging to a different
workspace.
Returns 404, matching the other retrieve endpoints.
Noted while confirming this, not fixed here: the project-level sibling
IssueViewViewSet.retrieve has the same .first() pattern and then dereferences
`issue_view.owned_by`, which raises AttributeError on None rather than answering
404 — a 500 instead of a hollow 200. Different method, so it gets its own ticket
rather than widening this one.
Co-authored-by: Plane AI <noreply@plane.so>
This commit is contained in:
@@ -129,6 +129,18 @@ class WorkspaceViewViewSet(BaseViewSet):
|
||||
# membership in the workspace could therefore read any global view in it
|
||||
# by id.
|
||||
issue_view = self.get_queryset().filter(pk=pk).first()
|
||||
|
||||
# get_queryset() is scoped to the URL workspace, so None means either no
|
||||
# such view or one belonging to a workspace this URL does not name.
|
||||
# Serializing None yields a hollow object — every field null or empty —
|
||||
# returned as 200, and enqueues a recent-visit for an entity that does
|
||||
# not exist. Answer 404, as the other retrieve endpoints do.
|
||||
if issue_view is None:
|
||||
return Response(
|
||||
{"error": "The required object does not exist."},
|
||||
status=status.HTTP_404_NOT_FOUND,
|
||||
)
|
||||
|
||||
serializer = IssueViewSerializer(issue_view)
|
||||
recent_visited_task.delay(
|
||||
slug=slug,
|
||||
|
||||
@@ -249,6 +249,20 @@ class TestWorkspaceViewRetrieveRequiresMembership:
|
||||
)
|
||||
assert str(response.data["id"]) == str(workspace_view.id)
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_missing_view_is_a_404_not_an_empty_200(self, session_client, workspace):
|
||||
"""A member asking for a view id that does not exist must get 404.
|
||||
|
||||
get_queryset() is scoped to the URL workspace, so this also covers a real
|
||||
view id belonging to a different workspace.
|
||||
"""
|
||||
url = WORKSPACE_VIEW_DETAIL_URL.format(slug=workspace.slug, pk=uuid4())
|
||||
response = session_client.get(url)
|
||||
|
||||
assert response.status_code == status.HTTP_404_NOT_FOUND, (
|
||||
f"Got {response.status_code}: {getattr(response, 'data', None)!r}"
|
||||
)
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_workspace_guest_can_read_a_global_view(self, workspace, workspace_view):
|
||||
"""Positive control: the role set matches list(), which permits guests."""
|
||||
|
||||
Reference in New Issue
Block a user