From 475485036a7c1d99f6ce301af7299b830371b980 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 11 Dec 2023 20:24:49 +0800 Subject: [PATCH 1/2] fix --- models/repo/repo.go | 30 +++++++++++++++----------- models/repo/repo_test.go | 46 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 12 deletions(-) diff --git a/models/repo/repo.go b/models/repo/repo.go index db3709f1e8025..80b612ea509be 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -602,25 +602,31 @@ func ComposeHTTPSCloneURL(owner, repo string) string { func ComposeSSHCloneURL(ownerName, repoName string) string { sshUser := setting.SSH.User - - // if we have a ipv6 literal we need to put brackets around it - // for the git cloning to work. sshDomain := setting.SSH.Domain - ip := net.ParseIP(setting.SSH.Domain) - if ip != nil && ip.To4() == nil { - sshDomain = "[" + setting.SSH.Domain + "]" + + // if the domain already contains a port, just use it (many users already use it this way) + if _, _, err := net.SplitHostPort(sshDomain); err == nil { + return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshDomain, url.PathEscape(ownerName), url.PathEscape(repoName)) } + // non-standard port, it must use full URI if setting.SSH.Port != 22 { - return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, - net.JoinHostPort(setting.SSH.Domain, strconv.Itoa(setting.SSH.Port)), - url.PathEscape(ownerName), - url.PathEscape(repoName)) + if strings.HasPrefix(sshDomain, "[") && strings.HasSuffix(sshDomain, "]") { + sshDomain = sshDomain[1 : len(sshDomain)-1] + } + sshHost := net.JoinHostPort(sshDomain, strconv.Itoa(setting.SSH.Port)) + return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName)) + } + + // for standard port, it can use a shorter URI (without the port) + sshHost := sshDomain + if ip := net.ParseIP(sshHost); ip != nil && ip.To4() == nil { + sshHost = "[" + sshHost + "]" // for IPv6 address, wrap it with brackets } if setting.Repository.UseCompatSSHURI { - return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshDomain, url.PathEscape(ownerName), url.PathEscape(repoName)) + return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName)) } - return fmt.Sprintf("%s@%s:%s/%s.git", sshUser, sshDomain, url.PathEscape(ownerName), url.PathEscape(repoName)) + return fmt.Sprintf("%s@%s:%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName)) } func (repo *Repository) cloneLink(isWiki bool) *CloneLink { diff --git a/models/repo/repo_test.go b/models/repo/repo_test.go index 4bbfeb634a798..11b99d42ac2a2 100644 --- a/models/repo/repo_test.go +++ b/models/repo/repo_test.go @@ -12,6 +12,8 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/markup" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" @@ -186,3 +188,47 @@ func TestGetRepositoryByURL(t *testing.T) { test(t, "try.gitea.io:user2/repo2.git") }) } + +func TestComposeSSHCloneURL(t *testing.T) { + defer test.MockVariableValue(&setting.SSH, setting.SSH)() + defer test.MockVariableValue(&setting.Repository, setting.Repository)() + + setting.SSH.User = "git" + + // test SSH_DOMAIN with port + setting.SSH.Domain = "domain:123" + setting.SSH.Port = 22 + setting.Repository.UseCompatSSHURI = false + assert.Equal(t, "ssh://git@domain:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + setting.SSH.Domain = "[::1]:123" + setting.SSH.Port = 456 + setting.Repository.UseCompatSSHURI = true + assert.Equal(t, "ssh://git@[::1]:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + + // test SSH_DOMAIN without port + setting.SSH.Domain = "domain" + setting.SSH.Port = 22 + setting.Repository.UseCompatSSHURI = false + assert.Equal(t, "git@domain:user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + setting.Repository.UseCompatSSHURI = true + assert.Equal(t, "ssh://git@domain/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + // test SSH_DOMAIN without port and use non-standard SSH port + setting.SSH.Port = 123 + setting.Repository.UseCompatSSHURI = false + assert.Equal(t, "ssh://git@domain:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + setting.Repository.UseCompatSSHURI = true + assert.Equal(t, "ssh://git@domain:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + + // test IPv6 SSH_DOMAIN without port + setting.Repository.UseCompatSSHURI = false + setting.SSH.Domain = "[::1]" + setting.SSH.Port = 22 + assert.Equal(t, "git@[::1]:user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + setting.SSH.Port = 123 + assert.Equal(t, "ssh://git@[::1]:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + setting.SSH.Domain = "::1" + setting.SSH.Port = 22 + assert.Equal(t, "git@[::1]:user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + setting.SSH.Port = 123 + assert.Equal(t, "ssh://git@[::1]:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) +} From d34ba5dc4dcfe56d25e1fb4e287bdfbc56cdf532 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 12 Dec 2023 00:57:39 +0800 Subject: [PATCH 2/2] simplify the logic, no need to introduce unnecessary SSH_DOMAIN="domain:port" support --- models/repo/repo.go | 8 -------- models/repo/repo_test.go | 21 +++------------------ 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/models/repo/repo.go b/models/repo/repo.go index 80b612ea509be..d87ddf659389c 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -604,16 +604,8 @@ func ComposeSSHCloneURL(ownerName, repoName string) string { sshUser := setting.SSH.User sshDomain := setting.SSH.Domain - // if the domain already contains a port, just use it (many users already use it this way) - if _, _, err := net.SplitHostPort(sshDomain); err == nil { - return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshDomain, url.PathEscape(ownerName), url.PathEscape(repoName)) - } - // non-standard port, it must use full URI if setting.SSH.Port != 22 { - if strings.HasPrefix(sshDomain, "[") && strings.HasSuffix(sshDomain, "]") { - sshDomain = sshDomain[1 : len(sshDomain)-1] - } sshHost := net.JoinHostPort(sshDomain, strconv.Itoa(setting.SSH.Port)) return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName)) } diff --git a/models/repo/repo_test.go b/models/repo/repo_test.go index 11b99d42ac2a2..ca9209d75153d 100644 --- a/models/repo/repo_test.go +++ b/models/repo/repo_test.go @@ -195,37 +195,22 @@ func TestComposeSSHCloneURL(t *testing.T) { setting.SSH.User = "git" - // test SSH_DOMAIN with port - setting.SSH.Domain = "domain:123" - setting.SSH.Port = 22 - setting.Repository.UseCompatSSHURI = false - assert.Equal(t, "ssh://git@domain:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) - setting.SSH.Domain = "[::1]:123" - setting.SSH.Port = 456 - setting.Repository.UseCompatSSHURI = true - assert.Equal(t, "ssh://git@[::1]:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) - - // test SSH_DOMAIN without port + // test SSH_DOMAIN setting.SSH.Domain = "domain" setting.SSH.Port = 22 setting.Repository.UseCompatSSHURI = false assert.Equal(t, "git@domain:user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) setting.Repository.UseCompatSSHURI = true assert.Equal(t, "ssh://git@domain/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) - // test SSH_DOMAIN without port and use non-standard SSH port + // test SSH_DOMAIN while use non-standard SSH port setting.SSH.Port = 123 setting.Repository.UseCompatSSHURI = false assert.Equal(t, "ssh://git@domain:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) setting.Repository.UseCompatSSHURI = true assert.Equal(t, "ssh://git@domain:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) - // test IPv6 SSH_DOMAIN without port + // test IPv6 SSH_DOMAIN setting.Repository.UseCompatSSHURI = false - setting.SSH.Domain = "[::1]" - setting.SSH.Port = 22 - assert.Equal(t, "git@[::1]:user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) - setting.SSH.Port = 123 - assert.Equal(t, "ssh://git@[::1]:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) setting.SSH.Domain = "::1" setting.SSH.Port = 22 assert.Equal(t, "git@[::1]:user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo"))