oauth2_proxy/providers/github_test.go
Mark Maglana 882fcf0a01 providers: iterate across all pages from /user/orgs github endpoint.
For some GHE instances where a user can have more than 100
organizations, traversing the other pages is important otherwise
oauth2_proxy will consider the user unauthorized. This change traverses
the list returned by the API to avoid that.

Update github provider tests to include this case.
2017-12-04 15:51:48 -05:00

174 lines
4.9 KiB
Go

package providers
import (
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/stretchr/testify/assert"
)
func testGitHubProvider(hostname string) *GitHubProvider {
p := NewGitHubProvider(
&ProviderData{
ProviderName: "",
LoginURL: &url.URL{},
RedeemURL: &url.URL{},
ProfileURL: &url.URL{},
ValidateURL: &url.URL{},
Scope: ""})
if hostname != "" {
updateURL(p.Data().LoginURL, hostname)
updateURL(p.Data().RedeemURL, hostname)
updateURL(p.Data().ProfileURL, hostname)
updateURL(p.Data().ValidateURL, hostname)
}
return p
}
func testGitHubBackend(payload []string) *httptest.Server {
pathToQueryMap := map[string][]string{
"/user": []string{""},
"/user/emails": []string{""},
"/user/orgs": []string{"limit=200&page=1", "limit=200&page=2", "limit=200&page=3"},
}
return httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
url := r.URL
query, ok := pathToQueryMap[url.Path]
validQuery := false
index := 0
for i, q := range query {
if q == url.RawQuery {
validQuery = true
index = i
}
}
if !ok {
w.WriteHeader(404)
} else if !validQuery {
w.WriteHeader(404)
} else {
w.WriteHeader(200)
w.Write([]byte(payload[index]))
}
}))
}
func TestGitHubProviderDefaults(t *testing.T) {
p := testGitHubProvider("")
assert.NotEqual(t, nil, p)
assert.Equal(t, "GitHub", p.Data().ProviderName)
assert.Equal(t, "https://github.com/login/oauth/authorize",
p.Data().LoginURL.String())
assert.Equal(t, "https://github.com/login/oauth/access_token",
p.Data().RedeemURL.String())
assert.Equal(t, "https://api.github.com/",
p.Data().ValidateURL.String())
assert.Equal(t, "user:email", p.Data().Scope)
}
func TestGitHubProviderOverrides(t *testing.T) {
p := NewGitHubProvider(
&ProviderData{
LoginURL: &url.URL{
Scheme: "https",
Host: "example.com",
Path: "/login/oauth/authorize"},
RedeemURL: &url.URL{
Scheme: "https",
Host: "example.com",
Path: "/login/oauth/access_token"},
ValidateURL: &url.URL{
Scheme: "https",
Host: "api.example.com",
Path: "/"},
Scope: "profile"})
assert.NotEqual(t, nil, p)
assert.Equal(t, "GitHub", p.Data().ProviderName)
assert.Equal(t, "https://example.com/login/oauth/authorize",
p.Data().LoginURL.String())
assert.Equal(t, "https://example.com/login/oauth/access_token",
p.Data().RedeemURL.String())
assert.Equal(t, "https://api.example.com/",
p.Data().ValidateURL.String())
assert.Equal(t, "profile", p.Data().Scope)
}
func TestGitHubProviderGetEmailAddress(t *testing.T) {
b := testGitHubBackend([]string{`[ {"email": "michael.bland@gsa.gov", "primary": true} ]`})
defer b.Close()
bURL, _ := url.Parse(b.URL)
p := testGitHubProvider(bURL.Host)
session := &SessionState{AccessToken: "imaginary_access_token"}
email, err := p.GetEmailAddress(session)
assert.Equal(t, nil, err)
assert.Equal(t, "michael.bland@gsa.gov", email)
}
func TestGitHubProviderGetEmailAddressWithOrg(t *testing.T) {
b := testGitHubBackend([]string{
`[ {"email": "michael.bland@gsa.gov", "primary": true, "login":"testorg"} ]`,
`[ {"email": "michael.bland1@gsa.gov", "primary": true, "login":"testorg1"} ]`,
`[ ]`,
})
defer b.Close()
bURL, _ := url.Parse(b.URL)
p := testGitHubProvider(bURL.Host)
p.Org = "testorg1"
session := &SessionState{AccessToken: "imaginary_access_token"}
email, err := p.GetEmailAddress(session)
assert.Equal(t, nil, err)
assert.Equal(t, "michael.bland@gsa.gov", email)
}
// Note that trying to trigger the "failed building request" case is not
// practical, since the only way it can fail is if the URL fails to parse.
func TestGitHubProviderGetEmailAddressFailedRequest(t *testing.T) {
b := testGitHubBackend([]string{"unused payload"})
defer b.Close()
bURL, _ := url.Parse(b.URL)
p := testGitHubProvider(bURL.Host)
// We'll trigger a request failure by using an unexpected access
// token. Alternatively, we could allow the parsing of the payload as
// JSON to fail.
session := &SessionState{AccessToken: "unexpected_access_token"}
email, err := p.GetEmailAddress(session)
assert.NotEqual(t, nil, err)
assert.Equal(t, "", email)
}
func TestGitHubProviderGetEmailAddressEmailNotPresentInPayload(t *testing.T) {
b := testGitHubBackend([]string{"{\"foo\": \"bar\"}"})
defer b.Close()
bURL, _ := url.Parse(b.URL)
p := testGitHubProvider(bURL.Host)
session := &SessionState{AccessToken: "imaginary_access_token"}
email, err := p.GetEmailAddress(session)
assert.NotEqual(t, nil, err)
assert.Equal(t, "", email)
}
func TestGitHubProviderGetUserName(t *testing.T) {
b := testGitHubBackend([]string{`{"email": "michael.bland@gsa.gov", "login": "mbland"}`})
defer b.Close()
bURL, _ := url.Parse(b.URL)
p := testGitHubProvider(bURL.Host)
session := &SessionState{AccessToken: "imaginary_access_token"}
email, err := p.GetUserName(session)
assert.Equal(t, nil, err)
assert.Equal(t, "mbland", email)
}