Skip to content

Commit

Permalink
Add support for localhost
Browse files Browse the repository at this point in the history
  • Loading branch information
samcoe committed Jun 22, 2022
1 parent 3caf6c4 commit 76a2603
Show file tree
Hide file tree
Showing 8 changed files with 233 additions and 11 deletions.
20 changes: 13 additions & 7 deletions internal/api/gql_client.go
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"net/http"
"strings"

"github.com/cli/go-gh/pkg/api"

Expand All @@ -23,15 +24,9 @@ type gqlClient struct {
func NewGQLClient(host string, opts *api.ClientOptions) api.GQLClient {
httpClient := NewHTTPClient(opts)

if isEnterprise(host) {
host = fmt.Sprintf("https://%s/api/graphql", host)
} else {
host = "https://api.github.com/graphql"
}

return gqlClient{
client: graphql.NewClient(host, &httpClient),
host: host,
host: gqlEndpoint(host),
httpClient: &httpClient,
}
}
Expand Down Expand Up @@ -114,3 +109,14 @@ type gqlResponse struct {
Data interface{}
Errors []api.GQLErrorItem
}

func gqlEndpoint(host string) string {
host = normalizeHostname(host)
if isEnterprise(host) {
return fmt.Sprintf("https://%s/api/graphql", host)
}
if strings.EqualFold(host, localhost) {
return fmt.Sprintf("http://api.%s/graphql", host)
}
return fmt.Sprintf("https://api.%s/graphql", host)
}
31 changes: 31 additions & 0 deletions internal/api/gql_client_test.go
Expand Up @@ -167,3 +167,34 @@ func TestGQLClientDoWithContext(t *testing.T) {
})
}
}

func TestGQLEndpoint(t *testing.T) {
tests := []struct {
name string
host string
wantEndpoint string
}{
{
name: "github",
host: "github.com",
wantEndpoint: "https://api.github.com/graphql",
},
{
name: "localhost",
host: "github.localhost",
wantEndpoint: "http://api.github.localhost/graphql",
},
{
name: "enterprise",
host: "enterprise.com",
wantEndpoint: "https://enterprise.com/api/graphql",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
endpoint := gqlEndpoint(tt.host)
assert.Equal(t, tt.wantEndpoint, endpoint)
})
}
}
16 changes: 14 additions & 2 deletions internal/api/http.go
Expand Up @@ -19,8 +19,9 @@ const (
accept = "Accept"
authorization = "Authorization"
contentType = "Content-Type"
defaultHostname = "github.com"
github = "github.com"
jsonContentType = "application/json; charset=utf-8"
localhost = "github.localhost"
modulePath = "github.com/cli/go-gh"
timeZone = "Time-Zone"
userAgent = "User-Agent"
Expand Down Expand Up @@ -127,7 +128,18 @@ func isSameDomain(requestHost, domain string) bool {
}

func isEnterprise(host string) bool {
return host != defaultHostname
return host != github && host != localhost
}

func normalizeHostname(hostname string) string {
hostname = strings.ToLower(hostname)
if strings.HasSuffix(hostname, "."+github) {
return github
}
if strings.HasSuffix(hostname, "."+localhost) {
return localhost
}
return hostname
}

type headerRoundTripper struct {
Expand Down
67 changes: 67 additions & 0 deletions internal/api/http_test.go
Expand Up @@ -121,6 +121,73 @@ func TestNewHTTPClient(t *testing.T) {
}
}

func TestIsEnterprise(t *testing.T) {
tests := []struct {
name string
host string
wantOut bool
}{
{
name: "github",
host: "github.com",
wantOut: false,
},
{
name: "localhost",
host: "github.localhost",
wantOut: false,
},
{
name: "enterprise",
host: "mygithub.com",
wantOut: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
out := isEnterprise(tt.host)
assert.Equal(t, tt.wantOut, out)
})
}
}

