Merge pull request #414 from relaxdiego/multi-page-org
Iterate through pages returned by List Your Organizations endpoint
This commit is contained in:
commit
d75f626cdd
@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -61,36 +62,51 @@ func (p *GitHubProvider) hasOrg(accessToken string) (bool, error) {
|
||||
Login string `json:"login"`
|
||||
}
|
||||
|
||||
params := url.Values{
|
||||
"limit": {"100"},
|
||||
type orgsPage []struct {
|
||||
Login string `json:"login"`
|
||||
}
|
||||
|
||||
endpoint := &url.URL{
|
||||
Scheme: p.ValidateURL.Scheme,
|
||||
Host: p.ValidateURL.Host,
|
||||
Path: path.Join(p.ValidateURL.Path, "/user/orgs"),
|
||||
RawQuery: params.Encode(),
|
||||
}
|
||||
req, _ := http.NewRequest("GET", endpoint.String(), nil)
|
||||
req.Header.Set("Accept", "application/vnd.github.v3+json")
|
||||
req.Header.Set("Authorization", fmt.Sprintf("token %s", accessToken))
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
pn := 1
|
||||
for {
|
||||
params := url.Values{
|
||||
"limit": {"200"},
|
||||
"page": {strconv.Itoa(pn)},
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return false, fmt.Errorf(
|
||||
"got %d from %q %s", resp.StatusCode, endpoint.String(), body)
|
||||
}
|
||||
endpoint := &url.URL{
|
||||
Scheme: p.ValidateURL.Scheme,
|
||||
Host: p.ValidateURL.Host,
|
||||
Path: path.Join(p.ValidateURL.Path, "/user/orgs"),
|
||||
RawQuery: params.Encode(),
|
||||
}
|
||||
req, _ := http.NewRequest("GET", endpoint.String(), nil)
|
||||
req.Header.Set("Accept", "application/vnd.github.v3+json")
|
||||
req.Header.Set("Authorization", fmt.Sprintf("token %s", accessToken))
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(body, &orgs); err != nil {
|
||||
return false, err
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
return false, fmt.Errorf(
|
||||
"got %d from %q %s", resp.StatusCode, endpoint.String(), body)
|
||||
}
|
||||
|
||||
var op orgsPage
|
||||
if err := json.Unmarshal(body, &op); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if len(op) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
orgs = append(orgs, op...)
|
||||
pn += 1
|
||||
}
|
||||
|
||||
var presentOrgs []string
|
||||
@ -118,7 +134,7 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) {
|
||||
}
|
||||
|
||||
params := url.Values{
|
||||
"limit": {"100"},
|
||||
"limit": {"200"},
|
||||
}
|
||||
|
||||
endpoint := &url.URL{
|
||||
|
@ -27,23 +27,32 @@ func testGitHubProvider(hostname string) *GitHubProvider {
|
||||
return p
|
||||
}
|
||||
|
||||
func testGitHubBackend(payload string) *httptest.Server {
|
||||
pathToQueryMap := map[string]string{
|
||||
"/user": "",
|
||||
"/user/emails": "",
|
||||
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 url.RawQuery != query {
|
||||
} else if !validQuery {
|
||||
w.WriteHeader(404)
|
||||
} else {
|
||||
w.WriteHeader(200)
|
||||
w.Write([]byte(payload))
|
||||
w.Write([]byte(payload[index]))
|
||||
}
|
||||
}))
|
||||
}
|
||||
@ -89,7 +98,7 @@ func TestGitHubProviderOverrides(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGitHubProviderGetEmailAddress(t *testing.T) {
|
||||
b := testGitHubBackend(`[ {"email": "michael.bland@gsa.gov", "primary": true} ]`)
|
||||
b := testGitHubBackend([]string{`[ {"email": "michael.bland@gsa.gov", "primary": true} ]`})
|
||||
defer b.Close()
|
||||
|
||||
bURL, _ := url.Parse(b.URL)
|
||||
@ -101,10 +110,28 @@ func TestGitHubProviderGetEmailAddress(t *testing.T) {
|
||||
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("unused payload")
|
||||
b := testGitHubBackend([]string{"unused payload"})
|
||||
defer b.Close()
|
||||
|
||||
bURL, _ := url.Parse(b.URL)
|
||||
@ -120,7 +147,7 @@ func TestGitHubProviderGetEmailAddressFailedRequest(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGitHubProviderGetEmailAddressEmailNotPresentInPayload(t *testing.T) {
|
||||
b := testGitHubBackend("{\"foo\": \"bar\"}")
|
||||
b := testGitHubBackend([]string{"{\"foo\": \"bar\"}"})
|
||||
defer b.Close()
|
||||
|
||||
bURL, _ := url.Parse(b.URL)
|
||||
@ -133,7 +160,7 @@ func TestGitHubProviderGetEmailAddressEmailNotPresentInPayload(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGitHubProviderGetUserName(t *testing.T) {
|
||||
b := testGitHubBackend(`{"email": "michael.bland@gsa.gov", "login": "mbland"}`)
|
||||
b := testGitHubBackend([]string{`{"email": "michael.bland@gsa.gov", "login": "mbland"}`})
|
||||
defer b.Close()
|
||||
|
||||
bURL, _ := url.Parse(b.URL)
|
||||
|
Loading…
Reference in New Issue
Block a user