Skip to content

Commit

Permalink
Support SSH for go get (#24664)
Browse files Browse the repository at this point in the history
fix #12192 Support SSH for go get

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: mfk <mfk@hengwei.com.cn>
Co-authored-by: silverwind <me@silverwind.io>
  • Loading branch information
5 people authored May 12, 2023
1 parent 4980813 commit 4b80813
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 15 deletions.
3 changes: 3 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,9 @@ ROUTER = console
;; Force ssh:// clone url instead of scp-style uri when default SSH port is used
;USE_COMPAT_SSH_URI = false
;;
;; Value for the "go get" request returns the repository url as https or ssh, default is https
;GO_GET_CLONE_URL_PROTOCOL = https
;;
;; Close issues as long as a commit on any branch marks it as fixed
;; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects, repo.packages, repo.actions.
;DISABLED_REPO_UNITS =
Expand Down
2 changes: 2 additions & 0 deletions docs/content/doc/administration/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ In addition there is _`StaticRootPath`_ which can be set as a built-in at build
HTTP protocol.
- `USE_COMPAT_SSH_URI`: **false**: Force ssh:// clone url instead of scp-style uri when
default SSH port is used.
- `GO_GET_CLONE_URL_PROTOCOL`: **https**: Value for the "go get" request returns the repository url as https or ssh
default is https.
- `ACCESS_CONTROL_ALLOW_ORIGIN`: **\<empty\>**: Value for Access-Control-Allow-Origin header,
default is not to present. **WARNING**: This maybe harmful to you website if you do not
give it a right value.
Expand Down
32 changes: 19 additions & 13 deletions models/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,16 +547,9 @@ func ComposeHTTPSCloneURL(owner, repo string) string {
return fmt.Sprintf("%s%s/%s.git", setting.AppURL, url.PathEscape(owner), url.PathEscape(repo))
}

func (repo *Repository) cloneLink(isWiki bool) *CloneLink {
repoName := repo.Name
if isWiki {
repoName += ".wiki"
}

func ComposeSSHCloneURL(ownerName, repoName string) string {
sshUser := setting.SSH.User

cl := new(CloneLink)

// if we have a ipv6 literal we need to put brackets around it
// for the git cloning to work.
sshDomain := setting.SSH.Domain
Expand All @@ -566,12 +559,25 @@ func (repo *Repository) cloneLink(isWiki bool) *CloneLink {
}

if setting.SSH.Port != 22 {
cl.SSH = fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, net.JoinHostPort(setting.SSH.Domain, strconv.Itoa(setting.SSH.Port)), url.PathEscape(repo.OwnerName), url.PathEscape(repoName))
} else if setting.Repository.UseCompatSSHURI {
cl.SSH = fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshDomain, url.PathEscape(repo.OwnerName), url.PathEscape(repoName))
} else {
cl.SSH = fmt.Sprintf("%s@%s:%s/%s.git", sshUser, sshDomain, url.PathEscape(repo.OwnerName), url.PathEscape(repoName))
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 setting.Repository.UseCompatSSHURI {
return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshDomain, url.PathEscape(ownerName), url.PathEscape(repoName))
}
return fmt.Sprintf("%s@%s:%s/%s.git", sshUser, sshDomain, url.PathEscape(ownerName), url.PathEscape(repoName))
}

func (repo *Repository) cloneLink(isWiki bool) *CloneLink {
repoName := repo.Name
if isWiki {
repoName += ".wiki"
}

cl := new(CloneLink)
cl.SSH = ComposeSSHCloneURL(repo.OwnerName, repoName)
cl.HTTPS = ComposeHTTPSCloneURL(repo.OwnerName, repoName)
return cl
}
Expand Down
9 changes: 8 additions & 1 deletion modules/context/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,14 @@ func EarlyResponseForGoGetMeta(ctx *Context) {
ctx.PlainText(http.StatusBadRequest, "invalid repository path")
return
}
goImportContent := fmt.Sprintf("%s git %s", ComposeGoGetImport(username, reponame), repo_model.ComposeHTTPSCloneURL(username, reponame))

