Skip to content

Commit

Permalink
repospec: support ssh urls with ssh certificates
Browse files Browse the repository at this point in the history
Organizations that use a custom SSH Certificate Authority with GitHub
Enterprise Cloud will have a host that starts with `org-12345@` instead
of `git@`. This removes the hard-coded `git@` in the repo spec parsing
for a regexp match on a valid username instead.

E.g. now it will be able to parse specs like `[email protected]:someOrg/someRepo/README.md?ref=someBranch`.

Docs [here](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-git-access-to-your-organizations-repositories/about-ssh-certificate-authorities#about-ssh-urls-with-ssh-certificates)
  • Loading branch information
mightyguava committed Sep 20, 2022
1 parent 23de149 commit f23dbf4
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 10 deletions.
33 changes: 23 additions & 10 deletions api/internal/git/repospec.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"net/url"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -195,18 +196,26 @@ func peelQuery(arg string) (string, string, time.Duration, bool) {
return parsed.Path, ref, duration, submodules
}

var userRegex = regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9-]*@`)

func parseHostSpec(n string) (string, string) {
var host string
// Start accumulating the host part.
for _, p := range []string{
// Order matters here.
"git::", "gh:", "ssh://", "https://", "http://",
"git@", "github.com:", "github.com/"} {
if len(p) < len(n) && strings.ToLower(n[:len(p)]) == p {
n = n[len(p):]
host += p
consumeHostStrings := func(parts []string) {
for _, p := range parts {
if len(p) < len(n) && strings.ToLower(n[:len(p)]) == p {
n = n[len(p):]
host += p
}
}
}
// Start accumulating the host part.
// Order matters here.
consumeHostStrings([]string{"git::", "gh:", "ssh://", "https://", "http://"})
if p := userRegex.FindString(n); p != "" {
n = n[len(p):]
host += p
}
consumeHostStrings([]string{"github.com:", "github.com/"})
if host == "git@" {
i := strings.Index(n, "/")
if i > -1 {
Expand Down Expand Up @@ -240,10 +249,14 @@ func parseHostSpec(n string) (string, string) {

func normalizeGitHostSpec(host string) string {
s := strings.ToLower(host)
m := userRegex.FindString(host)
if strings.Contains(s, "github.com") {
if strings.Contains(s, "git@") || strings.Contains(s, "ssh:") {
switch {
case m != "":
host = m + "github.com:"
case strings.Contains(s, "ssh:"):
host = "[email protected]:"
} else {
default:
host = "https://github.com/"
}
}
Expand Down
5 changes: 5 additions & 0 deletions api/internal/git/repospec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ func TestNewRepoSpecFromUrl_Permute(t *testing.T) {
{"git::https://git.example.com/", "https://git.example.com/"},
{"[email protected]:", "[email protected]:"},
{"[email protected]/", "[email protected]:"},
{"[email protected]:", "[email protected]:"},
{"[email protected]/", "[email protected]:"},
}
var orgRepos = []string{"someOrg/someRepo", "kubernetes/website"}
var pathNames = []string{"README.md", "foo/krusty.txt", ""}
Expand Down Expand Up @@ -61,6 +63,9 @@ func TestNewRepoSpecFromUrl_Permute(t *testing.T) {
rs, err := NewRepoSpecFromURL(uri)
if err != nil {
t.Errorf("problem %v", err)
if rs == nil {
rs = &RepoSpec{}
}
}
if rs.Host != hostSpec {
bad = append(bad, []string{"host", uri, rs.Host, hostSpec})
Expand Down

0 comments on commit f23dbf4

Please sign in to comment.