diff --git a/providers/github.go b/providers/github.go index 26526ce76..22cea6664 100644 --- a/providers/github.go +++ b/providers/github.go @@ -8,6 +8,7 @@ import ( "net/http" "net/url" "path" + "regexp" "strconv" "strings" ) @@ -69,7 +70,7 @@ func (p *GitHubProvider) hasOrg(accessToken string) (bool, error) { pn := 1 for { params := url.Values{ - "limit": {"200"}, + "limit": {"100"}, "page": {strconv.Itoa(pn)}, } @@ -134,7 +135,7 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) { } params := url.Values{ - "limit": {"200"}, + "limit": {"100"}, } endpoint := &url.URL{ @@ -143,45 +144,58 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) { Path: path.Join(p.ValidateURL.Path, "/user/teams"), 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 - } - - 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) - } - - if err := json.Unmarshal(body, &teams); err != nil { - return false, fmt.Errorf("%s unmarshaling %s", err, body) - } + team_url := endpoint.String() + pattern := regexp.MustCompile(`<([^>]+)>; rel="next"`) var hasOrg bool presentOrgs := make(map[string]bool) var presentTeams []string - for _, team := range teams { - presentOrgs[team.Org.Login] = true - if p.Org == team.Org.Login { - hasOrg = true - ts := strings.Split(p.Team, ",") - for _, t := range ts { - if t == team.Slug { - log.Printf("Found Github Organization:%q Team:%q (Name:%q)", team.Org.Login, team.Slug, team.Name) - return true, nil + for { + req, _ := http.NewRequest("GET", team_url, nil) + req.Header.Set("Accept", "application/vnd.github.hellcat-preview+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) + 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) + } + + if err := json.Unmarshal(body, &teams); err != nil { + return false, fmt.Errorf("%s unmarshaling %s", err, body) + } + + for _, team := range teams { + presentOrgs[team.Org.Login] = true + if p.Org == team.Org.Login { + hasOrg = true + ts := strings.Split(p.Team, ",") + for _, t := range ts { + if t == team.Slug { + log.Printf("Found Github Organization:%q Team:%q (Name:%q)", + team.Org.Login, team.Slug, team.Name) + return true, nil + } } + presentTeams = append(presentTeams, team.Slug) } - presentTeams = append(presentTeams, team.Slug) } + + matches := pattern.FindStringSubmatch(resp.Header["Link"][0]) + if len(matches) == 0 { + break + } + team_url = matches[1] } + if hasOrg { log.Printf("Missing Team:%q from Org:%q in teams: %v", p.Team, p.Org, presentTeams) } else { diff --git a/providers/github_test.go b/providers/github_test.go index 481018258..d1e4477fd 100644 --- a/providers/github_test.go +++ b/providers/github_test.go @@ -31,7 +31,7 @@ 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"}, + "/user/orgs": []string{"limit=100&page=1", "limit=100&page=2", "limit=100&page=3"}, } return httptest.NewServer(http.HandlerFunc(