func TestNormalizeHostname(t *testing.T) {
tests := []struct {
name string
host string
wantHost string
}{
{
name: "github domain",
host: "test.github.com",
wantHost: "github.com",
},
{
name: "capitalized",
host: "GitHub.com",
wantHost: "github.com",
},
{
name: "localhost domain",
host: "test.github.localhost",
wantHost: "github.localhost",
},
{
name: "enterprise domain",
host: "mygithub.com",
wantHost: "mygithub.com",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
normalized := normalizeHostname(tt.host)
assert.Equal(t, tt.wantHost, normalized)
})
}
}

type tripper struct {
roundTrip func(*http.Request) (*http.Response, error)
}
Expand Down
6 changes: 5 additions & 1 deletion internal/api/rest_client.go
Expand Up @@ -119,8 +119,12 @@ func restURL(hostname string, pathOrURL string) string {
}

func restPrefix(hostname string) string {
hostname = normalizeHostname(hostname)
if isEnterprise(hostname) {
return fmt.Sprintf("https://%s/api/v3/", hostname)
}
return "https://api.github.com/"
if strings.EqualFold(hostname, localhost) {
return fmt.Sprintf("http://api.%s/", hostname)
}
return fmt.Sprintf("https://api.%s/", hostname)
}
31 changes: 31 additions & 0 deletions internal/api/rest_client_test.go
Expand Up @@ -390,6 +390,37 @@ func TestRESTClientRequestWithContext(t *testing.T) {
}
}

func TestRestPrefix(t *testing.T) {
tests := []struct {
name string
host string
wantEndpoint string
}{
{
name: "github",
host: "github.com",
wantEndpoint: "https://api.github.com/",
},
{
name: "localhost",
host: "github.localhost",
wantEndpoint: "http://api.github.localhost/",
},
{
name: "enterprise",
host: "enterprise.com",
wantEndpoint: "https://enterprise.com/api/v3/",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
endpoint := restPrefix(tt.host)
assert.Equal(t, tt.wantEndpoint, endpoint)
})
}
}

func printPendingMocks(mocks []gock.Mock) string {
paths := []string{}
for _, mock := range mocks {
Expand Down
6 changes: 5 additions & 1 deletion pkg/auth/auth.go
Expand Up @@ -21,6 +21,7 @@ const (
githubEnterpriseToken = "GITHUB_ENTERPRISE_TOKEN"
githubToken = "GITHUB_TOKEN"
hostsKey = "hosts"
localhost = "github.localhost"
oauthToken = "oauth_token"
)

Expand Down Expand Up @@ -114,13 +115,16 @@ func defaultHost(cfg *config.Config) (string, string) {
}

func isEnterprise(host string) bool {
return host != github
return host != github && host != localhost
}

func normalizeHostname(host string) string {
hostname := strings.ToLower(host)
if strings.HasSuffix(hostname, "."+github) {
return github
}
if strings.HasSuffix(hostname, "."+localhost) {
return localhost
}
return hostname
}
67 changes: 67 additions & 0 deletions pkg/auth/auth_test.go
Expand Up @@ -223,6 +223,73 @@ func TestKnownHosts(t *testing.T) {
}
}

func TestIsEnterprise(t *testing.T) {
tests := []struct {
name string
host string
wantOut bool
}{
{
name: "github",
host: "github.com",
wantOut: false,
},
{
name: "localhost",
host: "github.localhost",
wantOut: false,
},
{
name: "enterprise",
host: "mygithub.com",
wantOut: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
out := isEnterprise(tt.host)
assert.Equal(t, tt.wantOut, out)
})
}
}

func TestNormalizeHostname(t *testing.T) {
tests := []struct {
name string
host string
wantHost string
}{
{
name: "github domain",
host: "test.github.com",
wantHost: "github.com",
},
{
name: "capitalized",
host: "GitHub.com",
wantHost: "github.com",
},
{
name: "localhost domain",
host: "test.github.localhost",
wantHost: "github.localhost",
},
{
name: "enterprise domain",
host: "mygithub.com",
wantHost: "mygithub.com",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
normalized := normalizeHostname(tt.host)
assert.Equal(t, tt.wantHost, normalized)
})
}
}

func testNoHostsConfig() *config.Config {
var data = ``
return config.ReadFromString(data)
Expand Down

0 comments on commit 76a2603

Please sign in to comment.