mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-09-05 23:57:12 +00:00
Add GetUser() interface and implement LoginFromCallback() for GitHub
ALso fixed some of the GitHub test helpers
This commit is contained in:
committed by
Joshua Casey
parent
b7f79f0adc
commit
49c468f00a
@@ -13,6 +13,21 @@ import (
|
||||
"go.pinniped.dev/internal/idtransform"
|
||||
)
|
||||
|
||||
// ExchangeAuthcodeArgs is used to spy on calls to
|
||||
// TestUpstreamGitHubIdentityProvider.ExchangeAuthcodeFunc().
|
||||
type ExchangeAuthcodeArgs struct {
|
||||
Ctx context.Context
|
||||
Authcode string
|
||||
RedirectURI string
|
||||
}
|
||||
|
||||
// GetUserArgs is used to spy on calls to
|
||||
// TestUpstreamGitHubIdentityProvider.GetUserFunc().
|
||||
type GetUserArgs struct {
|
||||
Ctx context.Context
|
||||
AccessToken string
|
||||
}
|
||||
|
||||
type TestUpstreamGitHubIdentityProviderBuilder struct {
|
||||
name string
|
||||
resourceUID types.UID
|
||||
@@ -24,10 +39,10 @@ type TestUpstreamGitHubIdentityProviderBuilder struct {
|
||||
groupNameAttribute v1alpha1.GitHubGroupNameAttribute
|
||||
allowedOrganizations []string
|
||||
authorizationURL string
|
||||
|
||||
// Assertions stuff
|
||||
authcodeExchangeErr error
|
||||
accessToken string
|
||||
authcodeExchangeErr error
|
||||
accessToken string
|
||||
getUserErr error
|
||||
getUserUser *upstreamprovider.GitHubUser
|
||||
}
|
||||
|
||||
func (u *TestUpstreamGitHubIdentityProviderBuilder) WithName(value string) *TestUpstreamGitHubIdentityProviderBuilder {
|
||||
@@ -80,8 +95,18 @@ func (u *TestUpstreamGitHubIdentityProviderBuilder) WithAccessToken(token string
|
||||
return u
|
||||
}
|
||||
|
||||
func (u *TestUpstreamGitHubIdentityProviderBuilder) WithEmptyAccessToken() *TestUpstreamGitHubIdentityProviderBuilder {
|
||||
u.accessToken = ""
|
||||
func (u *TestUpstreamGitHubIdentityProviderBuilder) WithAuthcodeExchangeError(err error) *TestUpstreamGitHubIdentityProviderBuilder {
|
||||
u.authcodeExchangeErr = err
|
||||
return u
|
||||
}
|
||||
|
||||
func (u *TestUpstreamGitHubIdentityProviderBuilder) WithUser(user *upstreamprovider.GitHubUser) *TestUpstreamGitHubIdentityProviderBuilder {
|
||||
u.getUserUser = user
|
||||
return u
|
||||
}
|
||||
|
||||
func (u *TestUpstreamGitHubIdentityProviderBuilder) WithGetUserError(err error) *TestUpstreamGitHubIdentityProviderBuilder {
|
||||
u.getUserErr = err
|
||||
return u
|
||||
}
|
||||
|
||||
@@ -96,8 +121,8 @@ func (u *TestUpstreamGitHubIdentityProviderBuilder) Build() *TestUpstreamGitHubI
|
||||
}
|
||||
return &TestUpstreamGitHubIdentityProvider{
|
||||
Name: u.name,
|
||||
ResourceUID: u.resourceUID,
|
||||
ClientID: u.clientID,
|
||||
ResourceUID: u.resourceUID,
|
||||
Scopes: u.scopes,
|
||||
DisplayNameForFederationDomain: u.displayNameForFederationDomain,
|
||||
TransformsForFederationDomain: u.transformsForFederationDomain,
|
||||
@@ -105,7 +130,12 @@ func (u *TestUpstreamGitHubIdentityProviderBuilder) Build() *TestUpstreamGitHubI
|
||||
GroupNameAttribute: u.groupNameAttribute,
|
||||
AllowedOrganizations: u.allowedOrganizations,
|
||||
AuthorizationURL: u.authorizationURL,
|
||||
|
||||
GetUserFunc: func(ctx context.Context, accessToken string) (*upstreamprovider.GitHubUser, error) {
|
||||
if u.getUserErr != nil {
|
||||
return nil, u.getUserErr
|
||||
}
|
||||
return u.getUserUser, nil
|
||||
},
|
||||
ExchangeAuthcodeFunc: func(ctx context.Context, authcode string) (string, error) {
|
||||
if u.authcodeExchangeErr != nil {
|
||||
return "", u.authcodeExchangeErr
|
||||
@@ -130,16 +160,14 @@ type TestUpstreamGitHubIdentityProvider struct {
|
||||
GroupNameAttribute v1alpha1.GitHubGroupNameAttribute
|
||||
AllowedOrganizations []string
|
||||
AuthorizationURL string
|
||||
GetUserFunc func(ctx context.Context, accessToken string) (*upstreamprovider.GitHubUser, error)
|
||||
ExchangeAuthcodeFunc func(ctx context.Context, authcode string) (string, error)
|
||||
|
||||
authcodeExchangeErr error
|
||||
|
||||
ExchangeAuthcodeFunc func(
|
||||
ctx context.Context,
|
||||
authcode string,
|
||||
) (string, error)
|
||||
|
||||
// Fields for tracking actual calls make to mock functions.
|
||||
exchangeAuthcodeCallCount int
|
||||
exchangeAuthcodeArgs []*ExchangeAuthcodeArgs
|
||||
getUserCallCount int
|
||||
getUserArgs []*GetUserArgs
|
||||
}
|
||||
|
||||
var _ upstreamprovider.UpstreamGithubIdentityProviderI = &TestUpstreamGitHubIdentityProvider{}
|
||||
@@ -203,3 +231,26 @@ func (u *TestUpstreamGitHubIdentityProvider) ExchangeAuthcodeArgs(call int) *Exc
|
||||
}
|
||||
return u.exchangeAuthcodeArgs[call]
|
||||
}
|
||||
|
||||
func (u *TestUpstreamGitHubIdentityProvider) GetUser(ctx context.Context, accessToken string) (*upstreamprovider.GitHubUser, error) {
|
||||
if u.getUserArgs == nil {
|
||||
u.getUserArgs = make([]*GetUserArgs, 0)
|
||||
}
|
||||
u.getUserCallCount++
|
||||
u.getUserArgs = append(u.getUserArgs, &GetUserArgs{
|
||||
Ctx: ctx,
|
||||
AccessToken: accessToken,
|
||||
})
|
||||
return u.GetUserFunc(ctx, accessToken)
|
||||
}
|
||||
|
||||
func (u *TestUpstreamGitHubIdentityProvider) GetUserCallCount() int {
|
||||
return u.getUserCallCount
|
||||
}
|
||||
|
||||
func (u *TestUpstreamGitHubIdentityProvider) GetUserArgs(call int) *GetUserArgs {
|
||||
if u.getUserArgs == nil {
|
||||
u.getUserArgs = make([]*GetUserArgs, 0)
|
||||
}
|
||||
return u.getUserArgs[call]
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ import (
|
||||
oidcpkce "go.pinniped.dev/pkg/oidcclient/pkce"
|
||||
)
|
||||
|
||||
// ExchangeAuthcodeArgs is used to spy on calls to
|
||||
// ExchangeAuthcodeAndValidateTokenArgs is used to spy on calls to
|
||||
// TestUpstreamOIDCIdentityProvider.ExchangeAuthcodeAndValidateTokensFunc().
|
||||
type ExchangeAuthcodeArgs struct {
|
||||
type ExchangeAuthcodeAndValidateTokenArgs struct {
|
||||
Ctx context.Context
|
||||
Authcode string
|
||||
PKCECodeVerifier oidcpkce.Code
|
||||
@@ -101,7 +101,7 @@ type TestUpstreamOIDCIdentityProvider struct {
|
||||
|
||||
// Fields for tracking actual calls make to mock functions.
|
||||
exchangeAuthcodeAndValidateTokensCallCount int
|
||||
exchangeAuthcodeAndValidateTokensArgs []*ExchangeAuthcodeArgs
|
||||
exchangeAuthcodeAndValidateTokensArgs []*ExchangeAuthcodeAndValidateTokenArgs
|
||||
passwordCredentialsGrantAndValidateTokensCallCount int
|
||||
passwordCredentialsGrantAndValidateTokensArgs []*PasswordCredentialsGrantAndValidateTokensArgs
|
||||
performRefreshCallCount int
|
||||
@@ -180,10 +180,10 @@ func (u *TestUpstreamOIDCIdentityProvider) ExchangeAuthcodeAndValidateTokens(
|
||||
redirectURI string,
|
||||
) (*oidctypes.Token, error) {
|
||||
if u.exchangeAuthcodeAndValidateTokensArgs == nil {
|
||||
u.exchangeAuthcodeAndValidateTokensArgs = make([]*ExchangeAuthcodeArgs, 0)
|
||||
u.exchangeAuthcodeAndValidateTokensArgs = make([]*ExchangeAuthcodeAndValidateTokenArgs, 0)
|
||||
}
|
||||
u.exchangeAuthcodeAndValidateTokensCallCount++
|
||||
u.exchangeAuthcodeAndValidateTokensArgs = append(u.exchangeAuthcodeAndValidateTokensArgs, &ExchangeAuthcodeArgs{
|
||||
u.exchangeAuthcodeAndValidateTokensArgs = append(u.exchangeAuthcodeAndValidateTokensArgs, &ExchangeAuthcodeAndValidateTokenArgs{
|
||||
Ctx: ctx,
|
||||
Authcode: authcode,
|
||||
PKCECodeVerifier: pkceCodeVerifier,
|
||||
@@ -197,9 +197,9 @@ func (u *TestUpstreamOIDCIdentityProvider) ExchangeAuthcodeAndValidateTokensCall
|
||||
return u.exchangeAuthcodeAndValidateTokensCallCount
|
||||
}
|
||||
|
||||
func (u *TestUpstreamOIDCIdentityProvider) ExchangeAuthcodeAndValidateTokensArgs(call int) *ExchangeAuthcodeArgs {
|
||||
func (u *TestUpstreamOIDCIdentityProvider) ExchangeAuthcodeAndValidateTokensArgs(call int) *ExchangeAuthcodeAndValidateTokenArgs {
|
||||
if u.exchangeAuthcodeAndValidateTokensArgs == nil {
|
||||
u.exchangeAuthcodeAndValidateTokensArgs = make([]*ExchangeAuthcodeArgs, 0)
|
||||
u.exchangeAuthcodeAndValidateTokensArgs = make([]*ExchangeAuthcodeAndValidateTokenArgs, 0)
|
||||
}
|
||||
return u.exchangeAuthcodeAndValidateTokensArgs[call]
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
idpdiscoveryv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
|
||||
"go.pinniped.dev/internal/federationdomain/dynamicupstreamprovider"
|
||||
"go.pinniped.dev/internal/federationdomain/resolvedprovider"
|
||||
"go.pinniped.dev/internal/federationdomain/resolvedprovider/resolvedgithub"
|
||||
@@ -264,48 +263,59 @@ func (b *UpstreamIDPListerBuilder) RequireExactlyZeroCallsToPasswordCredentialsG
|
||||
)
|
||||
}
|
||||
|
||||
func (b *UpstreamIDPListerBuilder) RequireExactlyOneCallToExchangeAuthcodeAndValidateTokens(
|
||||
func (b *UpstreamIDPListerBuilder) RequireExactlyOneOIDCAuthcodeExchange(
|
||||
t *testing.T,
|
||||
expectedPerformedByUpstreamName string,
|
||||
expectedArgs *oidctestutil.ExchangeAuthcodeAndValidateTokenArgs,
|
||||
) {
|
||||
t.Helper()
|
||||
var actualArgs *oidctestutil.ExchangeAuthcodeAndValidateTokenArgs
|
||||
var actualNameOfUpstreamWhichMadeCall string
|
||||
actualCallCount := 0
|
||||
for _, upstream := range b.upstreamOIDCIdentityProviders {
|
||||
callCountOnThisUpstream := upstream.ExchangeAuthcodeAndValidateTokensCallCount()
|
||||
actualCallCount += callCountOnThisUpstream
|
||||
if callCountOnThisUpstream == 1 {
|
||||
actualNameOfUpstreamWhichMadeCall = upstream.Name
|
||||
actualArgs = upstream.ExchangeAuthcodeAndValidateTokensArgs(0)
|
||||
}
|
||||
}
|
||||
require.Equal(t, 1, actualCallCount,
|
||||
"expected exactly one call to OIDC ExchangeAuthcodeAndValidateTokens()",
|
||||
)
|
||||
require.Equal(t, expectedPerformedByUpstreamName, actualNameOfUpstreamWhichMadeCall,
|
||||
"OIDC ExchangeAuthcodeAndValidateTokens() was called on the wrong upstream name",
|
||||
)
|
||||
require.Equal(t, expectedArgs, actualArgs)
|
||||
}
|
||||
|
||||
func (b *UpstreamIDPListerBuilder) RequireExactlyOneGitHubAuthcodeExchange(
|
||||
t *testing.T,
|
||||
expectedPerformedByUpstreamName string,
|
||||
expectedPerformedByUpstreamType idpdiscoveryv1alpha1.IDPType,
|
||||
expectedArgs *oidctestutil.ExchangeAuthcodeArgs,
|
||||
) {
|
||||
t.Helper()
|
||||
var actualArgs *oidctestutil.ExchangeAuthcodeArgs
|
||||
var actualNameOfUpstreamWhichMadeCall string
|
||||
var actualTypeOfUpstreamWhichMadeCall idpdiscoveryv1alpha1.IDPType
|
||||
actualCallCountAcrossAllOIDCAndGitHubUpstreams := 0
|
||||
for _, upstreamOIDC := range b.upstreamOIDCIdentityProviders {
|
||||
callCountOnThisUpstream := upstreamOIDC.ExchangeAuthcodeAndValidateTokensCallCount()
|
||||
actualCallCountAcrossAllOIDCAndGitHubUpstreams += callCountOnThisUpstream
|
||||
actualCallCount := 0
|
||||
for _, upstream := range b.upstreamGitHubIdentityProviders {
|
||||
callCountOnThisUpstream := upstream.ExchangeAuthcodeCallCount()
|
||||
actualCallCount += callCountOnThisUpstream
|
||||
if callCountOnThisUpstream == 1 {
|
||||
actualNameOfUpstreamWhichMadeCall = upstreamOIDC.Name
|
||||
actualTypeOfUpstreamWhichMadeCall = idpdiscoveryv1alpha1.IDPTypeOIDC
|
||||
actualArgs = upstreamOIDC.ExchangeAuthcodeAndValidateTokensArgs(0)
|
||||
actualNameOfUpstreamWhichMadeCall = upstream.Name
|
||||
actualArgs = upstream.ExchangeAuthcodeArgs(0)
|
||||
}
|
||||
}
|
||||
for _, upstreamGitHub := range b.upstreamGitHubIdentityProviders {
|
||||
callCountOnThisUpstream := upstreamGitHub.ExchangeAuthcodeCallCount()
|
||||
actualCallCountAcrossAllOIDCAndGitHubUpstreams += callCountOnThisUpstream
|
||||
if callCountOnThisUpstream == 1 {
|
||||
actualNameOfUpstreamWhichMadeCall = upstreamGitHub.Name
|
||||
actualTypeOfUpstreamWhichMadeCall = idpdiscoveryv1alpha1.IDPTypeGitHub
|
||||
actualArgs = upstreamGitHub.ExchangeAuthcodeArgs(0)
|
||||
}
|
||||
}
|
||||
require.Equal(t, 1, actualCallCountAcrossAllOIDCAndGitHubUpstreams,
|
||||
"expected exactly one call to (OIDC) ExchangeAuthcodeAndValidateTokensCallCount() or (GitHub) ExchangeAuthcodeCallCount()",
|
||||
require.Equal(t, 1, actualCallCount,
|
||||
"expected exactly one call to GitHub ExchangeAuthcode()",
|
||||
)
|
||||
require.Equal(t, expectedPerformedByUpstreamName, actualNameOfUpstreamWhichMadeCall,
|
||||
"(OIDC) ExchangeAuthcodeAndValidateTokensCallCount() or (GitHub) ExchangeAuthcodeCallCount() was called on the wrong upstream name",
|
||||
)
|
||||
require.Equal(t, expectedPerformedByUpstreamType, actualTypeOfUpstreamWhichMadeCall,
|
||||
"(OIDC) ExchangeAuthcodeAndValidateTokensCallCount() or (GitHub) ExchangeAuthcodeCallCount() was called on the wrong upstream type",
|
||||
"GitHub ExchangeAuthcode() was called on the wrong upstream name",
|
||||
)
|
||||
require.Equal(t, expectedArgs, actualArgs)
|
||||
}
|
||||
|
||||
func (b *UpstreamIDPListerBuilder) RequireExactlyZeroCallsToExchangeAuthcodeAndValidateTokens(t *testing.T) {
|
||||
func (b *UpstreamIDPListerBuilder) RequireExactlyZeroAuthcodeExchanges(t *testing.T) {
|
||||
t.Helper()
|
||||
actualCallCount := 0
|
||||
for _, upstreamOIDC := range b.upstreamOIDCIdentityProviders {
|
||||
@@ -316,7 +326,7 @@ func (b *UpstreamIDPListerBuilder) RequireExactlyZeroCallsToExchangeAuthcodeAndV
|
||||
}
|
||||
|
||||
require.Equal(t, 0, actualCallCount,
|
||||
"expected exactly zero calls to (OIDC) ExchangeAuthcodeAndValidateTokensCallCount() or (GitHub) ExchangeAuthcodeCallCount()",
|
||||
"expected exactly zero calls to OIDC ExchangeAuthcodeAndValidateTokens() or GitHub ExchangeAuthcode()",
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user