Skip to content

Commit 738bcd0

Browse files
committed
fix(api/v2): scope project view delete to its parent project
1 parent 9858792 commit 738bcd0

2 files changed

Lines changed: 16 additions & 0 deletions

File tree

pkg/models/project_view.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,13 @@ func (pv *ProjectView) ReadOne(s *xorm.Session, _ web.Auth) (err error) {
269269
// @Failure 500 {object} models.Message "Internal error"
270270
// @Router /projects/{project}/views/{id} [delete]
271271
func (pv *ProjectView) Delete(s *xorm.Session, _ web.Auth) (err error) {
272+
// Resolve the view under the path project first: the buckets/positions below are deleted by
273+
// view id alone, so without this guard a delete scoped to the wrong parent project would still
274+
// wipe another project's buckets and positions while matching zero project_views rows.
275+
if _, err = GetProjectViewByIDAndProject(s, pv.ID, pv.ProjectID); err != nil {
276+
return err
277+
}
278+
272279
_, err = s.
273280
Where("id = ? AND project_id = ?", pv.ID, pv.ProjectID).
274281
Delete(&ProjectView{})

pkg/webtests/huma_project_view_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,15 @@ func TestProjectView(t *testing.T) {
143143
assert.Equal(t, http.StatusNoContent, rec.Code)
144144
assert.Empty(t, rec.Body.String())
145145
})
146+
t.Run("View from another project", func(t *testing.T) {
147+
// view 5 belongs to project 2. testuser1 admins the path project (1),
148+
// so CanDelete passes — but the view isn't under project 1. The Delete
149+
// guard must 404 before touching project 2's buckets/positions, which
150+
// the old code wiped via a project_view_id-only delete.
151+
_, err := owned.testDeleteWithUser(nil, map[string]string{"view": "5"})
152+
require.Error(t, err)
153+
assert.Equal(t, http.StatusNotFound, getHTTPErrorCode(err))
154+
})
146155
t.Run("Forbidden", func(t *testing.T) {
147156
_, err := forbidden.testDeleteWithUser(nil, map[string]string{"view": "5"})
148157
require.Error(t, err)

0 commit comments

Comments
 (0)