WIP: Add an 'updated_at' field to the EditIssueOption struct

This field adds the possibility to set the update date when modifying
an issue through the API.

A 'NoAutoDate' in-memory field is added in the Issue struct.
If the update_at field is set, NoAutoDate is set to true and the
Issue's UpdatedUnix field is filled.

That information is passed down to the functions that actually updates
the database, which have been modified to not auto update dates if
requested.

A guard is added to the 'EditIssue' API call, to checks that the
udpate_at date is between the issue's creation date and the current
date (to avoid 'malicious' changes). It also limits the new feature
to project's owners and admins.
This commit is contained in:
fluzz 2023-05-30 18:42:58 +02:00
parent 70fffdc61d
commit c524d33402
9 changed files with 104 additions and 18 deletions

View file

@ -27,7 +27,12 @@ import (
// UpdateIssueCols updates cols of issue
func UpdateIssueCols(ctx context.Context, issue *Issue, cols ...string) error {
if _, err := db.GetEngine(ctx).ID(issue.ID).Cols(cols...).Update(issue); err != nil {
sess := db.GetEngine(ctx).ID(issue.ID)
if issue.NoAutoTime {
cols = append(cols, []string{"updated_unix"}...)
sess.NoAutoTime()
}
if _, err := sess.Cols(cols...).Update(issue); err != nil {
return err
}
return nil
@ -71,7 +76,11 @@ func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.Use
}
if issue.IsClosed {
issue.ClosedUnix = timeutil.TimeStampNow()
if issue.NoAutoTime {
issue.ClosedUnix = issue.UpdatedUnix
} else {
issue.ClosedUnix = timeutil.TimeStampNow()
}
} else {
issue.ClosedUnix = 0
}
@ -92,8 +101,14 @@ func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.Use
// Update issue count of milestone
if issue.MilestoneID > 0 {
if err := UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil {
return nil, err
if issue.NoAutoTime {
if err := UpdateMilestoneCountersWithDate(ctx, issue.MilestoneID, issue.UpdatedUnix); err != nil {
return nil, err
}
} else {
if err := UpdateMilestoneCounters(ctx, issue.MilestoneID); err != nil {
return nil, err
}
}
}
@ -449,10 +464,13 @@ func UpdateIssueByAPI(issue *Issue, doer *user_model.User) (statusChangeComment
return nil, false, err
}
if _, err := db.GetEngine(ctx).ID(issue.ID).Cols(
"name", "content", "milestone_id", "priority",
"deadline_unix", "updated_unix", "is_locked").
Update(issue); err != nil {
sess := db.GetEngine(ctx).ID(issue.ID)
cols := []string{"name", "content", "milestone_id", "priority", "deadline_unix", "is_locked"}
if issue.NoAutoTime {
cols = append(cols, "updated_unix")
sess.NoAutoTime()
}
if _, err := sess.Cols(cols...).Update(issue); err != nil {
return nil, false, err
}
@ -498,7 +516,7 @@ func UpdateIssueDeadline(issue *Issue, deadlineUnix timeutil.TimeStamp, doer *us
defer committer.Close()
// Update the deadline
if err = UpdateIssueCols(ctx, &Issue{ID: issue.ID, DeadlineUnix: deadlineUnix}, "deadline_unix"); err != nil {
if err = UpdateIssueCols(ctx, &Issue{ID: issue.ID, DeadlineUnix: deadlineUnix, NoAutoTime: issue.NoAutoTime, UpdatedUnix: issue.UpdatedUnix}, "deadline_unix"); err != nil {
return err
}