From 7ac2c42e4dc7d3509ab400f62bbe2d5ad7a17005 Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 11 Dec 2024 17:05:51 +0100 Subject: [PATCH] fix(caldav): fetch saved filter This fixes a bug which caused fetching saved filter and favorite projects to crash, because the respective project ID is not a valid project id without special handling. --- pkg/models/listeners.go | 4 ++-- pkg/models/project.go | 14 +++++++------- pkg/models/project_rights.go | 8 ++++---- pkg/models/project_view_rights.go | 8 ++++---- pkg/models/saved_filters.go | 12 ++++++------ pkg/models/saved_filters_rights.go | 2 +- pkg/models/saved_filters_test.go | 4 ++-- pkg/models/task_collection.go | 2 +- pkg/models/task_position.go | 2 +- pkg/routes/caldav/handler.go | 15 +++++++++++++++ 10 files changed, 43 insertions(+), 28 deletions(-) diff --git a/pkg/models/listeners.go b/pkg/models/listeners.go index 25d6dcf02..40bb51ae4 100644 --- a/pkg/models/listeners.go +++ b/pkg/models/listeners.go @@ -663,7 +663,7 @@ func (l *UpdateTaskInSavedFilterViews) Handle(msg *message.Message) (err error) filterIDs := []int64{} for _, view := range kanbanFilterViews { - filterIDs = append(filterIDs, getSavedFilterIDFromProjectID(view.ProjectID)) + filterIDs = append(filterIDs, GetSavedFilterIDFromProjectID(view.ProjectID)) } filters := map[int64]*SavedFilter{} @@ -688,7 +688,7 @@ func (l *UpdateTaskInSavedFilterViews) Handle(msg *message.Message) (err error) viewIDToCleanUp := []int64{} for _, view := range kanbanFilterViews { - filter, exists := filters[getSavedFilterIDFromProjectID(view.ProjectID)] + filter, exists := filters[GetSavedFilterIDFromProjectID(view.ProjectID)] if !exists { log.Debugf("Did not find filter for view %d", view.ID) continue diff --git a/pkg/models/project.go b/pkg/models/project.go index 68455478b..d14b7a0aa 100644 --- a/pkg/models/project.go +++ b/pkg/models/project.go @@ -265,10 +265,10 @@ func (p *Project) ReadOne(s *xorm.Session, a web.Auth) (err error) { } // Check for saved filters - filterID := getSavedFilterIDFromProjectID(p.ID) + filterID := GetSavedFilterIDFromProjectID(p.ID) isFilter := filterID > 0 if isFilter { - sf, err := getSavedFilterSimpleByID(s, filterID) + sf, err := GetSavedFilterSimpleByID(s, filterID) if err != nil { return err } @@ -591,7 +591,7 @@ func getSavedFilterProjects(s *xorm.Session, doer *user.User) (savedFiltersProje } for _, filter := range savedFilters { - filterProject := filter.toProject() + filterProject := filter.ToProject() filterProject.Owner = doer savedFiltersProjects = append(savedFiltersProjects, filterProject) } @@ -735,7 +735,7 @@ func addProjectDetails(s *xorm.Session, projects []*Project, a web.Auth) (err er func addMaxRightToProjects(s *xorm.Session, projects []*Project, u *user.User) (err error) { projectIDs := make([]int64, 0, len(projects)) for _, project := range projects { - if getSavedFilterIDFromProjectID(project.ID) > 0 { + if GetSavedFilterIDFromProjectID(project.ID) > 0 { project.MaxRight = RightAdmin continue } @@ -1039,9 +1039,9 @@ func recalculateProjectPositions(s *xorm.Session, parentProjectID int64) (err er // @Failure 500 {object} models.Message "Internal error" // @Router /projects/{id} [post] func (p *Project) Update(s *xorm.Session, a web.Auth) (err error) { - fid := getSavedFilterIDFromProjectID(p.ID) + fid := GetSavedFilterIDFromProjectID(p.ID) if fid > 0 { - f, err := getSavedFilterSimpleByID(s, fid) + f, err := GetSavedFilterSimpleByID(s, fid) if err != nil { return err } @@ -1054,7 +1054,7 @@ func (p *Project) Update(s *xorm.Session, a web.Auth) (err error) { return err } - *p = *f.toProject() + *p = *f.ToProject() return nil } diff --git a/pkg/models/project_rights.go b/pkg/models/project_rights.go index 88b83bdfe..5b3ef70e1 100644 --- a/pkg/models/project_rights.go +++ b/pkg/models/project_rights.go @@ -86,8 +86,8 @@ func (p *Project) CanRead(s *xorm.Session, a web.Auth) (bool, int, error) { } // Saved Filter Projects need a special case - if getSavedFilterIDFromProjectID(p.ID) > 0 { - sf := &SavedFilter{ID: getSavedFilterIDFromProjectID(p.ID)} + if GetSavedFilterIDFromProjectID(p.ID) > 0 { + sf := &SavedFilter{ID: GetSavedFilterIDFromProjectID(p.ID)} return sf.CanRead(s, a) } @@ -117,9 +117,9 @@ func (p *Project) CanUpdate(s *xorm.Session, a web.Auth) (canUpdate bool, err er return false, nil } - fid := getSavedFilterIDFromProjectID(p.ID) + fid := GetSavedFilterIDFromProjectID(p.ID) if fid > 0 { - sf, err := getSavedFilterSimpleByID(s, fid) + sf, err := GetSavedFilterSimpleByID(s, fid) if err != nil { return false, err } diff --git a/pkg/models/project_view_rights.go b/pkg/models/project_view_rights.go index 553dbd858..68b7c3b87 100644 --- a/pkg/models/project_view_rights.go +++ b/pkg/models/project_view_rights.go @@ -22,7 +22,7 @@ import ( ) func (pv *ProjectView) CanRead(s *xorm.Session, a web.Auth) (bool, int, error) { - filterID := getSavedFilterIDFromProjectID(pv.ProjectID) + filterID := GetSavedFilterIDFromProjectID(pv.ProjectID) if filterID > 0 { sf := &SavedFilter{ID: filterID} return sf.CanRead(s, a) @@ -33,7 +33,7 @@ func (pv *ProjectView) CanRead(s *xorm.Session, a web.Auth) (bool, int, error) { } func (pv *ProjectView) CanDelete(s *xorm.Session, a web.Auth) (bool, error) { - filterID := getSavedFilterIDFromProjectID(pv.ProjectID) + filterID := GetSavedFilterIDFromProjectID(pv.ProjectID) if filterID > 0 { sf := &SavedFilter{ID: filterID} return sf.CanDelete(s, a) @@ -44,7 +44,7 @@ func (pv *ProjectView) CanDelete(s *xorm.Session, a web.Auth) (bool, error) { } func (pv *ProjectView) CanUpdate(s *xorm.Session, a web.Auth) (bool, error) { - filterID := getSavedFilterIDFromProjectID(pv.ProjectID) + filterID := GetSavedFilterIDFromProjectID(pv.ProjectID) if filterID > 0 { sf := &SavedFilter{ID: filterID} return sf.CanUpdate(s, a) @@ -55,7 +55,7 @@ func (pv *ProjectView) CanUpdate(s *xorm.Session, a web.Auth) (bool, error) { } func (pv *ProjectView) CanCreate(s *xorm.Session, a web.Auth) (bool, error) { - filterID := getSavedFilterIDFromProjectID(pv.ProjectID) + filterID := GetSavedFilterIDFromProjectID(pv.ProjectID) if filterID > 0 { sf := &SavedFilter{ID: filterID} return sf.CanUpdate(s, a) diff --git a/pkg/models/saved_filters.go b/pkg/models/saved_filters.go index 4d17f0535..8a2927cc0 100644 --- a/pkg/models/saved_filters.go +++ b/pkg/models/saved_filters.go @@ -68,9 +68,9 @@ func (sf *SavedFilter) getTaskCollection() *TaskCollection { return sf.Filters } -// Returns the saved filter ID from a project ID. Will not check if the filter actually exists. +// GetSavedFilterIDFromProjectID returns the saved filter ID from a project ID. Will not check if the filter actually exists. // If the returned ID is zero, means that it is probably invalid. -func getSavedFilterIDFromProjectID(projectID int64) (filterID int64) { +func GetSavedFilterIDFromProjectID(projectID int64) (filterID int64) { // We get the id of the saved filter by multiplying the ProjectID with -1 and subtracting one filterID = projectID*-1 - 1 // FilterIDs from projectIDs are always positive @@ -99,7 +99,7 @@ func getSavedFiltersForUser(s *xorm.Session, auth web.Auth) (filters []*SavedFil return } -func (sf *SavedFilter) toProject() *Project { +func (sf *SavedFilter) ToProject() *Project { return &Project{ ID: getProjectIDFromSavedFilterID(sf.ID), Title: sf.Title, @@ -139,7 +139,7 @@ func (sf *SavedFilter) Create(s *xorm.Session, auth web.Auth) (err error) { return err } -func getSavedFilterSimpleByID(s *xorm.Session, id int64) (sf *SavedFilter, err error) { +func GetSavedFilterSimpleByID(s *xorm.Session, id int64) (sf *SavedFilter, err error) { sf = &SavedFilter{} exists, err := s. Where("id = ?", id). @@ -186,7 +186,7 @@ func (sf *SavedFilter) ReadOne(s *xorm.Session, _ web.Auth) error { // @Failure 500 {object} models.Message "Internal error" // @Router /filters/{id} [post] func (sf *SavedFilter) Update(s *xorm.Session, _ web.Auth) error { - origFilter, err := getSavedFilterSimpleByID(s, sf.ID) + origFilter, err := GetSavedFilterSimpleByID(s, sf.ID) if err != nil { return err } @@ -433,7 +433,7 @@ func RegisterAddTaskToFilterViewCron() { deleteCond := []builder.Cond{} taskIDsToRemove := []int64{} for _, view := range kanbanFilterViews { - filterID := getSavedFilterIDFromProjectID(view.ProjectID) + filterID := GetSavedFilterIDFromProjectID(view.ProjectID) filter, exists := filters[filterID] if !exists { log.Debugf("%sDid not find filter for view %d", logPrefix, view.ID) diff --git a/pkg/models/saved_filters_rights.go b/pkg/models/saved_filters_rights.go index 3794a7d58..c1e7e5ead 100644 --- a/pkg/models/saved_filters_rights.go +++ b/pkg/models/saved_filters_rights.go @@ -55,7 +55,7 @@ func (sf *SavedFilter) canDoFilter(s *xorm.Session, auth web.Auth) (can bool, er return false, ErrSavedFilterNotAvailableForLinkShare{LinkShareID: auth.GetID(), SavedFilterID: sf.ID} } - sff, err := getSavedFilterSimpleByID(s, sf.ID) + sff, err := GetSavedFilterSimpleByID(s, sf.ID) if err != nil { return false, err } diff --git a/pkg/models/saved_filters_test.go b/pkg/models/saved_filters_test.go index e1e514d61..1434870c1 100644 --- a/pkg/models/saved_filters_test.go +++ b/pkg/models/saved_filters_test.go @@ -38,10 +38,10 @@ func TestSavedFilter_getProjectIDFromFilter(t *testing.T) { func TestSavedFilter_getFilterIDFromProjectID(t *testing.T) { t.Run("normal", func(t *testing.T) { - assert.Equal(t, int64(1), getSavedFilterIDFromProjectID(-2)) + assert.Equal(t, int64(1), GetSavedFilterIDFromProjectID(-2)) }) t.Run("invalid", func(t *testing.T) { - assert.Equal(t, int64(0), getSavedFilterIDFromProjectID(2)) + assert.Equal(t, int64(0), GetSavedFilterIDFromProjectID(2)) }) } diff --git a/pkg/models/task_collection.go b/pkg/models/task_collection.go index 299096df5..71b9a9046 100644 --- a/pkg/models/task_collection.go +++ b/pkg/models/task_collection.go @@ -234,7 +234,7 @@ func (tf *TaskCollection) ReadAll(s *xorm.Session, a web.Auth, search string, pa // If the project id is < -1 this means we're dealing with a saved filter - in that case we get and populate the filter // -1 is the favorites project which works as intended if !tf.isSavedFilter && tf.ProjectID < -1 { - sf, err := getSavedFilterSimpleByID(s, getSavedFilterIDFromProjectID(tf.ProjectID)) + sf, err := GetSavedFilterSimpleByID(s, GetSavedFilterIDFromProjectID(tf.ProjectID)) if err != nil { return nil, 0, 0, err } diff --git a/pkg/models/task_position.go b/pkg/models/task_position.go index f70d84ca2..b2202c3aa 100644 --- a/pkg/models/task_position.go +++ b/pkg/models/task_position.go @@ -138,7 +138,7 @@ func RecalculateTaskPositions(s *xorm.Session, view *ProjectView, a web.Auth) (e if view.ProjectID < -1 { tc.ProjectID = 0 - sf, err := getSavedFilterSimpleByID(s, getSavedFilterIDFromProjectID(view.ProjectID)) + sf, err := GetSavedFilterSimpleByID(s, GetSavedFilterIDFromProjectID(view.ProjectID)) if err != nil { return err } diff --git a/pkg/routes/caldav/handler.go b/pkg/routes/caldav/handler.go index e78cef40e..88bbb5726 100644 --- a/pkg/routes/caldav/handler.go +++ b/pkg/routes/caldav/handler.go @@ -183,6 +183,21 @@ func getProjectFromParam(c echo.Context) (project *models.ProjectWithTasksAndBuc return nil, err } + if intParam == models.FavoritesPseudoProjectID { + return &models.ProjectWithTasksAndBuckets{Project: models.FavoritesPseudoProject}, nil + } + + if intParam < models.FavoritesPseudoProjectID { + var sf *models.SavedFilter + sf, err = models.GetSavedFilterSimpleByID(s, models.GetSavedFilterIDFromProjectID(intParam)) + if err != nil { + return nil, err + } + + project = &models.ProjectWithTasksAndBuckets{Project: *sf.ToProject()} + return + } + p, err := models.GetProjectSimpleByID(s, intParam) if err != nil { return nil, err