Add RemoteAddress
to mirrors (#26952)
This PR adds a new field `RemoteAddress` to both mirror types which contains the sanitized remote address for easier (database) access to that information. Will be used in the audit PR if merged.
This commit is contained in:
parent
5e039b0580
commit
c766140dad
@ -532,6 +532,8 @@ var migrations = []Migration{
|
||||
NewMigration("Add Actions artifacts expiration date", v1_21.AddExpiredUnixColumnInActionArtifactTable),
|
||||
// v275 -> v276
|
||||
NewMigration("Add ScheduleID for ActionRun", v1_21.AddScheduleIDForActionRun),
|
||||
// v276 -> v277
|
||||
NewMigration("Add RemoteAddress to mirrors", v1_21.AddRemoteAddressToMirrors),
|
||||
}
|
||||
|
||||
// GetCurrentDBVersion returns the current db version
|
||||
|
132
models/migrations/v1_21/v276.go
Normal file
132
models/migrations/v1_21/v276.go
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_21 //nolint
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
giturl "code.gitea.io/gitea/modules/git/url"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddRemoteAddressToMirrors(x *xorm.Engine) error {
|
||||
type Mirror struct {
|
||||
RemoteAddress string `xorm:"VARCHAR(2048)"`
|
||||
}
|
||||
|
||||
type PushMirror struct {
|
||||
RemoteAddress string `xorm:"VARCHAR(2048)"`
|
||||
}
|
||||
|
||||
if err := x.Sync(new(Mirror), new(PushMirror)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := migratePullMirrors(x); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return migratePushMirrors(x)
|
||||
}
|
||||
|
||||
func migratePullMirrors(x *xorm.Engine) error {
|
||||
type Mirror struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"INDEX"`
|
||||
RemoteAddress string `xorm:"VARCHAR(2048)"`
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := sess.Iterate(new(Mirror), func(_ int, bean any) error {
|
||||
m := bean.(*Mirror)
|
||||
remoteAddress, err := getRemoteAddress(sess, m.RepoID, "origin")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.RemoteAddress = remoteAddress
|
||||
|
||||
_, err = sess.ID(m.ID).Cols("remote_address").Update(m)
|
||||
return err
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func migratePushMirrors(x *xorm.Engine) error {
|
||||
type PushMirror struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"INDEX"`
|
||||
RemoteName string
|
||||
RemoteAddress string `xorm:"VARCHAR(2048)"`
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
|
||||
if err := sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := sess.Iterate(new(PushMirror), func(_ int, bean any) error {
|
||||
m := bean.(*PushMirror)
|
||||
remoteAddress, err := getRemoteAddress(sess, m.RepoID, m.RemoteName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.RemoteAddress = remoteAddress
|
||||
|
||||
_, err = sess.ID(m.ID).Cols("remote_address").Update(m)
|
||||
return err
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func getRemoteAddress(sess *xorm.Session, repoID int64, remoteName string) (string, error) {
|
||||
var ownerName string
|
||||
var repoName string
|
||||
has, err := sess.
|
||||
Table("repository").
|
||||
Cols("owner_name", "lower_name").
|
||||
Where("id=?", repoID).
|
||||
Get(&ownerName, &repoName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if !has {
|
||||
return "", fmt.Errorf("repository [%v] not found", repoID)
|
||||
}
|
||||
|
||||
repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(ownerName), strings.ToLower(repoName)+".git")
|
||||
|
||||
remoteURL, err := git.GetRemoteAddress(context.Background(), repoPath, remoteName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
u, err := giturl.Parse(remoteURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
u.User = nil
|
||||
|
||||
return u.String(), nil
|
||||
}
|
@ -31,7 +31,7 @@ type Mirror struct {
|
||||
LFS bool `xorm:"lfs_enabled NOT NULL DEFAULT false"`
|
||||
LFSEndpoint string `xorm:"lfs_endpoint TEXT"`
|
||||
|
||||
Address string `xorm:"-"`
|
||||
RemoteAddress string `xorm:"VARCHAR(2048)"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -20,10 +20,11 @@ var ErrPushMirrorNotExist = util.NewNotExistErrorf("PushMirror does not exist")
|
||||
|
||||
// PushMirror represents mirror information of a repository.
|
||||
type PushMirror struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"INDEX"`
|
||||
Repo *Repository `xorm:"-"`
|
||||
RemoteName string
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
RepoID int64 `xorm:"INDEX"`
|
||||
Repo *Repository `xorm:"-"`
|
||||
RemoteName string
|
||||
RemoteAddress string `xorm:"VARCHAR(2048)"`
|
||||
|
||||
SyncOnCommit bool `xorm:"NOT NULL DEFAULT true"`
|
||||
Interval time.Duration
|
||||
@ -31,6 +32,7 @@ type PushMirror struct {
|
||||
LastUpdateUnix timeutil.TimeStamp `xorm:"INDEX last_update"`
|
||||
LastError string `xorm:"text"`
|
||||
}
|
||||
|
||||
type PushMirrorOptions struct {
|
||||
ID int64
|
||||
RepoID int64
|
||||
|
@ -191,12 +191,8 @@ func (repo *Repository) SanitizedOriginalURL() string {
|
||||
if repo.OriginalURL == "" {
|
||||
return ""
|
||||
}
|
||||
u, err := url.Parse(repo.OriginalURL)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
u.User = nil
|
||||
return u.String()
|
||||
u, _ := util.SanitizeURL(repo.OriginalURL)
|
||||
return u
|
||||
}
|
||||
|
||||
// text representations to be returned in SizeDetail.Name
|
||||
|
@ -180,12 +180,17 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
|
||||
defer committer.Close()
|
||||
|
||||
if opts.Mirror {
|
||||
remoteAddress, err := util.SanitizeURL(opts.CloneAddr)
|
||||
if err != nil {
|
||||
return repo, err
|
||||
}
|
||||
mirrorModel := repo_model.Mirror{
|
||||
RepoID: repo.ID,
|
||||
Interval: setting.Mirror.DefaultInterval,
|
||||
EnablePrune: true,
|
||||
NextUpdateUnix: timeutil.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval),
|
||||
LFS: opts.LFS,
|
||||
RemoteAddress: remoteAddress,
|
||||
}
|
||||
if opts.LFS {
|
||||
mirrorModel.LFSEndpoint = opts.LFSEndpoint
|
||||
|
@ -39,3 +39,12 @@ func URLJoin(base string, elems ...string) string {
|
||||
}
|
||||
return joinedURL
|
||||
}
|
||||
|
||||
func SanitizeURL(s string) (string, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
u.User = nil
|
||||
return u.String(), nil
|
||||
}
|
||||
|
@ -353,12 +353,19 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro
|
||||
return
|
||||
}
|
||||
|
||||
remoteAddress, err := util.SanitizeURL(mirrorOption.RemoteAddress)
|
||||
if err != nil {
|
||||
ctx.ServerError("SanitizeURL", err)
|
||||
return
|
||||
}
|
||||
|
||||
pushMirror := &repo_model.PushMirror{
|
||||
RepoID: repo.ID,
|
||||
Repo: repo,
|
||||
RemoteName: fmt.Sprintf("remote_mirror_%s", remoteSuffix),
|
||||
Interval: interval,
|
||||
SyncOnCommit: mirrorOption.SyncOnCommit,
|
||||
RepoID: repo.ID,
|
||||
Repo: repo,
|
||||
RemoteName: fmt.Sprintf("remote_mirror_%s", remoteSuffix),
|
||||
Interval: interval,
|
||||
SyncOnCommit: mirrorOption.SyncOnCommit,
|
||||
RemoteAddress: remoteAddress,
|
||||
}
|
||||
|
||||
if err = repo_model.InsertPushMirror(ctx, pushMirror); err != nil {
|
||||
|
@ -243,6 +243,13 @@ func SettingsPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
remoteAddress, err := util.SanitizeURL(form.MirrorAddress)
|
||||
if err != nil {
|
||||
ctx.ServerError("SanitizeURL", err)
|
||||
return
|
||||
}
|
||||
pullMirror.RemoteAddress = remoteAddress
|
||||
|
||||
form.LFS = form.LFS && setting.LFS.StartServer
|
||||
|
||||
if len(form.LFSEndpoint) > 0 {
|
||||
@ -397,12 +404,19 @@ func SettingsPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
remoteAddress, err := util.SanitizeURL(form.PushMirrorAddress)
|
||||
if err != nil {
|
||||
ctx.ServerError("SanitizeURL", err)
|
||||
return
|
||||
}
|
||||
|
||||
m := &repo_model.PushMirror{
|
||||
RepoID: repo.ID,
|
||||
Repo: repo,
|
||||
RemoteName: fmt.Sprintf("remote_mirror_%s", remoteSuffix),
|
||||
SyncOnCommit: form.PushMirrorSyncOnCommit,
|
||||
Interval: interval,
|
||||
RepoID: repo.ID,
|
||||
Repo: repo,
|
||||
RemoteName: fmt.Sprintf("remote_mirror_%s", remoteSuffix),
|
||||
SyncOnCommit: form.PushMirrorSyncOnCommit,
|
||||
Interval: interval,
|
||||
RemoteAddress: remoteAddress,
|
||||
}
|
||||
if err := repo_model.InsertPushMirror(ctx, m); err != nil {
|
||||
ctx.ServerError("InsertPushMirror", err)
|
||||
|
@ -628,15 +628,6 @@ func markupRender(ctx *context.Context, renderCtx *markup.RenderContext, input i
|
||||
return escaped, output, err
|
||||
}
|
||||
|
||||
func safeURL(address string) string {
|
||||
u, err := url.Parse(address)
|
||||
if err != nil {
|
||||
return address
|
||||
}
|
||||
u.User = nil
|
||||
return u.String()
|
||||
}
|
||||
|
||||
func checkHomeCodeViewable(ctx *context.Context) {
|
||||
if len(ctx.Repo.Units) > 0 {
|
||||
if ctx.Repo.Repository.IsBeingCreated() {
|
||||
@ -660,7 +651,7 @@ func checkHomeCodeViewable(ctx *context.Context) {
|
||||
|
||||
ctx.Data["Repo"] = ctx.Repo
|
||||
ctx.Data["MigrateTask"] = task
|
||||
ctx.Data["CloneAddr"] = safeURL(cfg.CloneAddr)
|
||||
ctx.Data["CloneAddr"], _ = util.SanitizeURL(cfg.CloneAddr)
|
||||
ctx.Data["Failed"] = task.Status == structs.TaskStatusFailed
|
||||
ctx.HTML(http.StatusOK, tplMigrating)
|
||||
return
|
||||
|
@ -5,21 +5,16 @@ package convert
|
||||
|
||||
import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
)
|
||||
|
||||
// ToPushMirror convert from repo_model.PushMirror and remoteAddress to api.TopicResponse
|
||||
func ToPushMirror(pm *repo_model.PushMirror) (*api.PushMirror, error) {
|
||||
repo := pm.GetRepository()
|
||||
remoteAddress, err := getRemoteAddress(repo, pm.RemoteName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &api.PushMirror{
|
||||
RepoName: repo.Name,
|
||||
RemoteName: pm.RemoteName,
|
||||
RemoteAddress: remoteAddress,
|
||||
RemoteAddress: pm.RemoteAddress,
|
||||
CreatedUnix: pm.CreatedUnix.FormatLong(),
|
||||
LastUpdateUnix: pm.LastUpdateUnix.FormatLong(),
|
||||
LastError: pm.LastError,
|
||||
@ -27,13 +22,3 @@ func ToPushMirror(pm *repo_model.PushMirror) (*api.PushMirror, error) {
|
||||
SyncOnCommit: pm.SyncOnCommit,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getRemoteAddress(repo *repo_model.Repository, remoteName string) (string, error) {
|
||||
url, err := git.GetRemoteURL(git.DefaultContext, repo.RepoPath(), remoteName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// remove confidential information
|
||||
url.User = nil
|
||||
return url.String(), nil
|
||||
}
|
||||
|
@ -37,8 +37,7 @@
|
||||
{{end}}
|
||||
</div>
|
||||
{{if $.PullMirror}}
|
||||
{{$address := MirrorRemoteAddress $.Context . $.PullMirror.GetRemoteName false}}
|
||||
<div class="fork-flag">{{$.locale.Tr "repo.mirror_from"}} <a target="_blank" rel="noopener noreferrer" href="{{$address.Address}}">{{$address.Address}}</a></div>
|
||||
<div class="fork-flag">{{$.locale.Tr "repo.mirror_from"}} <a target="_blank" rel="noopener noreferrer" href="{{$.PullMirror.RemoteAddress}}">{{$.PullMirror.RemoteAddress}}</a></div>
|
||||
{{end}}
|
||||
{{if .IsFork}}<div class="fork-flag">{{$.locale.Tr "repo.forked_from"}} <a href="{{.BaseRepo.Link}}">{{.BaseRepo.FullName}}</a></div>{{end}}
|
||||
{{if .IsGenerated}}<div class="fork-flag">{{$.locale.Tr "repo.generated_from"}} <a href="{{.TemplateRepo.Link}}">{{.TemplateRepo.FullName}}</a></div>{{end}}
|
||||
|
@ -123,7 +123,7 @@
|
||||
{{else if $isWorkingPullMirror}}
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{(MirrorRemoteAddress $.Context .Repository .PullMirror.GetRemoteName false).Address}}</td>
|
||||
<td>{{.PullMirror.RemoteAddress}}</td>
|
||||
<td>{{$.locale.Tr "repo.settings.mirror_settings.direction.pull"}}</td>
|
||||
<td>{{DateTime "full" .PullMirror.UpdatedUnix}}</td>
|
||||
<td class="right aligned">
|
||||
@ -200,8 +200,7 @@
|
||||
<tbody>
|
||||
{{range .PushMirrors}}
|
||||
<tr>
|
||||
{{$address := MirrorRemoteAddress $.Context $.Repository .GetRemoteName true}}
|
||||
<td class="gt-word-break">{{$address.Address}}</td>
|
||||
<td class="gt-word-break">{{.RemoteAddress}}</td>
|
||||
<td>{{$.locale.Tr "repo.settings.mirror_settings.direction.push"}}</td>
|
||||
<td>{{if .LastUpdateUnix}}{{DateTime "full" .LastUpdateUnix}}{{else}}{{$.locale.Tr "never"}}{{end}} {{if .LastError}}<div class="ui red label" data-tooltip-content="{{.LastError}}">{{$.locale.Tr "error"}}</div>{{end}}</td>
|
||||
<td class="right aligned">
|
||||
@ -211,7 +210,7 @@
|
||||
data-tooltip-content="{{$.locale.Tr "repo.settings.mirror_settings.push_mirror.edit_sync_time"}}"
|
||||
data-modal-push-mirror-edit-id="{{.ID}}"
|
||||
data-modal-push-mirror-edit-interval="{{.Interval}}"
|
||||
data-modal-push-mirror-edit-address="{{$address.Address}}"
|
||||
data-modal-push-mirror-edit-address="{{.RemoteAddress}}"
|
||||
>
|
||||
{{svg "octicon-pencil" 14}}
|
||||
</button>
|
||||
|
Loading…
Reference in New Issue
Block a user