mirror of
https://github.com/makeplane/plane.git
synced 2026-09-02 12:09:14 +02:00
WorkspaceViewViewSet.retrieve was the only action on the class with no authorization check, and its queryset supplied none either. It filters on workspace__slug and then `Q(owned_by=request.user) | Q(access=1)`. That second clause reads as a visibility predicate but is vacuous: `access` sits in IssueViewSerializer.read_only_fields so the API never sets it, and the model defaults it to 1 (Public), so every row matches. Any authenticated account holding a view id could therefore read any global view in any workspace, including one it had no membership in. Requires workspace membership, matching the role set on list(). Also adds regression coverage for IssueDetailIdentifierEndpoint. That endpoint was reported as missing the guest restriction; it is not — the membership check at the top of get() is followed, after the issue is fetched, by an explicit role-5 / guest_view_all_features / created_by check. It had no test, so a guard preventing a guest from walking PROJ-1..PROJ-N and reading every work item's description_html was one refactor from being lost silently. Verified non-vacuous: neutering that check makes the test fail with 200 and the foreign work item's full payload. Co-authored-by: Plane AI <noreply@plane.so>