mirror of
https://github.com/makeplane/plane.git
synced 2026-09-02 03:59:00 +02:00
ProjectInvitationsViewset declared no permission_classes (inheriting IsAuthenticated) and only decorated create with @allow_permission([ADMIN]). The default list/retrieve/destroy actions were ungated and get_queryset was scoped only by URL slug + project_id, so any authenticated user could read another project's pending invitations — including invitee email and the raw token (re-exposing what #9305 stripped from the public path) — and delete them. Gate list/retrieve/destroy with @allow_permission([ROLE.ADMIN]), matching create (project admin, or a workspace-admin who is a project member). The workspace sibling WorkspaceInvitationsViewset was already admin-gated. Also drop a pre-existing unused User import in the same file. Adds contract regression tests (fail-before verified): a non-member of the project is rejected with 403 on list/retrieve/destroy (invite left intact), with a positive control confirming a project admin can still list. Co-authored-by: Plane AI <noreply@plane.so>