Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions admin/server/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ func (s *Server) GetGithubUserStatus(ctx context.Context, req *adminv1.GetGithub

client := github.NewTokenClient(ctx, token)
// List all the private organizations for the authenticated user
orgs, _, err := client.Organizations.List(ctx, "", nil)
orgs, err := listOrganizations(ctx, client, "")
if err != nil {
return nil, fmt.Errorf("failed to get user organizations: %w", err)
}
// List all the public organizations for the authenticated user
publicOrgs, _, err := client.Organizations.List(ctx, user.GithubUsername, nil)
publicOrgs, err := listOrganizations(ctx, client, user.GithubUsername)
if err != nil {
return nil, fmt.Errorf("failed to get user organizations: %w", err)
}
Expand Down Expand Up @@ -1248,6 +1248,26 @@ func (s *Server) githubAppInstallationURL(state githubConnectState) (string, err
return urlutil.MustWithQuery(res, map[string]string{"state": string(stateJSON)}), nil
}

// listOrganizations returns all organizations visible for the given user,
// following pagination. An empty user lists the organizations of the
// authenticated user.
func listOrganizations(ctx context.Context, client *github.Client, user string) ([]*github.Organization, error) {
orgs := make([]*github.Organization, 0)
opts := &github.ListOptions{PerPage: 100}
for {
page, resp, err := client.Organizations.List(ctx, user, opts)
if err != nil {
return nil, err
}
orgs = append(orgs, page...)
if resp.NextPage == 0 {
break
}
opts.Page = resp.NextPage
}
return orgs, nil
}

func fromStringPtr(s *string) string {
if s == nil {
return ""
Expand Down
33 changes: 33 additions & 0 deletions admin/server/github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,47 @@ package server

import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"os"
"os/exec"
"path/filepath"
"testing"

"github.com/google/go-github/v71/github"
"github.com/stretchr/testify/require"
)

func TestListOrganizationsPagination(t *testing.T) {
var srv *httptest.Server
srv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if r.URL.Query().Get("page") == "2" {
_, _ = w.Write([]byte(`[{"login":"org3"}]`))
return
}
w.Header().Set("Link", fmt.Sprintf(`<%s%s?page=2>; rel="next"`, srv.URL, r.URL.Path))
_, _ = w.Write([]byte(`[{"login":"org1"},{"login":"org2"}]`))
}))
defer srv.Close()

client := github.NewClient(nil)
base, err := url.Parse(srv.URL + "/")
require.NoError(t, err)
client.BaseURL = base
client.UploadURL = base

// Organizations of the authenticated user.
orgs, err := listOrganizations(context.Background(), client, "")
require.NoError(t, err)
require.Len(t, orgs, 3)
require.Equal(t, "org1", orgs[0].GetLogin())
require.Equal(t, "org2", orgs[1].GetLogin())
require.Equal(t, "org3", orgs[2].GetLogin())
}

func TestMirrorGitRepo(t *testing.T) {
src := setupMirrorSourceRepo(t)
dest := t.TempDir()
Expand Down
Loading