mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-11 15:44:52 +02:00
Add check redirect for migrations
This commit is contained in:
parent
56f23f623a
commit
4ac42f2b2f
@ -24,9 +24,9 @@ type Client interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewClient creates a LFS client
|
// NewClient creates a LFS client
|
||||||
func NewClient(endpoint *url.URL, httpTransport *http.Transport) Client {
|
func NewClient(endpoint *url.URL, httpTransport *http.Transport, checkRedirect func(req *http.Request, via []*http.Request) error) Client {
|
||||||
if endpoint.Scheme == "file" {
|
if endpoint.Scheme == "file" {
|
||||||
return newFilesystemClient(endpoint)
|
return newFilesystemClient(endpoint)
|
||||||
}
|
}
|
||||||
return newHTTPClient(endpoint, httpTransport)
|
return newHTTPClient(endpoint, httpTransport, checkRedirect)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ func (c *HTTPClient) BatchSize() int {
|
|||||||
return setting.LFSClient.BatchSize
|
return setting.LFSClient.BatchSize
|
||||||
}
|
}
|
||||||
|
|
||||||
func newHTTPClient(endpoint *url.URL, httpTransport *http.Transport) *HTTPClient {
|
func newHTTPClient(endpoint *url.URL, httpTransport *http.Transport, checkRedirect func(req *http.Request, via []*http.Request) error) *HTTPClient {
|
||||||
if httpTransport == nil {
|
if httpTransport == nil {
|
||||||
httpTransport = &http.Transport{
|
httpTransport = &http.Transport{
|
||||||
Proxy: proxy.Proxy(),
|
Proxy: proxy.Proxy(),
|
||||||
@ -42,7 +42,8 @@ func newHTTPClient(endpoint *url.URL, httpTransport *http.Transport) *HTTPClient
|
|||||||
}
|
}
|
||||||
|
|
||||||
hc := &http.Client{
|
hc := &http.Client{
|
||||||
Transport: httpTransport,
|
Transport: httpTransport,
|
||||||
|
CheckRedirect: checkRedirect,
|
||||||
}
|
}
|
||||||
|
|
||||||
basic := &BasicTransferAdapter{hc}
|
basic := &BasicTransferAdapter{hc}
|
||||||
|
|||||||
@ -129,7 +129,7 @@ func (g *GiteaLocalUploader) CreateRepo(ctx context.Context, repo *base.Reposito
|
|||||||
Wiki: opts.Wiki,
|
Wiki: opts.Wiki,
|
||||||
Releases: opts.Releases, // if didn't get releases, then sync them from tags
|
Releases: opts.Releases, // if didn't get releases, then sync them from tags
|
||||||
MirrorInterval: opts.MirrorInterval,
|
MirrorInterval: opts.MirrorInterval,
|
||||||
}, NewMigrationHTTPTransport())
|
}, NewMigrationHTTPTransport(), CheckMigrateRedirect)
|
||||||
|
|
||||||
g.sameApp = strings.HasPrefix(repo.OriginalURL, setting.AppURL)
|
g.sameApp = strings.HasPrefix(repo.OriginalURL, setting.AppURL)
|
||||||
g.repo = r
|
g.repo = r
|
||||||
|
|||||||
@ -100,6 +100,7 @@ func NewGithubDownloaderV3(_ context.Context, baseURL, userName, password, token
|
|||||||
Base: NewMigrationHTTPTransport(),
|
Base: NewMigrationHTTPTransport(),
|
||||||
Source: oauth2.ReuseTokenSource(nil, ts),
|
Source: oauth2.ReuseTokenSource(nil, ts),
|
||||||
},
|
},
|
||||||
|
CheckRedirect: CheckMigrateRedirect,
|
||||||
}
|
}
|
||||||
|
|
||||||
downloader.addClient(client, baseURL)
|
downloader.addClient(client, baseURL)
|
||||||
@ -111,7 +112,8 @@ func NewGithubDownloaderV3(_ context.Context, baseURL, userName, password, token
|
|||||||
return proxy.Proxy()(req)
|
return proxy.Proxy()(req)
|
||||||
}
|
}
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Transport: transport,
|
Transport: transport,
|
||||||
|
CheckRedirect: CheckMigrateRedirect,
|
||||||
}
|
}
|
||||||
downloader.addClient(client, baseURL)
|
downloader.addClient(client, baseURL)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -113,6 +113,7 @@ func (g *GogsDownloader) client(ctx context.Context) *gogs.Client {
|
|||||||
}
|
}
|
||||||
return httpTransport.RoundTrip(req.WithContext(ctx))
|
return httpTransport.RoundTrip(req.WithContext(ctx))
|
||||||
}),
|
}),
|
||||||
|
CheckRedirect: CheckMigrateRedirect,
|
||||||
})
|
})
|
||||||
return gogsClient
|
return gogsClient
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,8 +5,10 @@ package migrations
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/hostmatcher"
|
"code.gitea.io/gitea/modules/hostmatcher"
|
||||||
"code.gitea.io/gitea/modules/proxy"
|
"code.gitea.io/gitea/modules/proxy"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
@ -15,10 +17,27 @@ import (
|
|||||||
// NewMigrationHTTPClient returns a HTTP client for migration
|
// NewMigrationHTTPClient returns a HTTP client for migration
|
||||||
func NewMigrationHTTPClient() *http.Client {
|
func NewMigrationHTTPClient() *http.Client {
|
||||||
return &http.Client{
|
return &http.Client{
|
||||||
Transport: NewMigrationHTTPTransport(),
|
Transport: NewMigrationHTTPTransport(),
|
||||||
|
CheckRedirect: CheckMigrateRedirect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckMigrateRedirect(req *http.Request, via []*http.Request) error {
|
||||||
|
redirectURL := req.URL
|
||||||
|
if redirectURL == nil {
|
||||||
|
return &git.ErrInvalidCloneAddr{IsURLError: true, Host: "<EMPTY_REDIRECT_URL>"}
|
||||||
|
}
|
||||||
|
if redirectURL.Scheme != "http" && redirectURL.Scheme != "https" {
|
||||||
|
return &git.ErrInvalidCloneAddr{Host: redirectURL.Host, IsProtocolInvalid: true, IsPermissionDenied: true, IsURLError: true}
|
||||||
|
}
|
||||||
|
hostName := redirectURL.Hostname()
|
||||||
|
if hostName == "" {
|
||||||
|
return &git.ErrInvalidCloneAddr{IsURLError: true, Host: redirectURL.String()}
|
||||||
|
}
|
||||||
|
addrList, _ := net.LookupIP(hostName)
|
||||||
|
return checkByAllowBlockList(hostName, addrList)
|
||||||
|
}
|
||||||
|
|
||||||
// NewMigrationHTTPTransport returns a HTTP transport for migration
|
// NewMigrationHTTPTransport returns a HTTP transport for migration
|
||||||
func NewMigrationHTTPTransport() *http.Transport {
|
func NewMigrationHTTPTransport() *http.Transport {
|
||||||
return &http.Transport{
|
return &http.Transport{
|
||||||
|
|||||||
@ -5,12 +5,16 @@ package migrations
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
"code.gitea.io/gitea/modules/test"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@ -113,3 +117,43 @@ func TestAllowBlockList(t *testing.T) {
|
|||||||
// reset
|
// reset
|
||||||
init("", "", false)
|
init("", "", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCheckMigrateRedirect(t *testing.T) {
|
||||||
|
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||||
|
|
||||||
|
defer test.MockVariableValue(&setting.Migrations.AllowedDomains, "")()
|
||||||
|
defer test.MockVariableValue(&setting.Migrations.BlockedDomains, "")()
|
||||||
|
defer test.MockVariableValue(&setting.Migrations.AllowLocalNetworks, false)()
|
||||||
|
|
||||||
|
assert.NoError(t, Init())
|
||||||
|
|
||||||
|
err := CheckMigrateRedirect(&http.Request{URL: &url.URL{Scheme: "https", Host: "1.2.3.4"}}, nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
err = CheckMigrateRedirect(&http.Request{URL: &url.URL{Scheme: "https", Host: "127.0.0.1"}}, nil)
|
||||||
|
assert.Error(t, err)
|
||||||
|
var addrErr *git.ErrInvalidCloneAddr
|
||||||
|
assert.ErrorAs(t, err, &addrErr)
|
||||||
|
assert.True(t, addrErr.IsPermissionDenied)
|
||||||
|
|
||||||
|
err = CheckMigrateRedirect(&http.Request{URL: nil}, nil)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.ErrorAs(t, err, &addrErr)
|
||||||
|
assert.True(t, addrErr.IsURLError)
|
||||||
|
|
||||||
|
err = CheckMigrateRedirect(&http.Request{URL: &url.URL{Scheme: "file", Host: "example.com"}}, nil)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.ErrorAs(t, err, &addrErr)
|
||||||
|
assert.True(t, addrErr.IsProtocolInvalid)
|
||||||
|
assert.True(t, addrErr.IsPermissionDenied)
|
||||||
|
|
||||||
|
err = CheckMigrateRedirect(&http.Request{URL: &url.URL{Scheme: "https"}}, nil)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.ErrorAs(t, err, &addrErr)
|
||||||
|
assert.True(t, addrErr.IsURLError)
|
||||||
|
|
||||||
|
setting.Migrations.AllowLocalNetworks = true
|
||||||
|
assert.NoError(t, Init())
|
||||||
|
err = CheckMigrateRedirect(&http.Request{URL: &url.URL{Scheme: "https", Host: "127.0.0.1"}}, nil)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|||||||
@ -90,6 +90,7 @@ func NewOneDevDownloader(ctx context.Context, baseURL *url.URL, username, passwo
|
|||||||
}
|
}
|
||||||
return httpTransport.RoundTrip(req.WithContext(ctx))
|
return httpTransport.RoundTrip(req.WithContext(ctx))
|
||||||
}),
|
}),
|
||||||
|
CheckRedirect: CheckMigrateRedirect,
|
||||||
},
|
},
|
||||||
userMap: make(map[int64]*onedevUser),
|
userMap: make(map[int64]*onedevUser),
|
||||||
milestoneMap: make(map[int64]string),
|
milestoneMap: make(map[int64]string),
|
||||||
|
|||||||
@ -173,7 +173,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*repo_module.SyncResu
|
|||||||
if m.LFS && setting.LFS.StartServer {
|
if m.LFS && setting.LFS.StartServer {
|
||||||
log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo)
|
log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo)
|
||||||
endpoint := lfs.DetermineEndpoint(remoteURL.String(), m.LFSEndpoint)
|
endpoint := lfs.DetermineEndpoint(remoteURL.String(), m.LFSEndpoint)
|
||||||
lfsClient := lfs.NewClient(endpoint, migrations.NewMigrationHTTPTransport())
|
lfsClient := lfs.NewClient(endpoint, migrations.NewMigrationHTTPTransport(), migrations.CheckMigrateRedirect)
|
||||||
if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, m.Repo, gitRepo, lfsClient); err != nil {
|
if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, m.Repo, gitRepo, lfsClient); err != nil {
|
||||||
log.Error("SyncMirrors [repo: %-v]: failed to synchronize LFS objects for repository: %v", m.Repo.FullName(), err)
|
log.Error("SyncMirrors [repo: %-v]: failed to synchronize LFS objects for repository: %v", m.Repo.FullName(), err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -145,7 +145,7 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
|
|||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
endpoint := lfs.DetermineEndpoint(remoteURL.String(), "")
|
endpoint := lfs.DetermineEndpoint(remoteURL.String(), "")
|
||||||
lfsClient := lfs.NewClient(endpoint, migrations.NewMigrationHTTPTransport())
|
lfsClient := lfs.NewClient(endpoint, migrations.NewMigrationHTTPTransport(), migrations.CheckMigrateRedirect)
|
||||||
if err := pushAllLFSObjects(ctx, gitRepo, lfsClient); err != nil {
|
if err := pushAllLFSObjects(ctx, gitRepo, lfsClient); err != nil {
|
||||||
return util.SanitizeErrorCredentialURLs(err)
|
return util.SanitizeErrorCredentialURLs(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,7 +72,7 @@ func cloneWiki(ctx context.Context, repo *repo_model.Repository, opts migration.
|
|||||||
// MigrateRepositoryGitData starts migrating git related data after created migrating repository
|
// MigrateRepositoryGitData starts migrating git related data after created migrating repository
|
||||||
func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
|
func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
|
||||||
repo *repo_model.Repository, opts migration.MigrateOptions,
|
repo *repo_model.Repository, opts migration.MigrateOptions,
|
||||||
httpTransport *http.Transport,
|
httpTransport *http.Transport, checkRedirect func(req *http.Request, via []*http.Request) error,
|
||||||
) (*repo_model.Repository, error) {
|
) (*repo_model.Repository, error) {
|
||||||
if u.IsOrganization() {
|
if u.IsOrganization() {
|
||||||
t, err := organization.OrgFromUser(u).GetOwnerTeam(ctx)
|
t, err := organization.OrgFromUser(u).GetOwnerTeam(ctx)
|
||||||
@ -160,7 +160,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
|
|||||||
|
|
||||||
if opts.LFS {
|
if opts.LFS {
|
||||||
endpoint := lfs.DetermineEndpoint(opts.CloneAddr, opts.LFSEndpoint)
|
endpoint := lfs.DetermineEndpoint(opts.CloneAddr, opts.LFSEndpoint)
|
||||||
lfsClient := lfs.NewClient(endpoint, httpTransport)
|
lfsClient := lfs.NewClient(endpoint, httpTransport, checkRedirect)
|
||||||
if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, repo, gitRepo, lfsClient); err != nil {
|
if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, repo, gitRepo, lfsClient); err != nil {
|
||||||
log.Error("Failed to store missing LFS objects for repository: %v", err)
|
log.Error("Failed to store missing LFS objects for repository: %v", err)
|
||||||
return repo, fmt.Errorf("StoreMissingLfsObjectsInRepository: %w", err)
|
return repo, fmt.Errorf("StoreMissingLfsObjectsInRepository: %w", err)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user