From f061caa6555e0c9e922ee1e73dd2e4337360e9fe Mon Sep 17 00:00:00 2001 From: fluzz Date: Tue, 30 May 2023 18:53:56 +0200 Subject: [PATCH] Add a SetIssueUpdateDate() function in services/issue.go That function is used by some API calls to set the NoAutoDate and UpdatedUnix fields of an Issue if an updated_at date is provided. --- routers/api/v1/repo/issue.go | 29 ++++----------------------- services/issue/issue.go | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index bd756a3f11..9001f13af2 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -774,31 +774,10 @@ func EditIssue(ctx *context.APIContext) { return } - // In order to be set a specific update time, the DB will be updated - // with NoAutoTime. The 'noAutoTime' bool will be propagated down to the - // DB update calls to apply autoupdate or not. - issue.NoAutoTime = false - if form.Updated != nil { - // Check if the poster is allowed to set an update date - perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, ctx.Doer) - if err != nil { - ctx.Status(http.StatusForbidden) - return - } - if !perm.IsAdmin() && !perm.IsOwner() { - ctx.Error(http.StatusUnauthorized, "EditIssue", "user needs to have admin or owner right") - return - } - - // A simple guard against potential inconsistent calls - updatedUnix := timeutil.TimeStamp(form.Updated.Unix()) - if updatedUnix < issue.CreatedUnix || updatedUnix > timeutil.TimeStampNow() { - ctx.Error(http.StatusForbidden, "EditIssue", "unallowed update date") - return - } - - issue.UpdatedUnix = updatedUnix - issue.NoAutoTime = true + err = issue_service.SetIssueUpdateDate(ctx, issue, form.Updated, ctx.Doer) + if err != nil { + ctx.Error(http.StatusForbidden, "SetIssueUpdateDate", err) + return } oldTitle := issue.Title diff --git a/services/issue/issue.go b/services/issue/issue.go index 35409589ef..2c1350e7fd 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -6,6 +6,7 @@ package issue import ( "context" "fmt" + "time" activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" @@ -18,6 +19,7 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/storage" + "code.gitea.io/gitea/modules/timeutil" ) // NewIssue creates new issue with labels for repository. @@ -304,3 +306,40 @@ func deleteIssue(ctx context.Context, issue *issues_model.Issue) error { return committer.Commit() } + +// Set the UpdatedUnix date and the NoAutoTime field of an Issue if a non +// nil 'updated' time is provided +// +// In order to set a specific update time, the DB will be updated with +// NoAutoTime(). A 'NoAutoTime' boolean field in the Issue struct is used to +// propagate down to the DB update calls the will to apply autoupdate or not. +func SetIssueUpdateDate(ctx context.Context, issue *issues_model.Issue, updated *time.Time, doer *user_model.User) error { + issue.NoAutoTime = false + if updated == nil { + return nil + } + + if err := issue.LoadRepo(ctx); err != nil { + return err + } + + // Check if the poster is allowed to set an update date + perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + if err != nil { + return err + } + if !perm.IsAdmin() && !perm.IsOwner() { + return fmt.Errorf("user needs to have admin or owner right") + } + + // A simple guard against potential inconsistent calls + updatedUnix := timeutil.TimeStamp(updated.Unix()) + if updatedUnix < issue.CreatedUnix || updatedUnix > timeutil.TimeStampNow() { + return fmt.Errorf("unallowed update date") + } + + issue.UpdatedUnix = updatedUnix + issue.NoAutoTime = true + + return nil +}