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/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"path" | 	"path" | ||||||
|  | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -61,36 +62,51 @@ func (p *GitHubProvider) hasOrg(accessToken string) (bool, error) { | ||||||
| 		Login string `json:"login"` | 		Login string `json:"login"` | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	params := url.Values{ | 	type orgsPage []struct { | ||||||
| 		"limit": {"100"}, | 		Login string `json:"login"` | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	endpoint := &url.URL{ | 	pn := 1 | ||||||
| 		Scheme:   p.ValidateURL.Scheme, | 	for { | ||||||
| 		Host:     p.ValidateURL.Host, | 		params := url.Values{ | ||||||
| 		Path:     path.Join(p.ValidateURL.Path, "/user/orgs"), | 			"limit": {"200"}, | ||||||
| 		RawQuery: params.Encode(), | 			"page":  {strconv.Itoa(pn)}, | ||||||
| 	} | 		} | ||||||
| 	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 |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	body, err := ioutil.ReadAll(resp.Body) | 		endpoint := &url.URL{ | ||||||
| 	resp.Body.Close() | 			Scheme:   p.ValidateURL.Scheme, | ||||||
| 	if err != nil { | 			Host:     p.ValidateURL.Host, | ||||||
| 		return false, err | 			Path:     path.Join(p.ValidateURL.Path, "/user/orgs"), | ||||||
| 	} | 			RawQuery: params.Encode(), | ||||||
| 	if resp.StatusCode != 200 { | 		} | ||||||
| 		return false, fmt.Errorf( | 		req, _ := http.NewRequest("GET", endpoint.String(), nil) | ||||||
| 			"got %d from %q %s", resp.StatusCode, endpoint.String(), body) | 		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 { | 		body, err := ioutil.ReadAll(resp.Body) | ||||||
| 		return false, err | 		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 | 	var presentOrgs []string | ||||||
|  | @ -118,7 +134,7 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	params := url.Values{ | 	params := url.Values{ | ||||||
| 		"limit": {"100"}, | 		"limit": {"200"}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	endpoint := &url.URL{ | 	endpoint := &url.URL{ | ||||||
|  |  | ||||||
|  | @ -27,23 +27,32 @@ func testGitHubProvider(hostname string) *GitHubProvider { | ||||||
| 	return p | 	return p | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func testGitHubBackend(payload string) *httptest.Server { | func testGitHubBackend(payload []string) *httptest.Server { | ||||||
| 	pathToQueryMap := map[string]string{ | 	pathToQueryMap := map[string][]string{ | ||||||
| 		"/user":        "", | 		"/user":        []string{""}, | ||||||
| 		"/user/emails": "", | 		"/user/emails": []string{""}, | ||||||
|  | 		"/user/orgs":   []string{"limit=200&page=1", "limit=200&page=2", "limit=200&page=3"}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return httptest.NewServer(http.HandlerFunc( | 	return httptest.NewServer(http.HandlerFunc( | ||||||
| 		func(w http.ResponseWriter, r *http.Request) { | 		func(w http.ResponseWriter, r *http.Request) { | ||||||
| 			url := r.URL | 			url := r.URL | ||||||
| 			query, ok := pathToQueryMap[url.Path] | 			query, ok := pathToQueryMap[url.Path] | ||||||
|  | 			validQuery := false | ||||||
|  | 			index := 0 | ||||||
|  | 			for i, q := range query { | ||||||
|  | 				if q == url.RawQuery { | ||||||
|  | 					validQuery = true | ||||||
|  | 					index = i | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 			if !ok { | 			if !ok { | ||||||
| 				w.WriteHeader(404) | 				w.WriteHeader(404) | ||||||
| 			} else if url.RawQuery != query { | 			} else if !validQuery { | ||||||
| 				w.WriteHeader(404) | 				w.WriteHeader(404) | ||||||
| 			} else { | 			} else { | ||||||
| 				w.WriteHeader(200) | 				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) { | 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() | 	defer b.Close() | ||||||
| 
 | 
 | ||||||
| 	bURL, _ := url.Parse(b.URL) | 	bURL, _ := url.Parse(b.URL) | ||||||
|  | @ -101,10 +110,28 @@ func TestGitHubProviderGetEmailAddress(t *testing.T) { | ||||||
| 	assert.Equal(t, "michael.bland@gsa.gov", email) | 	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
 | // 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.
 | // practical, since the only way it can fail is if the URL fails to parse.
 | ||||||
| func TestGitHubProviderGetEmailAddressFailedRequest(t *testing.T) { | func TestGitHubProviderGetEmailAddressFailedRequest(t *testing.T) { | ||||||
| 	b := testGitHubBackend("unused payload") | 	b := testGitHubBackend([]string{"unused payload"}) | ||||||
| 	defer b.Close() | 	defer b.Close() | ||||||
| 
 | 
 | ||||||
| 	bURL, _ := url.Parse(b.URL) | 	bURL, _ := url.Parse(b.URL) | ||||||
|  | @ -120,7 +147,7 @@ func TestGitHubProviderGetEmailAddressFailedRequest(t *testing.T) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGitHubProviderGetEmailAddressEmailNotPresentInPayload(t *testing.T) { | func TestGitHubProviderGetEmailAddressEmailNotPresentInPayload(t *testing.T) { | ||||||
| 	b := testGitHubBackend("{\"foo\": \"bar\"}") | 	b := testGitHubBackend([]string{"{\"foo\": \"bar\"}"}) | ||||||
| 	defer b.Close() | 	defer b.Close() | ||||||
| 
 | 
 | ||||||
| 	bURL, _ := url.Parse(b.URL) | 	bURL, _ := url.Parse(b.URL) | ||||||
|  | @ -133,7 +160,7 @@ func TestGitHubProviderGetEmailAddressEmailNotPresentInPayload(t *testing.T) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGitHubProviderGetUserName(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() | 	defer b.Close() | ||||||
| 
 | 
 | ||||||
| 	bURL, _ := url.Parse(b.URL) | 	bURL, _ := url.Parse(b.URL) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue