mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-05-02 22:06:07 +00:00
Make github org comparison case-insensitive, but return original case
Co-authored-by: Joshua Casey <joshuatcasey@gmail.com>
This commit is contained in:
committed by
Joshua Casey
parent
8923704f3c
commit
8f8db3f542
@@ -16,6 +16,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
|
||||
"go.pinniped.dev/internal/plog"
|
||||
"go.pinniped.dev/internal/setutil"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -36,8 +37,8 @@ type TeamInfo struct {
|
||||
|
||||
type GitHubInterface interface {
|
||||
GetUserInfo(ctx context.Context) (*UserInfo, error)
|
||||
GetOrgMembership(ctx context.Context) (sets.Set[string], error)
|
||||
GetTeamMembership(ctx context.Context, allowedOrganizations sets.Set[string]) ([]TeamInfo, error)
|
||||
GetOrgMembership(ctx context.Context) ([]string, error)
|
||||
GetTeamMembership(ctx context.Context, allowedOrganizations *setutil.CaseInsensitiveSet) ([]TeamInfo, error)
|
||||
}
|
||||
|
||||
type githubClient struct {
|
||||
@@ -107,7 +108,7 @@ func (g *githubClient) GetUserInfo(ctx context.Context) (*UserInfo, error) {
|
||||
}
|
||||
|
||||
// GetOrgMembership returns an array of the "Login" attributes for all organizations to which the authenticated user belongs.
|
||||
func (g *githubClient) GetOrgMembership(ctx context.Context) (sets.Set[string], error) {
|
||||
func (g *githubClient) GetOrgMembership(ctx context.Context) ([]string, error) {
|
||||
const errorPrefix = "error fetching organizations for authenticated user"
|
||||
|
||||
organizationLogins := sets.New[string]()
|
||||
@@ -135,11 +136,11 @@ func (g *githubClient) GetOrgMembership(ctx context.Context) (sets.Set[string],
|
||||
}
|
||||
|
||||
plog.Trace("calculated response from GitHub org membership endpoint", "orgs", organizationLogins.UnsortedList())
|
||||
return organizationLogins, nil
|
||||
return organizationLogins.UnsortedList(), nil
|
||||
}
|
||||
|
||||
func isOrgAllowed(allowedOrganizations sets.Set[string], login string) bool {
|
||||
return len(allowedOrganizations) == 0 || allowedOrganizations.Has(login)
|
||||
func isOrgAllowed(allowedOrganizations *setutil.CaseInsensitiveSet, login string) bool {
|
||||
return allowedOrganizations.Empty() || allowedOrganizations.ContainsIgnoringCase(login)
|
||||
}
|
||||
|
||||
func buildAndValidateParentTeam(githubTeam *github.Team, organizationLogin string) (*TeamInfo, error) {
|
||||
@@ -176,7 +177,7 @@ func buildTeam(githubTeam *github.Team, organizationLogin string) (*TeamInfo, er
|
||||
// GetTeamMembership returns a description of each team to which the authenticated user belongs.
|
||||
// If allowedOrganizations is not empty, will filter the results to only those teams which belong to the allowed organizations.
|
||||
// Parent teams will also be returned.
|
||||
func (g *githubClient) GetTeamMembership(ctx context.Context, allowedOrganizations sets.Set[string]) ([]TeamInfo, error) {
|
||||
func (g *githubClient) GetTeamMembership(ctx context.Context, allowedOrganizations *setutil.CaseInsensitiveSet) ([]TeamInfo, error) {
|
||||
const errorPrefix = "error fetching team membership for authenticated user"
|
||||
teamInfos := sets.New[TeamInfo]()
|
||||
|
||||
|
||||
@@ -12,10 +12,10 @@ import (
|
||||
"github.com/google/go-github/v62/github"
|
||||
"github.com/migueleliasweb/go-github-mock/src/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/util/cert"
|
||||
|
||||
"go.pinniped.dev/internal/net/phttp"
|
||||
"go.pinniped.dev/internal/setutil"
|
||||
"go.pinniped.dev/internal/testutil/tlsserver"
|
||||
)
|
||||
|
||||
@@ -380,8 +380,7 @@ func TestGetOrgMembership(t *testing.T) {
|
||||
}
|
||||
|
||||
require.NotNil(t, actual)
|
||||
require.Equal(t, len(actual), len(test.wantOrgs))
|
||||
require.True(t, actual.HasAll(test.wantOrgs...))
|
||||
require.ElementsMatch(t, test.wantOrgs, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -394,7 +393,7 @@ func TestGetTeamMembership(t *testing.T) {
|
||||
httpClient *http.Client
|
||||
token string
|
||||
ctx context.Context
|
||||
allowedOrganizations []string
|
||||
allowedOrganizations *setutil.CaseInsensitiveSet
|
||||
wantErr string
|
||||
wantTeams []TeamInfo
|
||||
}{
|
||||
@@ -436,7 +435,7 @@ func TestGetTeamMembership(t *testing.T) {
|
||||
),
|
||||
),
|
||||
token: "some-token",
|
||||
allowedOrganizations: []string{"alpha", "beta"},
|
||||
allowedOrganizations: setutil.NewCaseInsensitiveSet("alpha", "beta"),
|
||||
wantTeams: []TeamInfo{
|
||||
{
|
||||
Name: "orgAlpha-team1-name",
|
||||
@@ -461,7 +460,7 @@ func TestGetTeamMembership(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "filters by allowedOrganizations",
|
||||
name: "filters by allowedOrganizations in a case-insensitive way, but preserves case as returned by GitHub API in the result",
|
||||
httpClient: mock.NewMockedHTTPClient(
|
||||
mock.WithRequestMatch(
|
||||
mock.GetUserTeams,
|
||||
@@ -470,38 +469,38 @@ func TestGetTeamMembership(t *testing.T) {
|
||||
Name: github.String("team1-name"),
|
||||
Slug: github.String("team1-slug"),
|
||||
Organization: &github.Organization{
|
||||
Login: github.String("alpha"),
|
||||
Login: github.String("alPhA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: github.String("team2-name"),
|
||||
Slug: github.String("team2-slug"),
|
||||
Organization: &github.Organization{
|
||||
Login: github.String("beta"),
|
||||
Login: github.String("bEtA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: github.String("team3-name"),
|
||||
Slug: github.String("team3-slug"),
|
||||
Organization: &github.Organization{
|
||||
Login: github.String("gamma"),
|
||||
Login: github.String("gAmmA"),
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
),
|
||||
token: "some-token",
|
||||
allowedOrganizations: []string{"alpha", "gamma"},
|
||||
allowedOrganizations: setutil.NewCaseInsensitiveSet("ALPHA", "gamma"),
|
||||
wantTeams: []TeamInfo{
|
||||
{
|
||||
Name: "team1-name",
|
||||
Slug: "team1-slug",
|
||||
Org: "alpha",
|
||||
Org: "alPhA",
|
||||
},
|
||||
{
|
||||
Name: "team3-name",
|
||||
Slug: "team3-slug",
|
||||
Org: "gamma",
|
||||
Org: "gAmmA",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -623,11 +622,8 @@ func TestGetTeamMembership(t *testing.T) {
|
||||
},
|
||||
),
|
||||
),
|
||||
token: "some-token",
|
||||
allowedOrganizations: []string{
|
||||
"org-with-nested-teams",
|
||||
"beta",
|
||||
},
|
||||
token: "some-token",
|
||||
allowedOrganizations: setutil.NewCaseInsensitiveSet("org-with-nested-teams", "beta"),
|
||||
wantTeams: []TeamInfo{
|
||||
{
|
||||
Name: "team-name-without-parent",
|
||||
@@ -677,7 +673,7 @@ func TestGetTeamMembership(t *testing.T) {
|
||||
),
|
||||
),
|
||||
token: "some-token",
|
||||
allowedOrganizations: []string{"page1-org-name", "page2-org-name"},
|
||||
allowedOrganizations: setutil.NewCaseInsensitiveSet("page1-org-name", "page2-org-name"),
|
||||
wantTeams: []TeamInfo{
|
||||
{
|
||||
Name: "page1-team-name",
|
||||
@@ -770,7 +766,7 @@ func TestGetTeamMembership(t *testing.T) {
|
||||
),
|
||||
),
|
||||
token: "does-this-token-work",
|
||||
allowedOrganizations: []string{"org-login"},
|
||||
allowedOrganizations: setutil.NewCaseInsensitiveSet("org-login"),
|
||||
wantTeams: []TeamInfo{
|
||||
{
|
||||
Name: "team1-name",
|
||||
@@ -821,7 +817,7 @@ func TestGetTeamMembership(t *testing.T) {
|
||||
ctx = test.ctx
|
||||
}
|
||||
|
||||
actual, err := githubClient.GetTeamMembership(ctx, sets.New[string](test.allowedOrganizations...))
|
||||
actual, err := githubClient.GetTeamMembership(ctx, test.allowedOrganizations)
|
||||
if test.wantErr != "" {
|
||||
rt, ok := test.httpClient.Transport.(*mock.EnforceHostRoundTripper)
|
||||
require.True(t, ok)
|
||||
|
||||
Reference in New Issue
Block a user