diff --git a/docs/content/doc/usage/errors.md b/docs/content/doc/usage/errors.md index 53a6e1fd6..d90a50fa5 100644 --- a/docs/content/doc/usage/errors.md +++ b/docs/content/doc/usage/errors.md @@ -63,6 +63,7 @@ This document describes the different errors Vikunja can return. | 3007 | 400 | A project with this identifier already exists. | | 3008 | 412 | The project is archived and can therefore only be accessed read only. This is also true for all tasks associated with this project. | | 3009 | 412 | The project cannot belong to a dynamically generated namespace like "Favorites". | +| 3010 | 412 | This project cannot be a child of itself.| ## Task diff --git a/pkg/models/error.go b/pkg/models/error.go index 6b7bb726c..5a9d1acdf 100644 --- a/pkg/models/error.go +++ b/pkg/models/error.go @@ -283,8 +283,35 @@ func (err *ErrProjectCannotBelongToAPseudoParentProject) HTTPError() web.HTTPErr } } +// ErrProjectCannotBeChildOfItself represents an error where a project cannot become a child of its own +type ErrProjectCannotBeChildOfItself struct { + ProjectID int64 +} + +// IsErrProjectCannotBeChildOfItsOwn checks if an error is a project is archived error. +func IsErrProjectCannotBeChildOfItsOwn(err error) bool { + _, ok := err.(*ErrProjectCannotBeChildOfItself) + return ok +} + +func (err *ErrProjectCannotBeChildOfItself) Error() string { + return fmt.Sprintf("Project cannot be made a child of itself [ProjectID: %d]", err.ProjectID) +} + +// ErrCodeProjectCannotBeChildOfItself holds the unique world-error code of this error +const ErrCodeProjectCannotBeChildOfItself = 3010 + +// HTTPError holds the http error description +func (err *ErrProjectCannotBeChildOfItself) HTTPError() web.HTTPError { + return web.HTTPError{ + HTTPCode: http.StatusPreconditionFailed, + Code: ErrCodeProjectCannotBeChildOfItself, + Message: "This project cannot be a child of itself.", + } +} + // ============== -// Project errors +// Task errors // ============== // ErrTaskCannotBeEmpty represents a "ErrProjectDoesNotExist" kind of error. Used if the project does not exist. diff --git a/pkg/models/project.go b/pkg/models/project.go index 7a8b324c3..83ae66b92 100644 --- a/pkg/models/project.go +++ b/pkg/models/project.go @@ -641,6 +641,12 @@ func checkProjectBeforeUpdateOrDelete(s *xorm.Session, project *Project) error { // Check if the parent project exists if project.ParentProjectID > 0 { + if project.ParentProjectID == project.ID { + return &ErrProjectCannotBeChildOfItself{ + ProjectID: project.ID, + } + } + _, err := GetProjectSimpleByID(s, project.ParentProjectID) if err != nil { return err