mirror of
https://github.com/makeplane/plane.git
synced 2026-09-02 03:59:00 +02:00
ProjectArchiveUnarchiveAPIEndpoint used ProjectBasePermission, whose POST branch is written for project creation and checks only workspace-level role (ADMIN/MEMBER) with no project_id binding at all. Since archive is POST but is not creation, any active workspace member could archive (and delete every UserFavorite row on) any project in the workspace, including a fully private one they have no ProjectMember row on and cannot otherwise read. DELETE (unarchive) was never affected by this — it falls through to ProjectBasePermission's non-POST branch, which does check project membership, so this was an asymmetry between the two verbs of the same endpoint (and that branch was itself stricter than intended: it required project ADMIN or workspace-ADMIN-plus-project-membership, not just an active project MEMBER). Give the endpoint a dedicated ProjectArchiveUnarchivePermission, scoped to project_id, mirroring the app-layer twin's gate (active ProjectMember with role ADMIN or MEMBER, or any active ProjectMember plus a workspace ADMIN) on both post and delete — instead of touching ProjectBasePermission itself, which is correctly relied on by the actual project-create endpoint and by ProjectDetailAPIEndpoint's patch/delete. 3 new tests, fail-before verified. Co-authored-by: Plane AI <noreply@plane.so>