mirror of
https://github.com/makeplane/plane.git
synced 2026-09-01 19:48:42 +02:00
* [WEB-8068] fix: scope workspace cycles/modules listing to project membership WorkspaceCyclesEndpoint and WorkspaceModulesEndpoint are guarded only by WorkspaceViewerPermission (any active workspace member) and filtered by workspace__slug alone, letting any workspace member enumerate cycle/module metadata (names, dates, issue counts) of private projects they are not a member of (GHSA-wcc5-qgfr-8g9c). Restrict both querysets to projects the requesting user is an active member of, mirroring WorkspaceStatesEndpoint / WorkspaceLabelsEndpoint: project__project_projectmember__member=request.user project__project_projectmember__is_active=True project__archived_at__isnull=True Add .distinct() to the Module query (the member join is to-many; Cycle already had it). Contract regression tests cover hidden cycles/modules for a non-project member, the positive project-member path, and no row duplication; fail-before verified. Co-authored-by: Plane AI <noreply@plane.so> * [WEB-8068] refactor: drop unnecessary distinct() from module listing Address Copilot review: the project-membership join is filtered to request.user, and ProjectMember has a unique constraint on (project, member) where deleted_at IS NULL, so the join yields at most one row per project and cannot duplicate Module rows. distinct() was dead weight (and a planner cost for large workspaces). Matches the reference WorkspaceStates/WorkspaceLabels endpoints, which use no distinct(). Also drop the distinct-focused contract test: adding a *different* project member never fans out the request.user-filtered join, so it would pass with or without distinct() — misleading coverage. Co-authored-by: Plane AI <noreply@plane.so> --------- Co-authored-by: Plane AI <noreply@plane.so>