mirror of
https://github.com/go-gitea/gitea.git
synced 2026-04-03 21:12:09 +02:00
Merge d909617bfdd046522f28d90c3938f2e89ce71cbd into 7b17234945ff3f7c6f09c54d9c4ffc93dc137212
This commit is contained in:
commit
edf6dfb717
@ -24,9 +24,9 @@ type Client interface {
|
||||
}
|
||||
|
||||
// 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" {
|
||||
return newFilesystemClient(endpoint)
|
||||
}
|
||||
return newHTTPClient(endpoint, httpTransport)
|
||||
return newHTTPClient(endpoint, httpTransport, checkRedirect)
|
||||
}
|
||||
|
||||
@ -12,10 +12,10 @@ import (
|
||||
|
||||
func TestNewClient(t *testing.T) {
|
||||
u, _ := url.Parse("file:///test")
|
||||
c := NewClient(u, nil)
|
||||
c := NewClient(u, nil, nil)
|
||||
assert.IsType(t, &FilesystemClient{}, c)
|
||||
|
||||
u, _ = url.Parse("https://test.com/lfs")
|
||||
c = NewClient(u, nil)
|
||||
c = NewClient(u, nil, nil)
|
||||
assert.IsType(t, &HTTPClient{}, c)
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ func (c *HTTPClient) BatchSize() int {
|
||||
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 {
|
||||
httpTransport = &http.Transport{
|
||||
Proxy: proxy.Proxy(),
|
||||
@ -42,7 +42,8 @@ func newHTTPClient(endpoint *url.URL, httpTransport *http.Transport) *HTTPClient
|
||||
}
|
||||
|
||||
hc := &http.Client{
|
||||
Transport: httpTransport,
|
||||
Transport: httpTransport,
|
||||
CheckRedirect: checkRedirect,
|
||||
}
|
||||
|
||||
basic := &BasicTransferAdapter{hc}
|
||||
|
||||
@ -129,7 +129,7 @@ func (g *GiteaLocalUploader) CreateRepo(ctx context.Context, repo *base.Reposito
|
||||
Wiki: opts.Wiki,
|
||||
Releases: opts.Releases, // if didn't get releases, then sync them from tags
|
||||
MirrorInterval: opts.MirrorInterval,
|
||||
}, NewMigrationHTTPTransport())
|
||||
}, NewMigrationHTTPTransport(), CheckMigrateRedirect)
|
||||
|
||||
g.sameApp = strings.HasPrefix(repo.OriginalURL, setting.AppURL)
|
||||
g.repo = r
|
||||
|
||||
@ -100,6 +100,7 @@ func NewGithubDownloaderV3(_ context.Context, baseURL, userName, password, token
|
||||
Base: NewMigrationHTTPTransport(),
|
||||
Source: oauth2.ReuseTokenSource(nil, ts),
|
||||
},
|
||||
CheckRedirect: CheckMigrateRedirect,
|
||||
}
|
||||
|
||||
downloader.addClient(client, baseURL)
|
||||
@ -111,7 +112,8 @@ func NewGithubDownloaderV3(_ context.Context, baseURL, userName, password, token
|
||||
return proxy.Proxy()(req)
|
||||
}
|
||||
client := &http.Client{
|
||||
Transport: transport,
|
||||
Transport: transport,
|
||||
CheckRedirect: CheckMigrateRedirect,
|
||||
}
|
||||
downloader.addClient(client, baseURL)
|
||||
}
|
||||
|
||||
@ -113,6 +113,7 @@ func (g *GogsDownloader) client(ctx context.Context) *gogs.Client {
|
||||
}
|
||||
return httpTransport.RoundTrip(req.WithContext(ctx))
|
||||
}),
|
||||
CheckRedirect: CheckMigrateRedirect,
|
||||
})
|
||||
return gogsClient
|
||||
}
|
||||
|
||||
@ -5,8 +5,10 @@ package migrations
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/hostmatcher"
|
||||
"code.gitea.io/gitea/modules/proxy"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
@ -15,10 +17,27 @@ import (
|
||||
// NewMigrationHTTPClient returns a HTTP client for migration
|
||||
func NewMigrationHTTPClient() *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
|
||||
func NewMigrationHTTPTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
|
||||
@ -5,12 +5,16 @@ package migrations
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
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/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@ -113,3 +117,43 @@ func TestAllowBlockList(t *testing.T) {
|
||||
// reset
|
||||
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))
|
||||
}),
|
||||
CheckRedirect: CheckMigrateRedirect,
|
||||
},
|
||||
userMap: make(map[int64]*onedevUser),
|
||||
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 {
|
||||
log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo)
|
||||
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 {
|
||||
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()
|
||||
|
||||
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 {
|
||||
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
|
||||
func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
|
||||
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) {
|
||||
if u.IsOrganization() {
|
||||
t, err := organization.OrgFromUser(u).GetOwnerTeam(ctx)
|
||||
@ -160,7 +160,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
|
||||
|
||||
if opts.LFS {
|
||||
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 {
|
||||
log.Error("Failed to store missing LFS objects for repository: %v", err)
|
||||
return repo, fmt.Errorf("StoreMissingLfsObjectsInRepository: %w", err)
|
||||
|
||||
@ -162,7 +162,7 @@ func testScheduleUpdateMirrorSync(t *testing.T) {
|
||||
}, false)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, mirrorRepo.IsMirror)
|
||||
mirrorRepo, err = repo_service.MigrateRepositoryGitData(t.Context(), user, mirrorRepo, opts, nil)
|
||||
mirrorRepo, err = repo_service.MigrateRepositoryGitData(t.Context(), user, mirrorRepo, opts, nil, nil)
|
||||
assert.NoError(t, err)
|
||||
mirrorContext := NewAPITestContext(t, user.Name, mirrorRepo.Name, auth_model.AccessTokenScopeWriteRepository)
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ func TestMirrorPull(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, mirrorRepo.IsMirror, "expected pull-mirror repo to be marked as a mirror immediately after its creation")
|
||||
|
||||
mirrorRepo, err = repo_service.MigrateRepositoryGitData(ctx, user, mirrorRepo, opts, nil)
|
||||
mirrorRepo, err = repo_service.MigrateRepositoryGitData(ctx, user, mirrorRepo, opts, nil, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// these units should have been enabled
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user