fix(api/v2): scope project view delete to its parent project

This commit is contained in:
kolaente 2026-06-01 14:28:53 +02:00 committed by kolaente
parent 9858792123
commit 738bcd0c77
2 changed files with 16 additions and 0 deletions

View File

@ -269,6 +269,13 @@ func (pv *ProjectView) ReadOne(s *xorm.Session, _ web.Auth) (err error) {
// @Failure 500 {object} models.Message "Internal error"
// @Router /projects/{project}/views/{id} [delete]
func (pv *ProjectView) Delete(s *xorm.Session, _ web.Auth) (err error) {
// Resolve the view under the path project first: the buckets/positions below are deleted by
// view id alone, so without this guard a delete scoped to the wrong parent project would still
// wipe another project's buckets and positions while matching zero project_views rows.
if _, err = GetProjectViewByIDAndProject(s, pv.ID, pv.ProjectID); err != nil {
return err
}
_, err = s.
Where("id = ? AND project_id = ?", pv.ID, pv.ProjectID).
Delete(&ProjectView{})

View File

@ -143,6 +143,15 @@ func TestProjectView(t *testing.T) {
assert.Equal(t, http.StatusNoContent, rec.Code)
assert.Empty(t, rec.Body.String())
})
t.Run("View from another project", func(t *testing.T) {
// view 5 belongs to project 2. testuser1 admins the path project (1),
// so CanDelete passes — but the view isn't under project 1. The Delete
// guard must 404 before touching project 2's buckets/positions, which
// the old code wiped via a project_view_id-only delete.
_, err := owned.testDeleteWithUser(nil, map[string]string{"view": "5"})
require.Error(t, err)
assert.Equal(t, http.StatusNotFound, getHTTPErrorCode(err))
})
t.Run("Forbidden", func(t *testing.T) {
_, err := forbidden.testDeleteWithUser(nil, map[string]string{"view": "5"})
require.Error(t, err)