Skip to content

Commit

Permalink
Add RemoteAddress to mirrors (#26952)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
KN4CK3R authored Sep 16, 2023
1 parent 5e039b0 commit c766140
Show file tree
Hide file tree
Showing 13 changed files with 194 additions and 53 deletions.
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
132 changes: 132 additions & 0 deletions models/migrations/v1_21/v276.go
Original file line number Diff line number Diff line change
@@ -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
}
2 changes: 1 addition & 1 deletion models/repo/mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
10 changes: 6 additions & 4 deletions models/repo/pushmirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,19 @@ 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
CreatedUnix timeutil.TimeStamp `xorm:"created"`
LastUpdateUnix timeutil.TimeStamp `xorm:"INDEX last_update"`
LastError string `xorm:"text"`
}

type PushMirrorOptions struct {
ID int64
RepoID int64
Expand Down
8 changes: 2 additions & 6 deletions models/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions modules/repository/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions modules/util/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
17 changes: 12 additions & 5 deletions routers/api/v1/repo/mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
24 changes: 19 additions & 5 deletions routers/web/repo/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down
11 changes: 1 addition & 10 deletions routers/web/repo/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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
Expand Down
17 changes: 1 addition & 16 deletions services/convert/mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,20 @@ 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,
Interval: pm.Interval.String(),
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
}
3 changes: 1 addition & 2 deletions templates/repo/header.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down
7 changes: 3 additions & 4 deletions templates/repo/settings/options.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -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">
Expand All @@ -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>
Expand Down

0 comments on commit c766140

Please sign in to comment.