Add session handling for tasks and related entities
This commit is contained in:
parent
1528e7d861
commit
7b1d838997
|
@ -222,7 +222,7 @@ func getUserTaskIDs(s *xorm.Session, u *user.User) (taskIDs []int64, err error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
tasks, _, _, err := getRawTasksForLists(lists, u, &taskOptions{
|
||||
tasks, _, _, err := getRawTasksForLists(s, lists, u, &taskOptions{
|
||||
page: -1,
|
||||
perPage: 0,
|
||||
})
|
||||
|
|
|
@ -88,7 +88,7 @@ func (l *Label) hasAccessToLabel(s *xorm.Session, a web.Auth) (has bool, maxRigh
|
|||
// Since the right depends on the task the label is associated with, we need to check that too.
|
||||
if ll.TaskID > 0 {
|
||||
t := &Task{ID: ll.TaskID}
|
||||
_, maxRight, err = t.CanRead(a)
|
||||
_, maxRight, err = t.CanRead(s, a)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ func (lt *LabelTask) Create(s *xorm.Session, a web.Auth) (err error) {
|
|||
func (lt *LabelTask) ReadAll(s *xorm.Session, a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, numberOfTotalItems int64, err error) {
|
||||
// Check if the user has the right to see the task
|
||||
task := Task{ID: lt.TaskID}
|
||||
canRead, _, err := task.CanRead(a)
|
||||
canRead, _, err := task.CanRead(s, a)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ type LabelTaskBulk struct {
|
|||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /tasks/{taskID}/labels/bulk [post]
|
||||
func (ltb *LabelTaskBulk) Create(s *xorm.Session, a web.Auth) (err error) {
|
||||
task, err := GetTaskByIDSimple(ltb.TaskID)
|
||||
task, err := GetTaskByIDSimple(s, ltb.TaskID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -70,9 +70,9 @@ func (ltb *LabelTaskBulk) CanCreate(s *xorm.Session, a web.Auth) (bool, error) {
|
|||
// always the same check for either deleting or adding a label to a task
|
||||
func canDoLabelTask(s *xorm.Session, taskID int64, a web.Auth) (bool, error) {
|
||||
// A user can add a label to a task if he can write to the task
|
||||
task, err := GetTaskByIDSimple(taskID)
|
||||
task, err := GetTaskByIDSimple(s, taskID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return task.CanUpdate(a)
|
||||
return task.CanUpdate(s, a)
|
||||
}
|
||||
|
|
|
@ -548,7 +548,7 @@ func updateListLastUpdated(s *xorm.Session, list *List) error {
|
|||
|
||||
func updateListByTaskID(s *xorm.Session, taskID int64) (err error) {
|
||||
// need to get the task to update the list last updated timestamp
|
||||
task, err := GetTaskByIDSimple(taskID)
|
||||
task, err := GetTaskByIDSimple(s, taskID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ func (ld *ListDuplicate) Create(s *xorm.Session, a web.Auth) (err error) {
|
|||
log.Debugf("Duplicated all buckets from list %d into %d", ld.ListID, ld.List.ID)
|
||||
|
||||
// Get all tasks + all task details
|
||||
tasks, _, _, err := getTasksForLists([]*List{{ID: ld.ListID}}, a, &taskOptions{})
|
||||
tasks, _, _, err := getTasksForLists(s, []*List{{ID: ld.ListID}}, a, &taskOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -301,7 +301,7 @@ type BulkAssignees struct {
|
|||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /tasks/{taskID}/assignees/bulk [post]
|
||||
func (ba *BulkAssignees) Create(s *xorm.Session, a web.Auth) (err error) {
|
||||
task, err := GetTaskByIDSimple(ba.TaskID)
|
||||
task, err := GetTaskByIDSimple(s, ba.TaskID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -24,20 +24,20 @@ import (
|
|||
// CanRead checks if the user can see an attachment
|
||||
func (ta *TaskAttachment) CanRead(s *xorm.Session, a web.Auth) (bool, int, error) {
|
||||
t := &Task{ID: ta.TaskID}
|
||||
return t.CanRead(a)
|
||||
return t.CanRead(s, a)
|
||||
}
|
||||
|
||||
// CanDelete checks if the user can delete an attachment
|
||||
func (ta *TaskAttachment) CanDelete(s *xorm.Session, a web.Auth) (bool, error) {
|
||||
t := &Task{ID: ta.TaskID}
|
||||
return t.CanWrite(a)
|
||||
return t.CanWrite(s, a)
|
||||
}
|
||||
|
||||
// CanCreate checks if the user can create an attachment
|
||||
func (ta *TaskAttachment) CanCreate(s *xorm.Session, a web.Auth) (bool, error) {
|
||||
t, err := GetTaskByIDSimple(ta.TaskID)
|
||||
t, err := GetTaskByIDSimple(s, ta.TaskID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return t.CanCreate(a)
|
||||
return t.CanCreate(s, a)
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ func (tf *TaskCollection) ReadAll(s *xorm.Session, a web.Auth, search string, pa
|
|||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
return getTasksForLists([]*List{list}, a, taskopts)
|
||||
return getTasksForLists(s, []*List{list}, a, taskopts)
|
||||
}
|
||||
|
||||
// If the list ID is not set, we get all tasks for the user.
|
||||
|
@ -190,5 +190,5 @@ func (tf *TaskCollection) ReadAll(s *xorm.Session, a web.Auth, search string, pa
|
|||
tf.Lists = []*List{{ID: tf.ListID}}
|
||||
}
|
||||
|
||||
return getTasksForLists(tf.Lists, a, taskopts)
|
||||
return getTasksForLists(s, tf.Lists, a, taskopts)
|
||||
}
|
||||
|
|
|
@ -25,23 +25,23 @@ import (
|
|||
// CanRead checks if a user can read a comment
|
||||
func (tc *TaskComment) CanRead(s *xorm.Session, a web.Auth) (bool, int, error) {
|
||||
t := Task{ID: tc.TaskID}
|
||||
return t.CanRead(a)
|
||||
return t.CanRead(s, a)
|
||||
}
|
||||
|
||||
// CanDelete checks if a user can delete a comment
|
||||
func (tc *TaskComment) CanDelete(s *xorm.Session, a web.Auth) (bool, error) {
|
||||
t := Task{ID: tc.TaskID}
|
||||
return t.CanWrite(a)
|
||||
return t.CanWrite(s, a)
|
||||
}
|
||||
|
||||
// CanUpdate checks if a user can update a comment
|
||||
func (tc *TaskComment) CanUpdate(s *xorm.Session, a web.Auth) (bool, error) {
|
||||
t := Task{ID: tc.TaskID}
|
||||
return t.CanWrite(a)
|
||||
return t.CanWrite(s, a)
|
||||
}
|
||||
|
||||
// CanCreate checks if a user can create a new comment
|
||||
func (tc *TaskComment) CanCreate(s *xorm.Session, a web.Auth) (bool, error) {
|
||||
t := Task{ID: tc.TaskID}
|
||||
return t.CanWrite(a)
|
||||
return t.CanWrite(s, a)
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ func (tc *TaskComment) TableName() string {
|
|||
// @Router /tasks/{taskID}/comments [put]
|
||||
func (tc *TaskComment) Create(s *xorm.Session, a web.Auth) (err error) {
|
||||
// Check if the task exists
|
||||
_, err = GetTaskSimple(&Task{ID: tc.TaskID})
|
||||
_, err = GetTaskSimple(s, &Task{ID: tc.TaskID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
func (rel *TaskRelation) CanDelete(s *xorm.Session, a web.Auth) (bool, error) {
|
||||
// A user can delete a relation if it can update the base task
|
||||
baseTask := &Task{ID: rel.TaskID}
|
||||
return baseTask.CanUpdate(a)
|
||||
return baseTask.CanUpdate(s, a)
|
||||
}
|
||||
|
||||
// CanCreate checks if a user can create a new relation between two relations
|
||||
|
@ -38,14 +38,14 @@ func (rel *TaskRelation) CanCreate(s *xorm.Session, a web.Auth) (bool, error) {
|
|||
|
||||
// Needs have write access to the base task and at least read access to the other task
|
||||
baseTask := &Task{ID: rel.TaskID}
|
||||
has, err := baseTask.CanUpdate(a)
|
||||
has, err := baseTask.CanUpdate(s, a)
|
||||
if err != nil || !has {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// We explicitly don't check if the two tasks are on the same list.
|
||||
otherTask := &Task{ID: rel.OtherTaskID}
|
||||
has, _, err = otherTask.CanRead(a)
|
||||
has, _, err = otherTask.CanRead(s, a)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ type taskOptions struct {
|
|||
// @Success 200 {array} models.Task "The tasks"
|
||||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /tasks/all [get]
|
||||
func (t *Task) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, totalItems int64, err error) {
|
||||
func (t *Task) ReadAll(s *xorm.Session, a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, totalItems int64, err error) {
|
||||
return nil, 0, 0, nil
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,7 @@ func getFilterCondForSeparateTable(table string, concat taskFilterConcatinator,
|
|||
}
|
||||
|
||||
//nolint:gocyclo
|
||||
func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []*Task, resultCount int, totalItems int64, err error) {
|
||||
func getRawTasksForLists(s *xorm.Session, lists []*List, a web.Auth, opts *taskOptions) (tasks []*Task, resultCount int, totalItems int64, err error) {
|
||||
|
||||
// If the user does not have any lists, don't try to get any tasks
|
||||
if len(lists) == 0 {
|
||||
|
@ -324,9 +324,7 @@ func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []
|
|||
}
|
||||
|
||||
// Then return all tasks for that lists
|
||||
query := x.NewSession().
|
||||
OrderBy(orderby)
|
||||
queryCount := x.NewSession()
|
||||
var where builder.Cond
|
||||
|
||||
if len(opts.search) > 0 {
|
||||
// Postgres' is case sensitive by default.
|
||||
|
@ -335,11 +333,9 @@ func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []
|
|||
// See https://stackoverflow.com/q/7005302/10924593
|
||||
// Seems okay to use that now, we may need to find a better solution overall in the future.
|
||||
if config.DatabaseType.GetString() == "postgres" {
|
||||
query = query.Where("title ILIKE ?", "%"+opts.search+"%")
|
||||
queryCount = queryCount.Where("title ILIKE ?", "%"+opts.search+"%")
|
||||
where = builder.Expr("title ILIKE ?", "%"+opts.search+"%")
|
||||
} else {
|
||||
query = query.Where("title LIKE ?", "%"+opts.search+"%")
|
||||
queryCount = queryCount.Where("title LIKE ?", "%"+opts.search+"%")
|
||||
where = &builder.Like{"title LIKE ?", "%" + opts.search + "%"}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,10 +348,13 @@ func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []
|
|||
|
||||
if hasFavoriteLists {
|
||||
// Make sure users can only see their favorites
|
||||
userLists, _, _, err := getRawListsForUser(&listOptions{
|
||||
user: &user.User{ID: a.GetID()},
|
||||
page: -1,
|
||||
})
|
||||
userLists, _, _, err := getRawListsForUser(
|
||||
s,
|
||||
&listOptions{
|
||||
user: &user.User{ID: a.GetID()},
|
||||
page: -1,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
@ -399,8 +398,8 @@ func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []
|
|||
filters = append(filters, cond)
|
||||
}
|
||||
|
||||
query = query.Where(listCond)
|
||||
queryCount = queryCount.Where(listCond)
|
||||
query := s.Where(builder.And(listCond, where))
|
||||
queryCount := s.Where(builder.And(listCond, where))
|
||||
|
||||
if len(filters) > 0 {
|
||||
if opts.filterConcat == filterConcatOr {
|
||||
|
@ -434,9 +433,9 @@ func getRawTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []
|
|||
return tasks, len(tasks), totalItems, nil
|
||||
}
|
||||
|
||||
func getTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []*Task, resultCount int, totalItems int64, err error) {
|
||||
func getTasksForLists(s *xorm.Session, lists []*List, a web.Auth, opts *taskOptions) (tasks []*Task, resultCount int, totalItems int64, err error) {
|
||||
|
||||
tasks, resultCount, totalItems, err = getRawTasksForLists(lists, a, opts)
|
||||
tasks, resultCount, totalItems, err = getRawTasksForLists(s, lists, a, opts)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
@ -446,7 +445,7 @@ func getTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []*Ta
|
|||
taskMap[t.ID] = t
|
||||
}
|
||||
|
||||
err = addMoreInfoToTasks(taskMap)
|
||||
err = addMoreInfoToTasks(s, taskMap)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
@ -455,18 +454,18 @@ func getTasksForLists(lists []*List, a web.Auth, opts *taskOptions) (tasks []*Ta
|
|||
}
|
||||
|
||||
// GetTaskByIDSimple returns a raw task without extra data by the task ID
|
||||
func GetTaskByIDSimple(taskID int64) (task Task, err error) {
|
||||
func GetTaskByIDSimple(s *xorm.Session, taskID int64) (task Task, err error) {
|
||||
if taskID < 1 {
|
||||
return Task{}, ErrTaskDoesNotExist{taskID}
|
||||
}
|
||||
|
||||
return GetTaskSimple(&Task{ID: taskID})
|
||||
return GetTaskSimple(s, &Task{ID: taskID})
|
||||
}
|
||||
|
||||
// GetTaskSimple returns a raw task without extra data
|
||||
func GetTaskSimple(t *Task) (task Task, err error) {
|
||||
func GetTaskSimple(s *xorm.Session, t *Task) (task Task, err error) {
|
||||
task = *t
|
||||
exists, err := x.Get(&task)
|
||||
exists, err := s.Get(&task)
|
||||
if err != nil {
|
||||
return Task{}, err
|
||||
}
|
||||
|
@ -494,9 +493,9 @@ func (bt *BulkTask) GetTasksByIDs(s *xorm.Session) (err error) {
|
|||
}
|
||||
|
||||
// GetTasksByUIDs gets all tasks from a bunch of uids
|
||||
func GetTasksByUIDs(uids []string) (tasks []*Task, err error) {
|
||||
func GetTasksByUIDs(s *xorm.Session, uids []string) (tasks []*Task, err error) {
|
||||
tasks = []*Task{}
|
||||
err = x.In("uid", uids).Find(&tasks)
|
||||
err = s.In("uid", uids).Find(&tasks)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -506,13 +505,13 @@ func GetTasksByUIDs(uids []string) (tasks []*Task, err error) {
|
|||
taskMap[t.ID] = t
|
||||
}
|
||||
|
||||
err = addMoreInfoToTasks(taskMap)
|
||||
err = addMoreInfoToTasks(s, taskMap)
|
||||
return
|
||||
}
|
||||
|
||||
func getRemindersForTasks(taskIDs []int64) (reminders []*TaskReminder, err error) {
|
||||
func getRemindersForTasks(s *xorm.Session, taskIDs []int64) (reminders []*TaskReminder, err error) {
|
||||
reminders = []*TaskReminder{}
|
||||
err = x.In("task_id", taskIDs).Find(&reminders)
|
||||
err = s.In("task_id", taskIDs).Find(&reminders)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -521,7 +520,7 @@ func (t *Task) setIdentifier(list *List) {
|
|||
}
|
||||
|
||||
// Get all assignees
|
||||
func addAssigneesToTasks(taskIDs []int64, taskMap map[int64]*Task) (err error) {
|
||||
func addAssigneesToTasks(s *xorm.Session, taskIDs []int64, taskMap map[int64]*Task) (err error) {
|
||||
taskAssignees, err := getRawTaskAssigneesForTasks(s, taskIDs)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -538,7 +537,7 @@ func addAssigneesToTasks(taskIDs []int64, taskMap map[int64]*Task) (err error) {
|
|||
}
|
||||
|
||||
// Get all labels for all the tasks
|
||||
func addLabelsToTasks(taskIDs []int64, taskMap map[int64]*Task) (err error) {
|
||||
func addLabelsToTasks(s *xorm.Session, taskIDs []int64, taskMap map[int64]*Task) (err error) {
|
||||
labels, _, _, err := getLabelsByTaskIDs(s, &LabelByTaskIDsOptions{
|
||||
TaskIDs: taskIDs,
|
||||
Page: -1,
|
||||
|
@ -556,7 +555,7 @@ func addLabelsToTasks(taskIDs []int64, taskMap map[int64]*Task) (err error) {
|
|||
}
|
||||
|
||||
// Get task attachments
|
||||
func addAttachmentsToTasks(taskIDs []int64, taskMap map[int64]*Task) (err error) {
|
||||
func addAttachmentsToTasks(s *xorm.Session, taskIDs []int64, taskMap map[int64]*Task) (err error) {
|
||||
attachments, err := getTaskAttachmentsByTaskIDs(s, taskIDs)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -568,11 +567,11 @@ func addAttachmentsToTasks(taskIDs []int64, taskMap map[int64]*Task) (err error)
|
|||
return
|
||||
}
|
||||
|
||||
func getTaskReminderMap(taskIDs []int64) (taskReminders map[int64][]time.Time, err error) {
|
||||
func getTaskReminderMap(s *xorm.Session, taskIDs []int64) (taskReminders map[int64][]time.Time, err error) {
|
||||
taskReminders = make(map[int64][]time.Time)
|
||||
|
||||
// Get all reminders and put them in a map to have it easier later
|
||||
reminders, err := getRemindersForTasks(taskIDs)
|
||||
reminders, err := getRemindersForTasks(s, taskIDs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -584,9 +583,9 @@ func getTaskReminderMap(taskIDs []int64) (taskReminders map[int64][]time.Time, e
|
|||
return
|
||||
}
|
||||
|
||||
func addRelatedTasksToTasks(taskIDs []int64, taskMap map[int64]*Task) (err error) {
|
||||
func addRelatedTasksToTasks(s *xorm.Session, taskIDs []int64, taskMap map[int64]*Task) (err error) {
|
||||
relatedTasks := []*TaskRelation{}
|
||||
err = x.In("task_id", taskIDs).Find(&relatedTasks)
|
||||
err = s.In("task_id", taskIDs).Find(&relatedTasks)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -597,7 +596,7 @@ func addRelatedTasksToTasks(taskIDs []int64, taskMap map[int64]*Task) (err error
|
|||
relatedTaskIDs = append(relatedTaskIDs, rt.OtherTaskID)
|
||||
}
|
||||
fullRelatedTasks := make(map[int64]*Task)
|
||||
err = x.In("id", relatedTaskIDs).Find(&fullRelatedTasks)
|
||||
err = s.In("id", relatedTaskIDs).Find(&fullRelatedTasks)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -614,7 +613,7 @@ func addRelatedTasksToTasks(taskIDs []int64, taskMap map[int64]*Task) (err error
|
|||
|
||||
// This function takes a map with pointers and returns a slice with pointers to tasks
|
||||
// It adds more stuff like assignees/labels/etc to a bunch of tasks
|
||||
func addMoreInfoToTasks(taskMap map[int64]*Task) (err error) {
|
||||
func addMoreInfoToTasks(s *xorm.Session, taskMap map[int64]*Task) (err error) {
|
||||
|
||||
// No need to iterate over users and stuff if the list doesn't have tasks
|
||||
if len(taskMap) == 0 {
|
||||
|
@ -631,17 +630,17 @@ func addMoreInfoToTasks(taskMap map[int64]*Task) (err error) {
|
|||
listIDs = append(listIDs, i.ListID)
|
||||
}
|
||||
|
||||
err = addAssigneesToTasks(taskIDs, taskMap)
|
||||
err = addAssigneesToTasks(s, taskIDs, taskMap)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = addLabelsToTasks(taskIDs, taskMap)
|
||||
err = addLabelsToTasks(s, taskIDs, taskMap)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = addAttachmentsToTasks(taskIDs, taskMap)
|
||||
err = addAttachmentsToTasks(s, taskIDs, taskMap)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -651,13 +650,13 @@ func addMoreInfoToTasks(taskMap map[int64]*Task) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
taskReminders, err := getTaskReminderMap(taskIDs)
|
||||
taskReminders, err := getTaskReminderMap(s, taskIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get all identifiers
|
||||
lists, err := GetListsByIDs(listIDs)
|
||||
lists, err := GetListsByIDs(s, listIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -679,7 +678,7 @@ func addMoreInfoToTasks(taskMap map[int64]*Task) (err error) {
|
|||
}
|
||||
|
||||
// Get all related tasks
|
||||
err = addRelatedTasksToTasks(taskIDs, taskMap)
|
||||
err = addRelatedTasksToTasks(s, taskIDs, taskMap)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -739,14 +738,8 @@ func checkBucketLimit(s *xorm.Session, t *Task, bucket *Bucket) (err error) {
|
|||
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
|
||||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /lists/{id} [put]
|
||||
func (t *Task) Create(a web.Auth) (err error) {
|
||||
s := x.NewSession()
|
||||
err = createTask(s, t, a, true)
|
||||
if err != nil {
|
||||
_ = s.Rollback()
|
||||
return err
|
||||
}
|
||||
return s.Commit()
|
||||
func (t *Task) Create(s *xorm.Session, a web.Auth) (err error) {
|
||||
return createTask(s, t, a, true)
|
||||
}
|
||||
|
||||
func createTask(s *xorm.Session, t *Task, a web.Auth, updateAssignees bool) (err error) {
|
||||
|
@ -853,21 +846,17 @@ func createTask(s *xorm.Session, t *Task, a web.Auth, updateAssignees bool) (err
|
|||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /tasks/{id} [post]
|
||||
//nolint:gocyclo
|
||||
func (t *Task) Update() (err error) {
|
||||
|
||||
s := x.NewSession()
|
||||
func (t *Task) Update(s *xorm.Session) (err error) {
|
||||
|
||||
// Check if the task exists and get the old values
|
||||
ot, err := GetTaskByIDSimple(t.ID)
|
||||
ot, err := GetTaskByIDSimple(s, t.ID)
|
||||
if err != nil {
|
||||
_ = s.Rollback()
|
||||
return
|
||||
}
|
||||
|
||||
// Get the reminders
|
||||
reminders, err := getRemindersForTasks([]int64{t.ID})
|
||||
reminders, err := getRemindersForTasks(s, []int64{t.ID})
|
||||
if err != nil {
|
||||
_ = s.Rollback()
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -881,20 +870,17 @@ func (t *Task) Update() (err error) {
|
|||
|
||||
// Update the assignees
|
||||
if err := ot.updateTaskAssignees(s, t.Assignees); err != nil {
|
||||
_ = s.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// Update the reminders
|
||||
if err := ot.updateReminders(s, t.Reminders); err != nil {
|
||||
_ = s.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// If there is a bucket set, make sure they belong to the same list as the task
|
||||
err = checkBucketAndTaskBelongToSameList(s, &ot, t.BucketID)
|
||||
if err != nil {
|
||||
_ = s.Rollback()
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -923,7 +909,6 @@ func (t *Task) Update() (err error) {
|
|||
if t.BucketID == 0 || (t.ListID != 0 && ot.ListID != t.ListID) {
|
||||
bucket, err = getDefaultBucket(s, t.ListID)
|
||||
if err != nil {
|
||||
_ = s.Rollback()
|
||||
return err
|
||||
}
|
||||
t.BucketID = bucket.ID
|
||||
|
@ -934,7 +919,6 @@ func (t *Task) Update() (err error) {
|
|||
latestTask := &Task{}
|
||||
_, err = s.Where("list_id = ?", t.ListID).OrderBy("id desc").Get(latestTask)
|
||||
if err != nil {
|
||||
_ = s.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -946,7 +930,6 @@ func (t *Task) Update() (err error) {
|
|||
// Only check the bucket limit if the task is being moved between buckets, allow reordering the task within a bucket
|
||||
if t.BucketID != ot.BucketID {
|
||||
if err := checkBucketLimit(s, t, bucket); err != nil {
|
||||
_ = s.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -972,7 +955,6 @@ func (t *Task) Update() (err error) {
|
|||
// Which is why we merge the actual task struct with the one we got from the db
|
||||
// The user struct overrides values in the actual one.
|
||||
if err := mergo.Merge(&ot, t, mergo.WithOverride); err != nil {
|
||||
_ = s.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -1034,7 +1016,6 @@ func (t *Task) Update() (err error) {
|
|||
Update(ot)
|
||||
*t = ot
|
||||
if err != nil {
|
||||
_ = s.Rollback()
|
||||
return err
|
||||
}
|
||||
// Get the task updated timestamp in a new struct - if we'd just try to put it into t which we already have, it
|
||||
|
@ -1042,17 +1023,11 @@ func (t *Task) Update() (err error) {
|
|||
nt := &Task{}
|
||||
_, err = s.ID(t.ID).Get(nt)
|
||||
if err != nil {
|
||||
_ = s.Rollback()
|
||||
return err
|
||||
}
|
||||
t.Updated = nt.Updated
|
||||
|
||||
err = updateListLastUpdated(s, &List{ID: t.ListID})
|
||||
if err != nil {
|
||||
_ = s.Rollback()
|
||||
return err
|
||||
}
|
||||
return s.Commit()
|
||||
return updateListLastUpdated(s, &List{ID: t.ListID})
|
||||
}
|
||||
|
||||
// This helper function updates the reminders, doneAt, start and end dates of the *old* task
|
||||
|
@ -1190,14 +1165,14 @@ func (t *Task) updateReminders(s *xorm.Session, reminders []time.Time) (err erro
|
|||
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
|
||||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /tasks/{id} [delete]
|
||||
func (t *Task) Delete() (err error) {
|
||||
func (t *Task) Delete(s *xorm.Session) (err error) {
|
||||
|
||||
if _, err = x.ID(t.ID).Delete(Task{}); err != nil {
|
||||
if _, err = s.ID(t.ID).Delete(Task{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete assignees
|
||||
if _, err = x.Where("task_id = ?", t.ID).Delete(TaskAssginee{}); err != nil {
|
||||
if _, err = s.Where("task_id = ?", t.ID).Delete(TaskAssginee{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -1219,16 +1194,16 @@ func (t *Task) Delete() (err error) {
|
|||
// @Failure 404 {object} models.Message "Task not found"
|
||||
// @Failure 500 {object} models.Message "Internal error"
|
||||
// @Router /tasks/{ID} [get]
|
||||
func (t *Task) ReadOne() (err error) {
|
||||
func (t *Task) ReadOne(s *xorm.Session) (err error) {
|
||||
|
||||
taskMap := make(map[int64]*Task, 1)
|
||||
taskMap[t.ID] = &Task{}
|
||||
*taskMap[t.ID], err = GetTaskByIDSimple(t.ID)
|
||||
*taskMap[t.ID], err = GetTaskByIDSimple(s, t.ID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = addMoreInfoToTasks(taskMap)
|
||||
err = addMoreInfoToTasks(s, taskMap)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -18,29 +18,30 @@ package models
|
|||
|
||||
import (
|
||||
"code.vikunja.io/web"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// CanDelete checks if the user can delete an task
|
||||
func (t *Task) CanDelete(a web.Auth) (bool, error) {
|
||||
return t.canDoTask(a)
|
||||
func (t *Task) CanDelete(s *xorm.Session, a web.Auth) (bool, error) {
|
||||
return t.canDoTask(s, a)
|
||||
}
|
||||
|
||||
// CanUpdate determines if a user has the right to update a list task
|
||||
func (t *Task) CanUpdate(a web.Auth) (bool, error) {
|
||||
return t.canDoTask(a)
|
||||
func (t *Task) CanUpdate(s *xorm.Session, a web.Auth) (bool, error) {
|
||||
return t.canDoTask(s, a)
|
||||
}
|
||||
|
||||
// CanCreate determines if a user has the right to create a list task
|
||||
func (t *Task) CanCreate(a web.Auth) (bool, error) {
|
||||
func (t *Task) CanCreate(s *xorm.Session, a web.Auth) (bool, error) {
|
||||
// A user can do a task if he has write acces to its list
|
||||
l := &List{ID: t.ListID}
|
||||
return l.CanWrite(s, a)
|
||||
}
|
||||
|
||||
// CanRead determines if a user can read a task
|
||||
func (t *Task) CanRead(a web.Auth) (canRead bool, maxRight int, err error) {
|
||||
func (t *Task) CanRead(s *xorm.Session, a web.Auth) (canRead bool, maxRight int, err error) {
|
||||
// Get the task, error out if it doesn't exist
|
||||
*t, err = GetTaskByIDSimple(t.ID)
|
||||
*t, err = GetTaskByIDSimple(s, t.ID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -51,14 +52,14 @@ func (t *Task) CanRead(a web.Auth) (canRead bool, maxRight int, err error) {
|
|||
}
|
||||
|
||||
// CanWrite checks if a user has write access to a task
|
||||
func (t *Task) CanWrite(a web.Auth) (canWrite bool, err error) {
|
||||
return t.canDoTask(a)
|
||||
func (t *Task) CanWrite(s *xorm.Session, a web.Auth) (canWrite bool, err error) {
|
||||
return t.canDoTask(s, a)
|
||||
}
|
||||
|
||||
// Helper function to check if a user can do stuff on a list task
|
||||
func (t *Task) canDoTask(a web.Auth) (bool, error) {
|
||||
func (t *Task) canDoTask(s *xorm.Session, a web.Auth) (bool, error) {
|
||||
// Get the task
|
||||
ot, err := GetTaskByIDSimple(t.ID)
|
||||
ot, err := GetTaskByIDSimple(s, t.ID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
|
@ -36,12 +36,15 @@ func TestTask_Create(t *testing.T) {
|
|||
|
||||
t.Run("normal", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
task := &Task{
|
||||
Title: "Lorem",
|
||||
Description: "Lorem Ipsum Dolor",
|
||||
ListID: 1,
|
||||
}
|
||||
err := task.Create(usr)
|
||||
err := task.Create(s, usr)
|
||||
assert.NoError(t, err)
|
||||
// Assert getting a uid
|
||||
assert.NotEmpty(t, task.UID)
|
||||
|
@ -50,6 +53,9 @@ func TestTask_Create(t *testing.T) {
|
|||
assert.Equal(t, int64(18), task.Index)
|
||||
// Assert moving it into the default bucket
|
||||
assert.Equal(t, int64(1), task.BucketID)
|
||||
err = s.Commit()
|
||||
assert.NoError(t, err)
|
||||
|
||||
db.AssertExists(t, "tasks", map[string]interface{}{
|
||||
"id": task.ID,
|
||||
"title": "Lorem",
|
||||
|
@ -62,47 +68,59 @@ func TestTask_Create(t *testing.T) {
|
|||
})
|
||||
t.Run("empty title", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
task := &Task{
|
||||
Title: "",
|
||||
Description: "Lorem Ipsum Dolor",
|
||||
ListID: 1,
|
||||
}
|
||||
err := task.Create(usr)
|
||||
err := task.Create(s, usr)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrTaskCannotBeEmpty(err))
|
||||
})
|
||||
t.Run("nonexistant list", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
task := &Task{
|
||||
Title: "Test",
|
||||
Description: "Lorem Ipsum Dolor",
|
||||
ListID: 9999999,
|
||||
}
|
||||
err := task.Create(usr)
|
||||
err := task.Create(s, usr)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrListDoesNotExist(err))
|
||||
})
|
||||
t.Run("noneixtant user", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
nUser := &user.User{ID: 99999999}
|
||||
task := &Task{
|
||||
Title: "Test",
|
||||
Description: "Lorem Ipsum Dolor",
|
||||
ListID: 1,
|
||||
}
|
||||
err := task.Create(nUser)
|
||||
err := task.Create(s, nUser)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, user.IsErrUserDoesNotExist(err))
|
||||
})
|
||||
t.Run("full bucket", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
task := &Task{
|
||||
Title: "Lorem",
|
||||
Description: "Lorem Ipsum Dolor",
|
||||
ListID: 1,
|
||||
BucketID: 2, // Bucket 2 already has 3 tasks and a limit of 3
|
||||
}
|
||||
err := task.Create(usr)
|
||||
err := task.Create(s, usr)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrBucketLimitExceeded(err))
|
||||
})
|
||||
|
@ -111,14 +129,20 @@ func TestTask_Create(t *testing.T) {
|
|||
func TestTask_Update(t *testing.T) {
|
||||
t.Run("normal", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
task := &Task{
|
||||
ID: 1,
|
||||
Title: "test10000",
|
||||
Description: "Lorem Ipsum Dolor",
|
||||
ListID: 1,
|
||||
}
|
||||
err := task.Update()
|
||||
err := task.Update(s)
|
||||
assert.NoError(t, err)
|
||||
err = s.Commit()
|
||||
assert.NoError(t, err)
|
||||
|
||||
db.AssertExists(t, "tasks", map[string]interface{}{
|
||||
"id": 1,
|
||||
"title": "test10000",
|
||||
|
@ -128,18 +152,24 @@ func TestTask_Update(t *testing.T) {
|
|||
})
|
||||
t.Run("nonexistant task", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
task := &Task{
|
||||
ID: 9999999,
|
||||
Title: "test10000",
|
||||
Description: "Lorem Ipsum Dolor",
|
||||
ListID: 1,
|
||||
}
|
||||
err := task.Update()
|
||||
err := task.Update(s)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrTaskDoesNotExist(err))
|
||||
})
|
||||
t.Run("full bucket", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
task := &Task{
|
||||
ID: 1,
|
||||
Title: "test10000",
|
||||
|
@ -147,12 +177,15 @@ func TestTask_Update(t *testing.T) {
|
|||
ListID: 1,
|
||||
BucketID: 2, // Bucket 2 already has 3 tasks and a limit of 3
|
||||
}
|
||||
err := task.Update()
|
||||
err := task.Update(s)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrBucketLimitExceeded(err))
|
||||
})
|
||||
t.Run("full bucket but not changing the bucket", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
task := &Task{
|
||||
ID: 4,
|
||||
Title: "test10000",
|
||||
|
@ -161,7 +194,7 @@ func TestTask_Update(t *testing.T) {
|
|||
ListID: 1,
|
||||
BucketID: 2, // Bucket 2 already has 3 tasks and a limit of 3
|
||||
}
|
||||
err := task.Update()
|
||||
err := task.Update(s)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
@ -169,11 +202,17 @@ func TestTask_Update(t *testing.T) {
|
|||
func TestTask_Delete(t *testing.T) {
|
||||
t.Run("normal", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
task := &Task{
|
||||
ID: 1,
|
||||
}
|
||||
err := task.Delete()
|
||||
err := task.Delete(s)
|
||||
assert.NoError(t, err)
|
||||
err = s.Commit()
|
||||
assert.NoError(t, err)
|
||||
|
||||
db.AssertMissing(t, "tasks", map[string]interface{}{
|
||||
"id": 1,
|
||||
})
|
||||
|
@ -183,6 +222,9 @@ func TestTask_Delete(t *testing.T) {
|
|||
func TestUpdateDone(t *testing.T) {
|
||||
t.Run("marking a task as done", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
oldTask := &Task{Done: false}
|
||||
newTask := &Task{Done: true}
|
||||
updateDone(oldTask, newTask)
|
||||
|
@ -190,6 +232,9 @@ func TestUpdateDone(t *testing.T) {
|
|||
})
|
||||
t.Run("unmarking a task as done", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
oldTask := &Task{Done: true}
|
||||
newTask := &Task{Done: false}
|
||||
updateDone(oldTask, newTask)
|
||||
|
@ -397,15 +442,21 @@ func TestUpdateDone(t *testing.T) {
|
|||
func TestTask_ReadOne(t *testing.T) {
|
||||
t.Run("default", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
task := &Task{ID: 1}
|
||||
err := task.ReadOne()
|
||||
err := task.ReadOne(s)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "task #1", task.Title)
|
||||
})
|
||||
t.Run("nonexisting", func(t *testing.T) {
|
||||
db.LoadAndAssertFixtures(t)
|
||||
s := x.NewSession()
|
||||
defer s.Close()
|
||||
|
||||
task := &Task{ID: 99999}
|
||||
err := task.ReadOne()
|
||||
err := task.ReadOne(s)
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrTaskDoesNotExist(err))
|
||||
})
|
||||
|
|
|
@ -111,7 +111,7 @@ func InsertFromStructure(str []*models.NamespaceWithLists, user *user.User) (err
|
|||
}
|
||||
|
||||
t.ListID = l.ID
|
||||
err = t.Create(user)
|
||||
err = t.Create(s, user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ func InsertFromStructure(str []*models.NamespaceWithLists, user *user.User) (err
|
|||
// First create the related tasks if they do not exist
|
||||
if rt.ID == 0 {
|
||||
rt.ListID = t.ListID
|
||||
err = rt.Create(user)
|
||||
err = rt.Create(s, user)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ func (vcls *VikunjaCaldavListStorage) GetResourcesByList(rpaths []string) ([]dat
|
|||
|
||||
// GetTasksByUIDs...
|
||||
// Parse these into ressources...
|
||||
tasks, err := models.GetTasksByUIDs(uids)
|
||||
tasks, err := models.GetTasksByUIDs(s, uids)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ func (vcls *VikunjaCaldavListStorage) GetResource(rpath string) (*data.Resource,
|
|||
if vcls.task != nil {
|
||||
// save and override the updated unix date to not break any later etag checks
|
||||
updated := vcls.task.Updated
|
||||
task, err := models.GetTaskSimple(&models.Task{ID: vcls.task.ID, UID: vcls.task.UID})
|
||||
task, err := models.GetTaskSimple(s, &models.Task{ID: vcls.task.ID, UID: vcls.task.UID})
|
||||
if err != nil {
|
||||
if models.IsErrTaskDoesNotExist(err) {
|
||||
return nil, false, errs.ResourceNotFoundError
|
||||
|
@ -238,7 +238,7 @@ func (vcls *VikunjaCaldavListStorage) CreateResource(rpath, content string) (*da
|
|||
vTask.ListID = vcls.list.ID
|
||||
|
||||
// Check the rights
|
||||
canCreate, err := vTask.CanCreate(vcls.user)
|
||||
canCreate, err := vTask.CanCreate(s, vcls.user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ func (vcls *VikunjaCaldavListStorage) CreateResource(rpath, content string) (*da
|
|||
}
|
||||
|
||||
// Create the task
|
||||
err = vTask.Create(vcls.user)
|
||||
err = vTask.Create(s, vcls.user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ func (vcls *VikunjaCaldavListStorage) UpdateResource(rpath, content string) (*da
|
|||
vTask.ID = vcls.task.ID
|
||||
|
||||
// Check the rights
|
||||
canUpdate, err := vTask.CanUpdate(vcls.user)
|
||||
canUpdate, err := vTask.CanUpdate(s, vcls.user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ func (vcls *VikunjaCaldavListStorage) UpdateResource(rpath, content string) (*da
|
|||
}
|
||||
|
||||
// Update the task
|
||||
err = vTask.Update()
|
||||
err = vTask.Update(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ func (vcls *VikunjaCaldavListStorage) UpdateResource(rpath, content string) (*da
|
|||
func (vcls *VikunjaCaldavListStorage) DeleteResource(rpath string) error {
|
||||
if vcls.task != nil {
|
||||
// Check the rights
|
||||
canDelete, err := vcls.task.CanDelete(vcls.user)
|
||||
canDelete, err := vcls.task.CanDelete(s, vcls.user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ func (vcls *VikunjaCaldavListStorage) DeleteResource(rpath string) error {
|
|||
}
|
||||
|
||||
// Delete it
|
||||
return vcls.task.Delete()
|
||||
return vcls.task.Delete(s)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
Loading…
Reference in New Issue