From 3dbd2d942bc9a8609b242a64a9416fb82b564ffe Mon Sep 17 00:00:00 2001 From: Jason Song Date: Fri, 6 Jan 2023 19:49:14 +0800 Subject: [PATCH 1/6] Remove old HookEventType (#22358) Supplement to #22256. --- models/webhook/hooktask.go | 63 -------------------------------- routers/api/v1/utils/hook.go | 70 ++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 98 deletions(-) diff --git a/models/webhook/hooktask.go b/models/webhook/hooktask.go index ccce1447bcf8f..8688fe5de3698 100644 --- a/models/webhook/hooktask.go +++ b/models/webhook/hooktask.go @@ -24,69 +24,6 @@ import ( // \___|_ / \____/ \____/|__|_ \ |____| (____ /____ >__|_ \ // \/ \/ \/ \/ \/ -// HookEventType is the type of an hook event -type HookEventType string - -// Types of hook events -const ( - HookEventCreate HookEventType = "create" - HookEventDelete HookEventType = "delete" - HookEventFork HookEventType = "fork" - HookEventPush HookEventType = "push" - HookEventIssues HookEventType = "issues" - HookEventIssueAssign HookEventType = "issue_assign" - HookEventIssueLabel HookEventType = "issue_label" - HookEventIssueMilestone HookEventType = "issue_milestone" - HookEventIssueComment HookEventType = "issue_comment" - HookEventPullRequest HookEventType = "pull_request" - HookEventPullRequestAssign HookEventType = "pull_request_assign" - HookEventPullRequestLabel HookEventType = "pull_request_label" - HookEventPullRequestMilestone HookEventType = "pull_request_milestone" - HookEventPullRequestComment HookEventType = "pull_request_comment" - HookEventPullRequestReviewApproved HookEventType = "pull_request_review_approved" - HookEventPullRequestReviewRejected HookEventType = "pull_request_review_rejected" - HookEventPullRequestReviewComment HookEventType = "pull_request_review_comment" - HookEventPullRequestSync HookEventType = "pull_request_sync" - HookEventWiki HookEventType = "wiki" - HookEventRepository HookEventType = "repository" - HookEventRelease HookEventType = "release" - HookEventPackage HookEventType = "package" -) - -// Event returns the HookEventType as an event string -func (h HookEventType) Event() string { - switch h { - case HookEventCreate: - return "create" - case HookEventDelete: - return "delete" - case HookEventFork: - return "fork" - case HookEventPush: - return "push" - case HookEventIssues, HookEventIssueAssign, HookEventIssueLabel, HookEventIssueMilestone: - return "issues" - case HookEventPullRequest, HookEventPullRequestAssign, HookEventPullRequestLabel, HookEventPullRequestMilestone, - HookEventPullRequestSync: - return "pull_request" - case HookEventIssueComment, HookEventPullRequestComment: - return "issue_comment" - case HookEventPullRequestReviewApproved: - return "pull_request_approved" - case HookEventPullRequestReviewRejected: - return "pull_request_rejected" - case HookEventPullRequestReviewComment: - return "pull_request_comment" - case HookEventWiki: - return "wiki" - case HookEventRepository: - return "repository" - case HookEventRelease: - return "release" - } - return "" -} - // HookRequest represents hook task request information. type HookRequest struct { URL string `json:"url"` diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go index fc202f51cfea3..065b761adb35b 100644 --- a/routers/api/v1/utils/hook.go +++ b/routers/api/v1/utils/hook.go @@ -107,11 +107,11 @@ func toAPIHook(ctx *context.APIContext, repoLink string, hook *webhook.Webhook) } func issuesHook(events []string, event string) bool { - return util.IsStringInSlice(event, events, true) || util.IsStringInSlice(string(webhook.HookEventIssues), events, true) + return util.IsStringInSlice(event, events, true) || util.IsStringInSlice(string(webhook_module.HookEventIssues), events, true) } func pullHook(events []string, event string) bool { - return util.IsStringInSlice(event, events, true) || util.IsStringInSlice(string(webhook.HookEventPullRequest), events, true) + return util.IsStringInSlice(event, events, true) || util.IsStringInSlice(string(webhook_module.HookEventPullRequest), events, true) } // addHook add the hook specified by `form`, `orgID` and `repoID`. If there is @@ -130,25 +130,25 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID HookEvent: &webhook_module.HookEvent{ ChooseEvents: true, HookEvents: webhook_module.HookEvents{ - Create: util.IsStringInSlice(string(webhook.HookEventCreate), form.Events, true), - Delete: util.IsStringInSlice(string(webhook.HookEventDelete), form.Events, true), - Fork: util.IsStringInSlice(string(webhook.HookEventFork), form.Events, true), + Create: util.IsStringInSlice(string(webhook_module.HookEventCreate), form.Events, true), + Delete: util.IsStringInSlice(string(webhook_module.HookEventDelete), form.Events, true), + Fork: util.IsStringInSlice(string(webhook_module.HookEventFork), form.Events, true), Issues: issuesHook(form.Events, "issues_only"), - IssueAssign: issuesHook(form.Events, string(webhook.HookEventIssueAssign)), - IssueLabel: issuesHook(form.Events, string(webhook.HookEventIssueLabel)), - IssueMilestone: issuesHook(form.Events, string(webhook.HookEventIssueMilestone)), - IssueComment: issuesHook(form.Events, string(webhook.HookEventIssueComment)), - Push: util.IsStringInSlice(string(webhook.HookEventPush), form.Events, true), + IssueAssign: issuesHook(form.Events, string(webhook_module.HookEventIssueAssign)), + IssueLabel: issuesHook(form.Events, string(webhook_module.HookEventIssueLabel)), + IssueMilestone: issuesHook(form.Events, string(webhook_module.HookEventIssueMilestone)), + IssueComment: issuesHook(form.Events, string(webhook_module.HookEventIssueComment)), + Push: util.IsStringInSlice(string(webhook_module.HookEventPush), form.Events, true), PullRequest: pullHook(form.Events, "pull_request_only"), - PullRequestAssign: pullHook(form.Events, string(webhook.HookEventPullRequestAssign)), - PullRequestLabel: pullHook(form.Events, string(webhook.HookEventPullRequestLabel)), - PullRequestMilestone: pullHook(form.Events, string(webhook.HookEventPullRequestMilestone)), - PullRequestComment: pullHook(form.Events, string(webhook.HookEventPullRequestComment)), + PullRequestAssign: pullHook(form.Events, string(webhook_module.HookEventPullRequestAssign)), + PullRequestLabel: pullHook(form.Events, string(webhook_module.HookEventPullRequestLabel)), + PullRequestMilestone: pullHook(form.Events, string(webhook_module.HookEventPullRequestMilestone)), + PullRequestComment: pullHook(form.Events, string(webhook_module.HookEventPullRequestComment)), PullRequestReview: pullHook(form.Events, "pull_request_review"), - PullRequestSync: pullHook(form.Events, string(webhook.HookEventPullRequestSync)), - Wiki: util.IsStringInSlice(string(webhook.HookEventWiki), form.Events, true), - Repository: util.IsStringInSlice(string(webhook.HookEventRepository), form.Events, true), - Release: util.IsStringInSlice(string(webhook.HookEventRelease), form.Events, true), + PullRequestSync: pullHook(form.Events, string(webhook_module.HookEventPullRequestSync)), + Wiki: util.IsStringInSlice(string(webhook_module.HookEventWiki), form.Events, true), + Repository: util.IsStringInSlice(string(webhook_module.HookEventRepository), form.Events, true), + Release: util.IsStringInSlice(string(webhook_module.HookEventRelease), form.Events, true), }, BranchFilter: form.BranchFilter, }, @@ -277,14 +277,14 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh w.PushOnly = false w.SendEverything = false w.ChooseEvents = true - w.Create = util.IsStringInSlice(string(webhook.HookEventCreate), form.Events, true) - w.Push = util.IsStringInSlice(string(webhook.HookEventPush), form.Events, true) - w.Create = util.IsStringInSlice(string(webhook.HookEventCreate), form.Events, true) - w.Delete = util.IsStringInSlice(string(webhook.HookEventDelete), form.Events, true) - w.Fork = util.IsStringInSlice(string(webhook.HookEventFork), form.Events, true) - w.Repository = util.IsStringInSlice(string(webhook.HookEventRepository), form.Events, true) - w.Wiki = util.IsStringInSlice(string(webhook.HookEventWiki), form.Events, true) - w.Release = util.IsStringInSlice(string(webhook.HookEventRelease), form.Events, true) + w.Create = util.IsStringInSlice(string(webhook_module.HookEventCreate), form.Events, true) + w.Push = util.IsStringInSlice(string(webhook_module.HookEventPush), form.Events, true) + w.Create = util.IsStringInSlice(string(webhook_module.HookEventCreate), form.Events, true) + w.Delete = util.IsStringInSlice(string(webhook_module.HookEventDelete), form.Events, true) + w.Fork = util.IsStringInSlice(string(webhook_module.HookEventFork), form.Events, true) + w.Repository = util.IsStringInSlice(string(webhook_module.HookEventRepository), form.Events, true) + w.Wiki = util.IsStringInSlice(string(webhook_module.HookEventWiki), form.Events, true) + w.Release = util.IsStringInSlice(string(webhook_module.HookEventRelease), form.Events, true) w.BranchFilter = form.BranchFilter err := w.SetHeaderAuthorization(form.AuthorizationHeader) @@ -295,19 +295,19 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh // Issues w.Issues = issuesHook(form.Events, "issues_only") - w.IssueAssign = issuesHook(form.Events, string(webhook.HookEventIssueAssign)) - w.IssueLabel = issuesHook(form.Events, string(webhook.HookEventIssueLabel)) - w.IssueMilestone = issuesHook(form.Events, string(webhook.HookEventIssueMilestone)) - w.IssueComment = issuesHook(form.Events, string(webhook.HookEventIssueComment)) + w.IssueAssign = issuesHook(form.Events, string(webhook_module.HookEventIssueAssign)) + w.IssueLabel = issuesHook(form.Events, string(webhook_module.HookEventIssueLabel)) + w.IssueMilestone = issuesHook(form.Events, string(webhook_module.HookEventIssueMilestone)) + w.IssueComment = issuesHook(form.Events, string(webhook_module.HookEventIssueComment)) // Pull requests w.PullRequest = pullHook(form.Events, "pull_request_only") - w.PullRequestAssign = pullHook(form.Events, string(webhook.HookEventPullRequestAssign)) - w.PullRequestLabel = pullHook(form.Events, string(webhook.HookEventPullRequestLabel)) - w.PullRequestMilestone = pullHook(form.Events, string(webhook.HookEventPullRequestMilestone)) - w.PullRequestComment = pullHook(form.Events, string(webhook.HookEventPullRequestComment)) + w.PullRequestAssign = pullHook(form.Events, string(webhook_module.HookEventPullRequestAssign)) + w.PullRequestLabel = pullHook(form.Events, string(webhook_module.HookEventPullRequestLabel)) + w.PullRequestMilestone = pullHook(form.Events, string(webhook_module.HookEventPullRequestMilestone)) + w.PullRequestComment = pullHook(form.Events, string(webhook_module.HookEventPullRequestComment)) w.PullRequestReview = pullHook(form.Events, "pull_request_review") - w.PullRequestSync = pullHook(form.Events, string(webhook.HookEventPullRequestSync)) + w.PullRequestSync = pullHook(form.Events, string(webhook_module.HookEventPullRequestSync)) if err := w.UpdateEvent(); err != nil { ctx.Error(http.StatusInternalServerError, "UpdateEvent", err) From d42b52fcfa4b175810e8da6bc1a8822838ff6456 Mon Sep 17 00:00:00 2001 From: crystal <71373843+CrystalCommunication@users.noreply.github.com> Date: Fri, 6 Jan 2023 05:44:02 -0700 Subject: [PATCH 2/6] make /{username}.png redirect to user/org avatar (#22356) fix #22355 Co-authored-by: Lunny Xiao --- routers/web/web.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/web/web.go b/routers/web/web.go index 31b3eb9baadac..997185974c201 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -634,7 +634,7 @@ func RegisterRoutes(m *web.Route) { http.ServeFile(ctx.Resp, ctx.Req, path.Join(setting.StaticRootPath, "public/img/favicon.png")) }) m.Group("/{username}", func() { - m.Get(".png", func(ctx *context.Context) { ctx.Error(http.StatusNotFound) }) + m.Get(".png", user.AvatarByUserName) m.Get(".keys", user.ShowSSHKeys) m.Get(".gpg", user.ShowGPGKeys) m.Get(".rss", feedEnabled, feed.ShowUserFeedRSS) From 6135359a049b9d9ab43c5901d4cdadfc45094aa1 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Sun, 8 Jan 2023 09:34:58 +0800 Subject: [PATCH 3/6] Always reuse transaction (#22362) --- models/activities/notification.go | 2 +- models/db/context.go | 71 +++++++++++++++++------------- models/db/context_test.go | 56 ++++++++++++++++++++++- models/db/error.go | 3 -- models/issues/issue.go | 2 +- models/project/project.go | 2 +- models/repo/collaboration.go | 2 +- models/repo_transfer.go | 2 +- modules/notification/ui/ui.go | 2 +- modules/repository/collaborator.go | 2 +- services/issue/comments.go | 2 +- 11 files changed, 104 insertions(+), 42 deletions(-) diff --git a/models/activities/notification.go b/models/activities/notification.go index d20a53a41d860..321d543c736ae 100644 --- a/models/activities/notification.go +++ b/models/activities/notification.go @@ -141,7 +141,7 @@ func CountNotifications(ctx context.Context, opts *FindNotificationOptions) (int // CreateRepoTransferNotification creates notification for the user a repository was transferred to func CreateRepoTransferNotification(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) error { - return db.AutoTx(ctx, func(ctx context.Context) error { + return db.WithTx(ctx, func(ctx context.Context) error { var notify []*Notification if newOwner.IsOrganization() { diff --git a/models/db/context.go b/models/db/context.go index 3db8b16528da4..455f3d1c5de74 100644 --- a/models/db/context.go +++ b/models/db/context.go @@ -71,6 +71,14 @@ type Engined interface { // GetEngine will get a db Engine from this context or return an Engine restricted to this context func GetEngine(ctx context.Context) Engine { + if e := getEngine(ctx); e != nil { + return e + } + return x.Context(ctx) +} + +// getEngine will get a db Engine from this context or return nil +func getEngine(ctx context.Context) Engine { if engined, ok := ctx.(Engined); ok { return engined.Engine() } @@ -78,7 +86,7 @@ func GetEngine(ctx context.Context) Engine { if enginedInterface != nil { return enginedInterface.(Engined).Engine() } - return x.Context(ctx) + return nil } // Committer represents an interface to Commit or Close the Context @@ -87,10 +95,22 @@ type Committer interface { Close() error } -// TxContext represents a transaction Context +// halfCommitter is a wrapper of Committer. +// It can be closed early, but can't be committed early, it is useful for reusing a transaction. +type halfCommitter struct { + Committer +} + +func (*halfCommitter) Commit() error { + // do nothing + return nil +} + +// TxContext represents a transaction Context, +// it will reuse the existing transaction in the parent context or create a new one. func TxContext(parentCtx context.Context) (*Context, Committer, error) { - if InTransaction(parentCtx) { - return nil, nil, ErrAlreadyInTransaction + if sess, ok := inTransaction(parentCtx); ok { + return newContext(parentCtx, sess, true), &halfCommitter{Committer: sess}, nil } sess := x.NewSession() @@ -102,20 +122,11 @@ func TxContext(parentCtx context.Context) (*Context, Committer, error) { return newContext(DefaultContext, sess, true), sess, nil } -// WithTx represents executing database operations on a transaction -// This function will always open a new transaction, if a transaction exist in parentCtx return an error. -func WithTx(parentCtx context.Context, f func(ctx context.Context) error) error { - if InTransaction(parentCtx) { - return ErrAlreadyInTransaction - } - return txWithNoCheck(parentCtx, f) -} - -// AutoTx represents executing database operations on a transaction, if the transaction exist, +// WithTx represents executing database operations on a transaction, if the transaction exist, // this function will reuse it otherwise will create a new one and close it when finished. -func AutoTx(parentCtx context.Context, f func(ctx context.Context) error) error { - if InTransaction(parentCtx) { - return f(newContext(parentCtx, GetEngine(parentCtx), true)) +func WithTx(parentCtx context.Context, f func(ctx context.Context) error) error { + if sess, ok := inTransaction(parentCtx); ok { + return f(newContext(parentCtx, sess, true)) } return txWithNoCheck(parentCtx, f) } @@ -202,25 +213,25 @@ func EstimateCount(ctx context.Context, bean interface{}) (int64, error) { // InTransaction returns true if the engine is in a transaction otherwise return false func InTransaction(ctx context.Context) bool { - var e Engine - if engined, ok := ctx.(Engined); ok { - e = engined.Engine() - } else { - enginedInterface := ctx.Value(enginedContextKey) - if enginedInterface != nil { - e = enginedInterface.(Engined).Engine() - } - } + _, ok := inTransaction(ctx) + return ok +} + +func inTransaction(ctx context.Context) (*xorm.Session, bool) { + e := getEngine(ctx) if e == nil { - return false + return nil, false } switch t := e.(type) { case *xorm.Engine: - return false + return nil, false case *xorm.Session: - return t.IsInTx() + if t.IsInTx() { + return t, true + } + return nil, false default: - return false + return nil, false } } diff --git a/models/db/context_test.go b/models/db/context_test.go index e7518a50d8d29..95a01d4a26eb2 100644 --- a/models/db/context_test.go +++ b/models/db/context_test.go @@ -25,8 +25,62 @@ func TestInTransaction(t *testing.T) { assert.NoError(t, err) defer committer.Close() assert.True(t, db.InTransaction(ctx)) - assert.Error(t, db.WithTx(ctx, func(ctx context.Context) error { + assert.NoError(t, db.WithTx(ctx, func(ctx context.Context) error { assert.True(t, db.InTransaction(ctx)) return nil })) } + +func TestTxContext(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + { // create new transaction + ctx, committer, err := db.TxContext(db.DefaultContext) + assert.NoError(t, err) + assert.True(t, db.InTransaction(ctx)) + assert.NoError(t, committer.Commit()) + } + + { // reuse the transaction created by TxContext and commit it + ctx, committer, err := db.TxContext(db.DefaultContext) + engine := db.GetEngine(ctx) + assert.NoError(t, err) + assert.True(t, db.InTransaction(ctx)) + { + ctx, committer, err := db.TxContext(ctx) + assert.NoError(t, err) + assert.True(t, db.InTransaction(ctx)) + assert.Equal(t, engine, db.GetEngine(ctx)) + assert.NoError(t, committer.Commit()) + } + assert.NoError(t, committer.Commit()) + } + + { // reuse the transaction created by TxContext and close it + ctx, committer, err := db.TxContext(db.DefaultContext) + engine := db.GetEngine(ctx) + assert.NoError(t, err) + assert.True(t, db.InTransaction(ctx)) + { + ctx, committer, err := db.TxContext(ctx) + assert.NoError(t, err) + assert.True(t, db.InTransaction(ctx)) + assert.Equal(t, engine, db.GetEngine(ctx)) + assert.NoError(t, committer.Close()) + } + assert.NoError(t, committer.Close()) + } + + { // reuse the transaction created by WithTx + assert.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error { + assert.True(t, db.InTransaction(ctx)) + { + ctx, committer, err := db.TxContext(ctx) + assert.NoError(t, err) + assert.True(t, db.InTransaction(ctx)) + assert.NoError(t, committer.Commit()) + } + return nil + })) + } +} diff --git a/models/db/error.go b/models/db/error.go index 5860cb4a071d1..edc8e80a9c605 100644 --- a/models/db/error.go +++ b/models/db/error.go @@ -4,14 +4,11 @@ package db import ( - "errors" "fmt" "code.gitea.io/gitea/modules/util" ) -var ErrAlreadyInTransaction = errors.New("database connection has already been in a transaction") - // ErrCancelled represents an error due to context cancellation type ErrCancelled struct { Message string diff --git a/models/issues/issue.go b/models/issues/issue.go index f45e635c0ecea..417d6a1557892 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -2365,7 +2365,7 @@ func CountOrphanedIssues(ctx context.Context) (int64, error) { // DeleteOrphanedIssues delete issues without a repo func DeleteOrphanedIssues(ctx context.Context) error { var attachmentPaths []string - err := db.AutoTx(ctx, func(ctx context.Context) error { + err := db.WithTx(ctx, func(ctx context.Context) error { var ids []int64 if err := db.GetEngine(ctx).Table("issue").Distinct("issue.repo_id"). diff --git a/models/project/project.go b/models/project/project.go index 0a07cfe22ad1b..f432d0bc4c5bd 100644 --- a/models/project/project.go +++ b/models/project/project.go @@ -300,7 +300,7 @@ func changeProjectStatus(ctx context.Context, p *Project, isClosed bool) error { // DeleteProjectByID deletes a project from a repository. if it's not in a database // transaction, it will start a new database transaction func DeleteProjectByID(ctx context.Context, id int64) error { - return db.AutoTx(ctx, func(ctx context.Context) error { + return db.WithTx(ctx, func(ctx context.Context) error { p, err := GetProjectByID(ctx, id) if err != nil { if IsErrProjectNotExist(err) { diff --git a/models/repo/collaboration.go b/models/repo/collaboration.go index 29bcab70f36a3..7989e5bdf9c5d 100644 --- a/models/repo/collaboration.go +++ b/models/repo/collaboration.go @@ -105,7 +105,7 @@ func ChangeCollaborationAccessMode(ctx context.Context, repo *Repository, uid in return nil } - return db.AutoTx(ctx, func(ctx context.Context) error { + return db.WithTx(ctx, func(ctx context.Context) error { e := db.GetEngine(ctx) collaboration := &Collaboration{ diff --git a/models/repo_transfer.go b/models/repo_transfer.go index 19e6c0662727f..27a77f9b8cc9f 100644 --- a/models/repo_transfer.go +++ b/models/repo_transfer.go @@ -155,7 +155,7 @@ func TestRepositoryReadyForTransfer(status repo_model.RepositoryStatus) error { // CreatePendingRepositoryTransfer transfer a repo from one owner to a new one. // it marks the repository transfer as "pending" func CreatePendingRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.User, repoID int64, teams []*organization.Team) error { - return db.AutoTx(ctx, func(ctx context.Context) error { + return db.WithTx(ctx, func(ctx context.Context) error { repo, err := repo_model.GetRepositoryByID(ctx, repoID) if err != nil { return err diff --git a/modules/notification/ui/ui.go b/modules/notification/ui/ui.go index 63a3ffd199989..bc66c3d5a3db4 100644 --- a/modules/notification/ui/ui.go +++ b/modules/notification/ui/ui.go @@ -243,7 +243,7 @@ func (ns *notificationService) NotifyPullReviewRequest(ctx context.Context, doer } func (ns *notificationService) NotifyRepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) { - err := db.AutoTx(ctx, func(ctx context.Context) error { + err := db.WithTx(ctx, func(ctx context.Context) error { return activities_model.CreateRepoTransferNotification(ctx, doer, newOwner, repo) }) if err != nil { diff --git a/modules/repository/collaborator.go b/modules/repository/collaborator.go index f2b95151879ff..f5cdc35045353 100644 --- a/modules/repository/collaborator.go +++ b/modules/repository/collaborator.go @@ -14,7 +14,7 @@ import ( ) func AddCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error { - return db.AutoTx(ctx, func(ctx context.Context) error { + return db.WithTx(ctx, func(ctx context.Context) error { collaboration := &repo_model.Collaboration{ RepoID: repo.ID, UserID: u.ID, diff --git a/services/issue/comments.go b/services/issue/comments.go index 46c0daf70a336..1323fb47aa440 100644 --- a/services/issue/comments.go +++ b/services/issue/comments.go @@ -123,7 +123,7 @@ func UpdateComment(ctx context.Context, c *issues_model.Comment, doer *user_mode // DeleteComment deletes the comment func DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) error { - err := db.AutoTx(ctx, func(ctx context.Context) error { + err := db.WithTx(ctx, func(ctx context.Context) error { return issues_model.DeleteComment(ctx, comment) }) if err != nil { From bdf8c80f4196763869b540554656dcadacb8d9bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Jan 2023 19:48:00 +0800 Subject: [PATCH 4/6] Bump json5 from 1.0.1 to 1.0.2 (#22365) Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
Release notes

Sourced from json5's releases.

v1.0.2

  • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295). This has been backported to v1. (#298)
Changelog

Sourced from json5's changelog.

Unreleased [code, diff]

v2.2.3 [code, diff]

  • Fix: json5@2.2.3 is now the 'latest' release according to npm instead of v1.0.2. (#299)

v2.2.2 [code, diff]

  • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295).

v2.2.1 [code, diff]

  • Fix: Removed dependence on minimist to patch CVE-2021-44906. (#266)

v2.2.0 [code, diff]

  • New: Accurate and documented TypeScript declarations are now included. There is no need to install @types/json5. (#236, #244)

v2.1.3 [code, diff]

  • Fix: An out of memory bug when parsing numbers has been fixed. (#228, #229)

v2.1.2 [code, diff]

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=json5&package-manager=npm_and_yarn&previous-version=1.0.1&new-version=1.0.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) - `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language - `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language - `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language - `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/go-gitea/gitea/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 65d9695a01130..a301dcddb301e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5893,9 +5893,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", - "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "bin": { "json5": "lib/cli.js" }, @@ -8937,9 +8937,9 @@ } }, "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -14210,9 +14210,9 @@ "dev": true }, "json5": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", - "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==" + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsonc-parser": { "version": "2.2.1", @@ -16502,9 +16502,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" From dfd2db569594006fc7e9ba7a0eb3f796f70e4fda Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 8 Jan 2023 21:22:41 +0800 Subject: [PATCH 5/6] Fix set system setting failure once it cached (#22333) Unfortunately, #22295 introduced a bug that when set a cached system setting, it will not affect. This PR make sure to remove the cache key when updating a system setting. Fix #22332 --- models/system/setting.go | 27 +++++++++++++++------------ models/system/setting_test.go | 6 +++++- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/models/system/setting.go b/models/system/setting.go index 3eb8b3955d123..0701c4bf48dc4 100644 --- a/models/system/setting.go +++ b/models/system/setting.go @@ -12,7 +12,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/cache" - "code.gitea.io/gitea/modules/setting" + setting_module "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "strk.kbt.io/projects/go/libravatar" @@ -88,7 +88,7 @@ func GetSettingNoCache(key string) (*Setting, error) { if len(v) == 0 { return nil, ErrSettingIsNotExist{key} } - return v[key], nil + return v[strings.ToLower(key)], nil } // GetSetting returns the setting value via the key @@ -131,7 +131,7 @@ func GetSettings(keys []string) (map[string]*Setting, error) { type AllSettings map[string]*Setting func (settings AllSettings) Get(key string) Setting { - if v, ok := settings[key]; ok { + if v, ok := settings[strings.ToLower(key)]; ok { return *v } return Setting{} @@ -184,14 +184,17 @@ func SetSettingNoVersion(key, value string) error { // SetSetting updates a users' setting for a specific key func SetSetting(setting *Setting) error { - _, err := cache.GetString(genSettingCacheKey(setting.SettingKey), func() (string, error) { - return setting.SettingValue, upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version) - }) - if err != nil { + if err := upsertSettingValue(strings.ToLower(setting.SettingKey), setting.SettingValue, setting.Version); err != nil { return err } setting.Version++ + + cc := cache.GetCache() + if cc != nil { + return cc.Put(genSettingCacheKey(setting.SettingKey), setting.SettingValue, setting_module.CacheService.TTLSeconds()) + } + return nil } @@ -243,7 +246,7 @@ func Init() error { var disableGravatar bool disableGravatarSetting, err := GetSettingNoCache(KeyPictureDisableGravatar) if IsErrSettingIsNotExist(err) { - disableGravatar = setting.GetDefaultDisableGravatar() + disableGravatar = setting_module.GetDefaultDisableGravatar() disableGravatarSetting = &Setting{SettingValue: strconv.FormatBool(disableGravatar)} } else if err != nil { return err @@ -254,7 +257,7 @@ func Init() error { var enableFederatedAvatar bool enableFederatedAvatarSetting, err := GetSettingNoCache(KeyPictureEnableFederatedAvatar) if IsErrSettingIsNotExist(err) { - enableFederatedAvatar = setting.GetDefaultEnableFederatedAvatar(disableGravatar) + enableFederatedAvatar = setting_module.GetDefaultEnableFederatedAvatar(disableGravatar) enableFederatedAvatarSetting = &Setting{SettingValue: strconv.FormatBool(enableFederatedAvatar)} } else if err != nil { return err @@ -262,16 +265,16 @@ func Init() error { enableFederatedAvatar = disableGravatarSetting.GetValueBool() } - if setting.OfflineMode { + if setting_module.OfflineMode { disableGravatar = true enableFederatedAvatar = false } if enableFederatedAvatar || !disableGravatar { var err error - GravatarSourceURL, err = url.Parse(setting.GravatarSource) + GravatarSourceURL, err = url.Parse(setting_module.GravatarSource) if err != nil { - return fmt.Errorf("Failed to parse Gravatar URL(%s): %w", setting.GravatarSource, err) + return fmt.Errorf("Failed to parse Gravatar URL(%s): %w", setting_module.GravatarSource, err) } } diff --git a/models/system/setting_test.go b/models/system/setting_test.go index 3ff5ba2520890..c43d2e30841d2 100644 --- a/models/system/setting_test.go +++ b/models/system/setting_test.go @@ -33,10 +33,14 @@ func TestSettings(t *testing.T) { assert.EqualValues(t, newSetting.SettingValue, settings[strings.ToLower(keyName)].SettingValue) // updated setting - updatedSetting := &system.Setting{SettingKey: keyName, SettingValue: "100", Version: newSetting.Version} + updatedSetting := &system.Setting{SettingKey: keyName, SettingValue: "100", Version: settings[strings.ToLower(keyName)].Version} err = system.SetSetting(updatedSetting) assert.NoError(t, err) + value, err := system.GetSetting(keyName) + assert.NoError(t, err) + assert.EqualValues(t, updatedSetting.SettingValue, value) + // get all settings settings, err = system.GetAllSettings() assert.NoError(t, err) From b878155b8741c2769b6aa50a80609c36822451c9 Mon Sep 17 00:00:00 2001 From: delvh Date: Sun, 8 Jan 2023 19:25:28 +0100 Subject: [PATCH 6/6] Replace `can not` with `cannot` (#22372) Fixes #22371. --- options/locale/locale_en-US.ini | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 62471abe6f19c..ddc0ee25d51e4 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -95,7 +95,7 @@ copy_content = Copy content copy_branch = Copy branch name copy_success = Copied! copy_error = Copy failed -copy_type_unsupported = This file type can not be copied +copy_type_unsupported = This file type cannot be copied write = Write preview = Preview @@ -325,7 +325,7 @@ invalid_code = Your confirmation code is invalid or has expired. reset_password_helper = Recover Account reset_password_wrong_user = You are signed in as %s, but the account recovery link is for %s password_too_short = Password length cannot be less than %d characters. -non_local_account = Non-local users can not update their password through the Gitea web interface. +non_local_account = Non-local users cannot update their password through the Gitea web interface. verify = Verify scratch_code = Scratch code use_scratch_code = Use a scratch code @@ -507,10 +507,10 @@ cannot_add_org_to_team = An organization cannot be added as a team member. duplicate_invite_to_team = The user was already invited as a team member. organization_leave_success = You have successfully left the organization %s. -invalid_ssh_key = Can not verify your SSH key: %s -invalid_gpg_key = Can not verify your GPG key: %s +invalid_ssh_key = Cannot verify your SSH key: %s +invalid_gpg_key = Cannot verify your GPG key: %s invalid_ssh_principal = Invalid principal: %s -unable_verify_ssh_key = "Can not verify the SSH key; double-check it for mistakes." +unable_verify_ssh_key = "Cannot verify the SSH key; double-check it for mistakes." auth_failed = Authentication failed: %v still_own_repo = "Your account owns one or more repositories; delete or transfer them first." @@ -618,7 +618,7 @@ new_password = New Password retype_new_password = Re-Type New Password password_incorrect = The current password is incorrect. change_password_success = Your password has been updated. Sign in using your new password from now on. -password_change_disabled = Non-local users can not update their password through the Gitea web interface. +password_change_disabled = Non-local users cannot update their password through the Gitea web interface. emails = Email Addresses manage_emails = Manage Email Addresses @@ -813,7 +813,7 @@ orgs_none = You are not a member of any organizations. repos_none = You do not own any repositories delete_account = Delete Your Account -delete_prompt = This operation will permanently delete your user account. It CAN NOT be undone. +delete_prompt = This operation will permanently delete your user account. It CANNOT be undone. delete_with_all_comments = Your account is younger than %s. To avoid ghost comments, all issue/PR comments will be deleted with it. confirm_delete_account = Confirm Deletion delete_account_title = Delete User Account @@ -977,7 +977,7 @@ migrate.clone_address_desc = The HTTP(S) or Git 'clone' URL of an existing repos migrate.github_token_desc = You can put one or more tokens with comma separated here to make migrating faster because of GitHub API rate limit. WARN: Abusing this feature may violate the service provider's policy and lead to account blocking. migrate.clone_local_path = or a local server path migrate.permission_denied = You are not allowed to import local repositories. -migrate.permission_denied_blocked = You can not import from disallowed hosts, please ask the admin to check ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS settings. +migrate.permission_denied_blocked = You cannot import from disallowed hosts, please ask the admin to check ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS settings. migrate.invalid_local_path = "The local path is invalid. It does not exist or is not a directory." migrate.invalid_lfs_endpoint = The LFS endpoint is not valid. migrate.failed = Migration failed: %v @@ -1590,7 +1590,7 @@ pulls.wrong_commit_id = "commit id must be a commit id on the target branch" pulls.no_merge_desc = This pull request cannot be merged because all repository merge options are disabled. pulls.no_merge_helper = Enable merge options in the repository settings or merge the pull request manually. -pulls.no_merge_wip = This pull request can not be merged because it is marked as being a work in progress. +pulls.no_merge_wip = This pull request cannot be merged because it is marked as being a work in progress. pulls.no_merge_not_ready = This pull request is not ready to be merged, check review status and status checks. pulls.no_merge_access = You are not authorized to merge this pull request. pulls.merge_pull_request = Create merge commit @@ -1925,8 +1925,8 @@ settings.update_settings_success = The repository settings have been updated. settings.confirm_delete = Delete Repository settings.add_collaborator = Add Collaborator settings.add_collaborator_success = The collaborator has been added. -settings.add_collaborator_inactive_user = Can not add an inactive user as a collaborator. -settings.add_collaborator_owner = Can not add an owner as a collaborator. +settings.add_collaborator_inactive_user = Cannot add an inactive user as a collaborator. +settings.add_collaborator_owner = Cannot add an owner as a collaborator. settings.add_collaborator_duplicate = The collaborator is already added to this repository. settings.delete_collaborator = Remove settings.collaborator_deletion = Remove Collaborator @@ -2071,7 +2071,7 @@ settings.branches = Branches settings.protected_branch = Branch Protection settings.protected_branch_can_push = Allow push? settings.protected_branch_can_push_yes = You can push -settings.protected_branch_can_push_no = You can not push +settings.protected_branch_can_push_no = You cannot push settings.branch_protection = Branch Protection for Branch '%s' settings.protect_this_branch = Enable Branch Protection settings.protect_this_branch_desc = Prevents deletion and restricts Git pushing and merging to the branch. @@ -2323,7 +2323,7 @@ tag.create_success = Tag '%s' has been created. topic.manage_topics = Manage Topics topic.done = Done -topic.count_prompt = You can not select more than 25 topics +topic.count_prompt = You cannot select more than 25 topics topic.format_prompt = Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long. find_file.go_to_file = Go to file @@ -3061,7 +3061,7 @@ raw_minutes = minutes [dropzone] default_message = Drop files or click here to upload. -invalid_input_type = You can not upload files of this type. +invalid_input_type = You cannot upload files of this type. file_too_big = File size ({{filesize}} MB) exceeds the maximum size of ({{maxFilesize}} MB). remove_file = Remove file