var cloneURL string
if setting.Repository.GoGetCloneURLProtocol == "ssh" {
cloneURL = repo_model.ComposeSSHCloneURL(username, reponame)
} else {
cloneURL = repo_model.ComposeHTTPSCloneURL(username, reponame)
}
goImportContent := fmt.Sprintf("%s git %s", ComposeGoGetImport(username, reponame), cloneURL)
htmlMeta := fmt.Sprintf(`<meta name="go-import" content="%s">`, html.EscapeString(goImportContent))
ctx.PlainText(http.StatusOK, htmlMeta)
}
Expand Down
2 changes: 2 additions & 0 deletions modules/setting/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ var (
DisableHTTPGit bool
AccessControlAllowOrigin string
UseCompatSSHURI bool
GoGetCloneURLProtocol string
DefaultCloseIssuesViaCommitsInAnyBranch bool
EnablePushCreateUser bool
EnablePushCreateOrg bool
Expand Down Expand Up @@ -273,6 +274,7 @@ func loadRepositoryFrom(rootCfg ConfigProvider) {
sec := rootCfg.Section("repository")
Repository.DisableHTTPGit = sec.Key("DISABLE_HTTP_GIT").MustBool()
Repository.UseCompatSSHURI = sec.Key("USE_COMPAT_SSH_URI").MustBool()
Repository.GoGetCloneURLProtocol = sec.Key("GO_GET_CLONE_URL_PROTOCOL").MustString("https")
Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1)
Repository.DefaultBranch = sec.Key("DEFAULT_BRANCH").MustString(Repository.DefaultBranch)
RepoRootPath = sec.Key("ROOT").MustString(path.Join(AppDataPath, "gitea-repositories"))
Expand Down
9 changes: 8 additions & 1 deletion routers/web/goget.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,14 @@ func goGet(ctx *context.Context) {
}

goGetImport := context.ComposeGoGetImport(ownerName, trimmedRepoName)
goImportContent := fmt.Sprintf("%s git %s", goGetImport, repo_model.ComposeHTTPSCloneURL(ownerName, repoName) /*CloneLink*/)

var cloneURL string
if setting.Repository.GoGetCloneURLProtocol == "ssh" {
cloneURL = repo_model.ComposeSSHCloneURL(ownerName, repoName)
} else {
cloneURL = repo_model.ComposeHTTPSCloneURL(ownerName, repoName)
}
goImportContent := fmt.Sprintf("%s git %s", goGetImport, cloneURL /*CloneLink*/)
goSourceContent := fmt.Sprintf("%s _ %s %s", goGetImport, prefix+"{/dir}" /*GoDocDirectory*/, prefix+"{/dir}/{file}#L{line}" /*GoDocFile*/)
goGetCli := fmt.Sprintf("go get %s%s", insecure, goGetImport)

Expand Down
26 changes: 26 additions & 0 deletions tests/integration/goget_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,29 @@ func TestGoGet(t *testing.T) {

assert.Equal(t, expected, resp.Body.String())
}

func TestGoGetForSSH(t *testing.T) {
defer tests.PrepareTestEnv(t)()

old := setting.Repository.GoGetCloneURLProtocol
defer func() {
setting.Repository.GoGetCloneURLProtocol = old
}()
setting.Repository.GoGetCloneURLProtocol = "ssh"

req := NewRequest(t, "GET", "/blah/glah/plah?go-get=1")
resp := MakeRequest(t, req, http.StatusOK)

expected := fmt.Sprintf(`<!doctype html>
<html>
<head>
<meta name="go-import" content="%[1]s:%[2]s/blah/glah git ssh://git@%[4]s:%[5]d/blah/glah.git">
<meta name="go-source" content="%[1]s:%[2]s/blah/glah _ %[3]sblah/glah/src/branch/master{/dir} %[3]sblah/glah/src/branch/master{/dir}/{file}#L{line}">
</head>
<body>
go get --insecure %[1]s:%[2]s/blah/glah
</body>
</html>`, setting.Domain, setting.HTTPPort, setting.AppURL, setting.SSH.Domain, setting.SSH.Port)

assert.Equal(t, expected, resp.Body.String())
}

0 comments on commit 4b80813

Please sign in to comment.