From c8c8377acbab41083f1b92e836a9bde15e29e362 Mon Sep 17 00:00:00 2001 From: Gusted Date: Sat, 2 Nov 2024 15:06:27 +0100 Subject: [PATCH] fix: add ID check for updating push mirror interval - Ensure that the specified push mirror ID belongs to the requested repository, otherwise it is possible to modify the intervals of the push mirrors that do not belong to the requested repository. - Integration test added. (cherry picked from commit 786dfc7fb81ee76d4292ca5fcb33e6ea7bdccc29) --- routers/web/repo/setting/setting.go | 16 +++--- tests/integration/mirror_push_test.go | 79 +++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 9 deletions(-) diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index aee2e2f469..ce506eafb1 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -566,21 +566,19 @@ func SettingsPost(ctx *context.Context) { // as an error on the UI for this action ctx.Data["Err_RepoName"] = nil + m, err := selectPushMirrorByForm(ctx, form, repo) + if err != nil { + ctx.NotFound("", nil) + return + } + interval, err := time.ParseDuration(form.PushMirrorInterval) if err != nil || (interval != 0 && interval < setting.Mirror.MinInterval) { ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &forms.RepoSettingForm{}) return } - id, err := strconv.ParseInt(form.PushMirrorID, 10, 64) - if err != nil { - ctx.ServerError("UpdatePushMirrorIntervalPushMirrorID", err) - return - } - m := &repo_model.PushMirror{ - ID: id, - Interval: interval, - } + m.Interval = interval if err := repo_model.UpdatePushMirrorInterval(ctx, m); err != nil { ctx.ServerError("UpdatePushMirrorInterval", err) return diff --git a/tests/integration/mirror_push_test.go b/tests/integration/mirror_push_test.go index 2dda4d6836..fa62219707 100644 --- a/tests/integration/mirror_push_test.go +++ b/tests/integration/mirror_push_test.go @@ -323,3 +323,82 @@ func TestSSHPushMirror(t *testing.T) { }) }) } + +func TestPushMirrorSettings(t *testing.T) { + onGiteaRun(t, func(t *testing.T, u *url.URL) { + defer test.MockVariableValue(&setting.Migrations.AllowLocalNetworks, true)() + defer test.MockVariableValue(&setting.Mirror.Enabled, true)() + require.NoError(t, migrations.Init()) + + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) + srcRepo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) + assert.False(t, srcRepo.HasWiki()) + sess := loginUser(t, user.Name) + pushToRepo, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{ + Name: optional.Some("push-mirror-test"), + AutoInit: optional.Some(false), + EnabledUnits: optional.Some([]unit.Type{unit.TypeCode}), + }) + defer f() + + t.Run("Adding", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/settings", srcRepo2.FullName()), map[string]string{ + "_csrf": GetCSRF(t, sess, fmt.Sprintf("/%s/settings", srcRepo2.FullName())), + "action": "push-mirror-add", + "push_mirror_address": u.String() + pushToRepo.FullName(), + "push_mirror_interval": "0", + }) + sess.MakeRequest(t, req, http.StatusSeeOther) + + req = NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/settings", srcRepo.FullName()), map[string]string{ + "_csrf": GetCSRF(t, sess, fmt.Sprintf("/%s/settings", srcRepo.FullName())), + "action": "push-mirror-add", + "push_mirror_address": u.String() + pushToRepo.FullName(), + "push_mirror_interval": "0", + }) + sess.MakeRequest(t, req, http.StatusSeeOther) + + flashCookie := sess.GetCookie(gitea_context.CookieNameFlash) + assert.NotNil(t, flashCookie) + assert.Contains(t, flashCookie.Value, "success") + }) + + mirrors, _, err := repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo.ID, db.ListOptions{}) + require.NoError(t, err) + assert.Len(t, mirrors, 1) + mirrorID := mirrors[0].ID + + mirrors, _, err = repo_model.GetPushMirrorsByRepoID(db.DefaultContext, srcRepo2.ID, db.ListOptions{}) + require.NoError(t, err) + assert.Len(t, mirrors, 1) + + t.Run("Interval", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + unittest.AssertExistsAndLoadBean(t, &repo_model.PushMirror{ID: mirrorID - 1}) + + req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/settings", srcRepo.FullName()), map[string]string{ + "_csrf": GetCSRF(t, sess, fmt.Sprintf("/%s/settings", srcRepo.FullName())), + "action": "push-mirror-update", + "push_mirror_id": strconv.FormatInt(mirrorID-1, 10), + "push_mirror_interval": "10m0s", + }) + sess.MakeRequest(t, req, http.StatusNotFound) + + req = NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/settings", srcRepo.FullName()), map[string]string{ + "_csrf": GetCSRF(t, sess, fmt.Sprintf("/%s/settings", srcRepo.FullName())), + "action": "push-mirror-update", + "push_mirror_id": strconv.FormatInt(mirrorID, 10), + "push_mirror_interval": "10m0s", + }) + sess.MakeRequest(t, req, http.StatusSeeOther) + + flashCookie := sess.GetCookie(gitea_context.CookieNameFlash) + assert.NotNil(t, flashCookie) + assert.Contains(t, flashCookie.Value, "success") + }) + }) +}