Refactor SSH clone URL generation code (#28421)

Refactor the code and add tests, keep the old logic.
This commit is contained in:
wxiaoguang 2023-12-15 14:18:12 +08:00 committed by GitHub
parent 6632d1497c
commit 4f04ab2586
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 13 deletions

View file

@ -606,25 +606,23 @@ func ComposeHTTPSCloneURL(owner, repo string) string {
func ComposeSSHCloneURL(ownerName, repoName string) string { func ComposeSSHCloneURL(ownerName, repoName string) string {
sshUser := setting.SSH.User 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 sshDomain := setting.SSH.Domain
ip := net.ParseIP(setting.SSH.Domain)
if ip != nil && ip.To4() == nil { // non-standard port, it must use full URI
sshDomain = "[" + setting.SSH.Domain + "]" if setting.SSH.Port != 22 {
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))
} }
if setting.SSH.Port != 22 { // for standard port, it can use a shorter URI (without the port)
return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshHost := sshDomain
net.JoinHostPort(setting.SSH.Domain, strconv.Itoa(setting.SSH.Port)), if ip := net.ParseIP(sshHost); ip != nil && ip.To4() == nil {
url.PathEscape(ownerName), sshHost = "[" + sshHost + "]" // for IPv6 address, wrap it with brackets
url.PathEscape(repoName))
} }
if setting.Repository.UseCompatSSHURI { 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 { func (repo *Repository) cloneLink(isWiki bool) *CloneLink {

View file

@ -12,6 +12,8 @@ import (
"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/markup" "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -186,3 +188,32 @@ func TestGetRepositoryByURL(t *testing.T) {
test(t, "try.gitea.io:user2/repo2.git") 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
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 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
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"))
}