add new unit tests in auth_handler_test.go

This commit is contained in:
Ryan Richard 2023-08-22 17:28:56 -07:00
parent 2eb82cc1d7
commit b2656b9cb1
4 changed files with 317 additions and 104 deletions

View File

@ -30,12 +30,14 @@ import (
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake" supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1" "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1"
"go.pinniped.dev/internal/authenticators" "go.pinniped.dev/internal/authenticators"
"go.pinniped.dev/internal/celtransformer"
"go.pinniped.dev/internal/federationdomain/csrftoken" "go.pinniped.dev/internal/federationdomain/csrftoken"
"go.pinniped.dev/internal/federationdomain/endpoints/jwks" "go.pinniped.dev/internal/federationdomain/endpoints/jwks"
"go.pinniped.dev/internal/federationdomain/oidc" "go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/federationdomain/oidcclientvalidator" "go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
"go.pinniped.dev/internal/federationdomain/storage" "go.pinniped.dev/internal/federationdomain/storage"
"go.pinniped.dev/internal/here" "go.pinniped.dev/internal/here"
"go.pinniped.dev/internal/idtransform"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/internal/testutil/oidctestutil" "go.pinniped.dev/internal/testutil/oidctestutil"
@ -43,7 +45,7 @@ import (
"go.pinniped.dev/pkg/oidcclient/pkce" "go.pinniped.dev/pkg/oidcclient/pkce"
) )
func TestAuthorizationEndpoint(t *testing.T) { func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
const ( const (
oidcUpstreamName = "some-oidc-idp" oidcUpstreamName = "some-oidc-idp"
oidcUpstreamResourceUID = "oidc-resource-uid" oidcUpstreamResourceUID = "oidc-resource-uid"
@ -80,6 +82,9 @@ func TestAuthorizationEndpoint(t *testing.T) {
pinnipedCLIClientID = "pinniped-cli" pinnipedCLIClientID = "pinniped-cli"
dynamicClientID = "client.oauth.pinniped.dev-test-name" dynamicClientID = "client.oauth.pinniped.dev-test-name"
dynamicClientUID = "fake-client-uid" dynamicClientUID = "fake-client-uid"
transformationUsernamePrefix = "username_prefix:"
transformationGroupsPrefix = "groups_prefix:"
) )
require.Len(t, happyState, 8, "we expect fosite to allow 8 byte state params, so we want to test that boundary case") require.Len(t, happyState, 8, "we expect fosite to allow 8 byte state params, so we want to test that boundary case")
@ -221,6 +226,12 @@ func TestAuthorizationEndpoint(t *testing.T) {
"state": happyState, "state": happyState,
} }
fositeAccessDeniedWithConfiguredPolicyRejectionHintErrorQuery = map[string]string{
"error": "access_denied",
"error_description": "The resource owner or authorization server denied the request. Reason: configured identity policy rejected this authentication: authentication was rejected by a configured policy.",
"state": happyState,
}
fositeLoginRequiredErrorQuery = map[string]string{ fositeLoginRequiredErrorQuery = map[string]string{
"error": "login_required", "error": "login_required",
"error_description": "The Authorization Server requires End-User authentication.", "error_description": "The Authorization Server requires End-User authentication.",
@ -324,19 +335,21 @@ func TestAuthorizationEndpoint(t *testing.T) {
return nil, false, nil return nil, false, nil
} }
upstreamLDAPIdentityProvider := oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder(). upstreamLDAPIdentityProviderBuilder := func() *oidctestutil.TestUpstreamLDAPIdentityProviderBuilder {
return oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().
WithName(ldapUpstreamName). WithName(ldapUpstreamName).
WithResourceUID(ldapUpstreamResourceUID). WithResourceUID(ldapUpstreamResourceUID).
WithURL(parsedUpstreamLDAPURL). WithURL(parsedUpstreamLDAPURL).
WithAuthenticateFunc(ldapAuthenticateFunc). WithAuthenticateFunc(ldapAuthenticateFunc)
Build() }
upstreamActiveDirectoryIdentityProvider := oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder(). upstreamActiveDirectoryIdentityProviderBuilder := func() *oidctestutil.TestUpstreamLDAPIdentityProviderBuilder {
return oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().
WithName(activeDirectoryUpstreamName). WithName(activeDirectoryUpstreamName).
WithResourceUID(activeDirectoryUpstreamResourceUID). WithResourceUID(activeDirectoryUpstreamResourceUID).
WithURL(parsedUpstreamLDAPURL). WithURL(parsedUpstreamLDAPURL).
WithAuthenticateFunc(ldapAuthenticateFunc). WithAuthenticateFunc(ldapAuthenticateFunc)
Build() }
erroringUpstreamLDAPIdentityProvider := oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder(). erroringUpstreamLDAPIdentityProvider := oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().
WithName(ldapUpstreamName). WithName(ldapUpstreamName).
@ -550,16 +563,6 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
} }
expectedHappyOIDCPasswordGrantCustomSessionWithUsernameAndGroups := func(wantUsername string, wantGroups []string) *psession.CustomSessionData {
copyOfCustomSession := *expectedHappyOIDCPasswordGrantCustomSession
copyOfOIDC := *(expectedHappyOIDCPasswordGrantCustomSession.OIDC)
copyOfCustomSession.OIDC = &copyOfOIDC
copyOfCustomSession.Username = wantUsername
copyOfCustomSession.UpstreamUsername = wantUsername
copyOfCustomSession.UpstreamGroups = wantGroups
return &copyOfCustomSession
}
expectedHappyOIDCPasswordGrantCustomSessionWithAccessToken := &psession.CustomSessionData{ expectedHappyOIDCPasswordGrantCustomSessionWithAccessToken := &psession.CustomSessionData{
Username: oidcUpstreamUsername, Username: oidcUpstreamUsername,
UpstreamUsername: oidcUpstreamUsername, UpstreamUsername: oidcUpstreamUsername,
@ -574,6 +577,26 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
} }
withUsernameAndGroupsInCustomSession := func(expectedCustomSessionData *psession.CustomSessionData, wantDownstreamUsername string, wantUpstreamUsername string, wantUpstreamGroups []string) *psession.CustomSessionData {
copyOfCustomSession := *expectedCustomSessionData
if expectedCustomSessionData.LDAP != nil {
copyOfLDAP := *(expectedCustomSessionData.LDAP)
copyOfCustomSession.LDAP = &copyOfLDAP
}
if expectedCustomSessionData.OIDC != nil {
copyOfOIDC := *(expectedCustomSessionData.OIDC)
copyOfCustomSession.OIDC = &copyOfOIDC
}
if expectedCustomSessionData.ActiveDirectory != nil {
copyOfActiveDirectory := *(expectedCustomSessionData.ActiveDirectory)
copyOfCustomSession.ActiveDirectory = &copyOfActiveDirectory
}
copyOfCustomSession.Username = wantDownstreamUsername
copyOfCustomSession.UpstreamUsername = wantUpstreamUsername
copyOfCustomSession.UpstreamGroups = wantUpstreamGroups
return &copyOfCustomSession
}
addFullyCapableDynamicClientAndSecretToKubeResources := func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) { addFullyCapableDynamicClientAndSecretToKubeResources := func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) {
oidcClient, secret := testutil.FullyCapableOIDCClientAndStorageSecret(t, oidcClient, secret := testutil.FullyCapableOIDCClientAndStorageSecret(t,
"some-namespace", dynamicClientID, dynamicClientUID, downstreamRedirectURI, "some-namespace", dynamicClientID, dynamicClientUID, downstreamRedirectURI,
@ -589,6 +612,24 @@ func TestAuthorizationEndpoint(t *testing.T) {
encodedIncomingCookieCSRFValue, err := happyCookieEncoder.Encode("csrf", incomingCookieCSRFValue) encodedIncomingCookieCSRFValue, err := happyCookieEncoder.Encode("csrf", incomingCookieCSRFValue)
require.NoError(t, err) require.NoError(t, err)
transformer, err := celtransformer.NewCELTransformer(5 * time.Second) // CI workers can be slow, so allow slow transforms
require.NoError(t, err)
prefixUsernameAndGroupsPipeline := idtransform.NewTransformationPipeline()
rejectAuthPipeline := idtransform.NewTransformationPipeline()
var compiledTransform idtransform.IdentityTransformation
compiledTransform, err = transformer.CompileTransformation(&celtransformer.UsernameTransformation{Expression: fmt.Sprintf(`"%s" + username`, transformationUsernamePrefix)}, nil)
require.NoError(t, err)
prefixUsernameAndGroupsPipeline.AppendTransformation(compiledTransform)
compiledTransform, err = transformer.CompileTransformation(&celtransformer.GroupsTransformation{Expression: fmt.Sprintf(`groups.map(g, "%s" + g)`, transformationGroupsPrefix)}, nil)
require.NoError(t, err)
prefixUsernameAndGroupsPipeline.AppendTransformation(compiledTransform)
compiledTransform, err = transformer.CompileTransformation(&celtransformer.AllowAuthenticationPolicy{Expression: `username == "someone-special"`}, nil)
require.NoError(t, err)
rejectAuthPipeline.AppendTransformation(compiledTransform)
type testCase struct { type testCase struct {
name string name string
@ -673,7 +714,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "LDAP upstream browser flow happy path using GET without a CSRF cookie", name: "LDAP upstream browser flow happy path using GET without a CSRF cookie",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
generateCSRF: happyCSRFGenerator, generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator, generatePKCE: happyPKCEGenerator,
generateNonce: happyNonceGenerator, generateNonce: happyNonceGenerator,
@ -688,9 +729,65 @@ func TestAuthorizationEndpoint(t *testing.T) {
wantUpstreamStateParamInLocationHeader: true, wantUpstreamStateParamInLocationHeader: true,
wantBodyStringWithLocationInHref: true, wantBodyStringWithLocationInHref: true,
}, },
{
name: "OIDC upstream browser flow happy path using GET without a CSRF cookie using backwards compatibility mode to have a default IDP (display name does not need to be sent as query param)",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()).
WithDefaultIDPDisplayName(oidcUpstreamName), // specify which IDP is the backwards-compatibility mode IDP
generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator,
generateNonce: happyNonceGenerator,
stateEncoder: happyStateEncoder,
cookieEncoder: happyCookieEncoder,
method: http.MethodGet,
path: happyGetRequestPath, // does not include IDP display name as query param
wantStatus: http.StatusSeeOther,
wantContentType: htmlContentType,
wantCSRFValueInCookieHeader: happyCSRF,
wantLocationHeader: expectedRedirectLocationForUpstreamOIDC(expectedUpstreamStateParam(nil, "", oidcUpstreamName, "oidc"), nil),
wantUpstreamStateParamInLocationHeader: true,
wantBodyStringWithLocationInHref: true,
},
{
name: "with multiple IDPs available, request chooses to use OIDC browser flow",
idps: oidctestutil.NewUpstreamIDPListerBuilder().
WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()).
WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator,
generateNonce: happyNonceGenerator,
stateEncoder: happyStateEncoder,
cookieEncoder: happyCookieEncoder,
method: http.MethodGet,
path: happyGetRequestPathForOIDCUpstream, // includes IDP display name of OIDC upstream
wantStatus: http.StatusSeeOther,
wantContentType: htmlContentType,
wantCSRFValueInCookieHeader: happyCSRF,
wantLocationHeader: expectedRedirectLocationForUpstreamOIDC(expectedUpstreamStateParam(nil, "", oidcUpstreamName, "oidc"), nil),
wantUpstreamStateParamInLocationHeader: true,
wantBodyStringWithLocationInHref: true,
},
{
name: "with multiple IDPs available, request chooses to use LDAP browser flow",
idps: oidctestutil.NewUpstreamIDPListerBuilder().
WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()).
WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator,
generateNonce: happyNonceGenerator,
stateEncoder: happyStateEncoder,
cookieEncoder: happyCookieEncoder,
method: http.MethodGet,
path: happyGetRequestPathForLDAPUpstream, // includes IDP display name of LDAP upstream
wantStatus: http.StatusSeeOther,
wantContentType: htmlContentType,
wantCSRFValueInCookieHeader: happyCSRF,
wantLocationHeader: urlWithQuery(downstreamIssuer+"/login", map[string]string{"state": expectedUpstreamStateParam(nil, "", ldapUpstreamName, "ldap")}),
wantUpstreamStateParamInLocationHeader: true,
wantBodyStringWithLocationInHref: true,
},
{ {
name: "LDAP upstream browser flow happy path using GET without a CSRF cookie using a dynamic client", name: "LDAP upstream browser flow happy path using GET without a CSRF cookie using a dynamic client",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources,
generateCSRF: happyCSRFGenerator, generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator, generatePKCE: happyPKCEGenerator,
@ -708,7 +805,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "Active Directory upstream browser flow happy path using GET without a CSRF cookie", name: "Active Directory upstream browser flow happy path using GET without a CSRF cookie",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
generateCSRF: happyCSRFGenerator, generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator, generatePKCE: happyPKCEGenerator,
generateNonce: happyNonceGenerator, generateNonce: happyNonceGenerator,
@ -725,7 +822,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "Active Directory upstream browser flow happy path using GET without a CSRF cookie using a dynamic client", name: "Active Directory upstream browser flow happy path using GET without a CSRF cookie using a dynamic client",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources,
generateCSRF: happyCSRFGenerator, generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator, generatePKCE: happyPKCEGenerator,
@ -763,6 +860,48 @@ func TestAuthorizationEndpoint(t *testing.T) {
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod, wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: expectedHappyOIDCPasswordGrantCustomSession, wantDownstreamCustomSessionData: expectedHappyOIDCPasswordGrantCustomSession,
}, },
{
name: "OIDC upstream password grant happy path using GET with identity transformations which change username and groups",
idps: oidctestutil.NewUpstreamIDPListerBuilder().
WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().WithTransformsForFederationDomain(prefixUsernameAndGroupsPipeline).Build()),
method: http.MethodGet,
path: happyGetRequestPathForOIDCPasswordGrantUpstream,
customUsernameHeader: ptr.To(oidcUpstreamUsername),
customPasswordHeader: ptr.To(oidcUpstreamPassword),
wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation,
wantStatus: http.StatusFound,
wantContentType: htmlContentType,
wantRedirectLocationRegexp: happyAuthcodeDownstreamRedirectLocationRegexp,
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
wantDownstreamIDTokenUsername: transformationUsernamePrefix + oidcUpstreamUsername,
wantDownstreamIDTokenGroups: testutil.AddPrefixToEach(transformationGroupsPrefix, oidcUpstreamGroupMembership),
wantDownstreamRequestedScopes: happyDownstreamScopesRequested,
wantDownstreamRedirectURI: downstreamRedirectURI,
wantDownstreamGrantedScopes: happyDownstreamScopesGranted,
wantDownstreamNonce: downstreamNonce,
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: withUsernameAndGroupsInCustomSession(
expectedHappyOIDCPasswordGrantCustomSession,
transformationUsernamePrefix+oidcUpstreamUsername,
oidcUpstreamUsername,
oidcUpstreamGroupMembership,
),
},
{
name: "OIDC upstream password grant with identity transformations which rejects auth",
idps: oidctestutil.NewUpstreamIDPListerBuilder().
WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().WithTransformsForFederationDomain(rejectAuthPipeline).Build()),
method: http.MethodGet,
path: happyGetRequestPathForOIDCPasswordGrantUpstream,
customUsernameHeader: ptr.To(oidcUpstreamUsername),
customPasswordHeader: ptr.To(oidcUpstreamPassword),
wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation,
wantStatus: http.StatusFound,
wantContentType: jsonContentType,
wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeAccessDeniedWithConfiguredPolicyRejectionHintErrorQuery),
wantBodyString: "",
},
{ {
name: "OIDC upstream password grant happy path using GET with additional claim mappings", name: "OIDC upstream password grant happy path using GET with additional claim mappings",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder(). idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().
@ -827,7 +966,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "LDAP cli upstream happy path using GET", name: "LDAP cli upstream happy path using GET",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: happyGetRequestPathForLDAPUpstream, path: happyGetRequestPathForLDAPUpstream,
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -846,9 +985,49 @@ func TestAuthorizationEndpoint(t *testing.T) {
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod, wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: expectedHappyLDAPUpstreamCustomSession, wantDownstreamCustomSessionData: expectedHappyLDAPUpstreamCustomSession,
}, },
{
name: "LDAP cli upstream happy path using GET with identity transformations which change username and groups",
idps: oidctestutil.NewUpstreamIDPListerBuilder().
WithLDAP(upstreamLDAPIdentityProviderBuilder().WithTransformsForFederationDomain(prefixUsernameAndGroupsPipeline).Build()),
method: http.MethodGet,
path: happyGetRequestPathForLDAPUpstream,
customUsernameHeader: ptr.To(happyLDAPUsername),
customPasswordHeader: ptr.To(happyLDAPPassword),
wantStatus: http.StatusFound,
wantContentType: htmlContentType,
wantRedirectLocationRegexp: happyAuthcodeDownstreamRedirectLocationRegexp,
wantDownstreamIDTokenSubject: upstreamLDAPURL + "&sub=" + happyLDAPUID,
wantDownstreamIDTokenUsername: transformationUsernamePrefix + happyLDAPUsernameFromAuthenticator,
wantDownstreamIDTokenGroups: testutil.AddPrefixToEach(transformationGroupsPrefix, happyLDAPGroups),
wantDownstreamRequestedScopes: happyDownstreamScopesRequested,
wantDownstreamRedirectURI: downstreamRedirectURI,
wantDownstreamGrantedScopes: happyDownstreamScopesGranted,
wantDownstreamNonce: downstreamNonce,
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: withUsernameAndGroupsInCustomSession(
expectedHappyLDAPUpstreamCustomSession,
transformationUsernamePrefix+happyLDAPUsernameFromAuthenticator,
happyLDAPUsernameFromAuthenticator,
happyLDAPGroups,
),
},
{
name: "LDAP cli upstream with identity transformations which reject auth",
idps: oidctestutil.NewUpstreamIDPListerBuilder().
WithLDAP(upstreamLDAPIdentityProviderBuilder().WithTransformsForFederationDomain(rejectAuthPipeline).Build()),
method: http.MethodGet,
path: happyGetRequestPathForLDAPUpstream,
customUsernameHeader: ptr.To(happyLDAPUsername),
customPasswordHeader: ptr.To(happyLDAPPassword),
wantStatus: http.StatusFound,
wantContentType: jsonContentType,
wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeAccessDeniedWithConfiguredPolicyRejectionHintErrorQuery),
wantBodyString: "",
},
{ {
name: "ActiveDirectory cli upstream happy path using GET", name: "ActiveDirectory cli upstream happy path using GET",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: happyGetRequestPathForADUpstream, path: happyGetRequestPathForADUpstream,
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -886,7 +1065,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "LDAP upstream browser flow happy path using GET with a CSRF cookie", name: "LDAP upstream browser flow happy path using GET with a CSRF cookie",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
generateCSRF: happyCSRFGenerator, generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator, generatePKCE: happyPKCEGenerator,
generateNonce: happyNonceGenerator, generateNonce: happyNonceGenerator,
@ -903,7 +1082,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "Active Directory upstream browser flow happy path using GET with a CSRF cookie", name: "Active Directory upstream browser flow happy path using GET with a CSRF cookie",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
generateCSRF: happyCSRFGenerator, generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator, generatePKCE: happyPKCEGenerator,
generateNonce: happyNonceGenerator, generateNonce: happyNonceGenerator,
@ -959,7 +1138,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "LDAP upstream browser flow happy path using POST", name: "LDAP upstream browser flow happy path using POST",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
generateCSRF: happyCSRFGenerator, generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator, generatePKCE: happyPKCEGenerator,
generateNonce: happyNonceGenerator, generateNonce: happyNonceGenerator,
@ -978,7 +1157,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "LDAP upstream browser flow happy path using POST with a dynamic client", name: "LDAP upstream browser flow happy path using POST with a dynamic client",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources,
generateCSRF: happyCSRFGenerator, generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator, generatePKCE: happyPKCEGenerator,
@ -998,7 +1177,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "Active Directory upstream browser flow happy path using POST", name: "Active Directory upstream browser flow happy path using POST",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
generateCSRF: happyCSRFGenerator, generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator, generatePKCE: happyPKCEGenerator,
generateNonce: happyNonceGenerator, generateNonce: happyNonceGenerator,
@ -1017,7 +1196,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "Active Directory upstream browser flow happy path using POST with a dynamic client", name: "Active Directory upstream browser flow happy path using POST with a dynamic client",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources,
generateCSRF: happyCSRFGenerator, generateCSRF: happyCSRFGenerator,
generatePKCE: happyPKCEGenerator, generatePKCE: happyPKCEGenerator,
@ -1061,7 +1240,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "LDAP cli upstream happy path using POST", name: "LDAP cli upstream happy path using POST",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodPost, method: http.MethodPost,
path: "/some/path", path: "/some/path",
contentType: formContentType, contentType: formContentType,
@ -1084,7 +1263,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "Active Directory cli upstream happy path using POST", name: "Active Directory cli upstream happy path using POST",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodPost, method: http.MethodPost,
path: "/some/path", path: "/some/path",
contentType: formContentType, contentType: formContentType,
@ -1264,7 +1443,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "LDAP upstream happy path when downstream redirect uri matches what is configured for client except for the port number", name: "LDAP upstream happy path when downstream redirect uri matches what is configured for client except for the port number",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{ path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{
"redirect_uri": downstreamRedirectURIWithDifferentPort, // not the same port number that is registered for the client "redirect_uri": downstreamRedirectURIWithDifferentPort, // not the same port number that is registered for the client
@ -1430,7 +1609,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "wrong upstream password for LDAP authentication", name: "wrong upstream password for LDAP authentication",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: happyGetRequestPathForLDAPUpstream, path: happyGetRequestPathForLDAPUpstream,
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -1442,7 +1621,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "wrong upstream password for Active Directory authentication", name: "wrong upstream password for Active Directory authentication",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: happyGetRequestPathForADUpstream, path: happyGetRequestPathForADUpstream,
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -1454,7 +1633,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "wrong upstream username for LDAP authentication", name: "wrong upstream username for LDAP authentication",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: happyGetRequestPathForLDAPUpstream, path: happyGetRequestPathForLDAPUpstream,
customUsernameHeader: ptr.To("wrong-username"), customUsernameHeader: ptr.To("wrong-username"),
@ -1466,7 +1645,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "wrong upstream username for Active Directory authentication", name: "wrong upstream username for Active Directory authentication",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: happyGetRequestPathForADUpstream, path: happyGetRequestPathForADUpstream,
customUsernameHeader: ptr.To("wrong-username"), customUsernameHeader: ptr.To("wrong-username"),
@ -1490,7 +1669,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing upstream username but has password on request for LDAP authentication", name: "missing upstream username but has password on request for LDAP authentication",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: happyGetRequestPathForLDAPUpstream, path: happyGetRequestPathForLDAPUpstream,
customUsernameHeader: nil, // do not send header customUsernameHeader: nil, // do not send header
@ -1502,7 +1681,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing upstream username on request for Active Directory authentication", name: "missing upstream username on request for Active Directory authentication",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: happyGetRequestPathForADUpstream, path: happyGetRequestPathForADUpstream,
customUsernameHeader: nil, // do not send header customUsernameHeader: nil, // do not send header
@ -1514,7 +1693,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing upstream password on request for LDAP authentication", name: "missing upstream password on request for LDAP authentication",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: happyGetRequestPathForLDAPUpstream, path: happyGetRequestPathForLDAPUpstream,
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -1526,7 +1705,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing upstream password on request for Active Directory authentication", name: "missing upstream password on request for Active Directory authentication",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: happyGetRequestPathForADUpstream, path: happyGetRequestPathForADUpstream,
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -1653,7 +1832,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "dynamic clients are not allowed to use LDAP CLI-flow authentication because we don't want them to handle user credentials", name: "dynamic clients are not allowed to use LDAP CLI-flow authentication because we don't want them to handle user credentials",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources,
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}),
@ -1666,7 +1845,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "dynamic clients are not allowed to use Active Directory CLI-flow authentication because we don't want them to handle user credentials", name: "dynamic clients are not allowed to use Active Directory CLI-flow authentication because we don't want them to handle user credentials",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources,
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}),
@ -1727,7 +1906,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "downstream redirect uri does not match what is configured for client when using LDAP upstream", name: "downstream redirect uri does not match what is configured for client when using LDAP upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{ path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{
"redirect_uri": "http://127.0.0.1/does-not-match-what-is-configured-for-pinniped-cli-client", "redirect_uri": "http://127.0.0.1/does-not-match-what-is-configured-for-pinniped-cli-client",
@ -1740,7 +1919,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "downstream redirect uri does not match what is configured for client when using active directory upstream", name: "downstream redirect uri does not match what is configured for client when using active directory upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForADUpstream(map[string]string{ path: modifiedHappyGetRequestPathForADUpstream(map[string]string{
"redirect_uri": "http://127.0.0.1/does-not-match-what-is-configured-for-pinniped-cli-client", "redirect_uri": "http://127.0.0.1/does-not-match-what-is-configured-for-pinniped-cli-client",
@ -1778,7 +1957,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "downstream client does not exist when using LDAP upstream", name: "downstream client does not exist when using LDAP upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"client_id": "invalid-client"}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"client_id": "invalid-client"}),
wantStatus: http.StatusUnauthorized, wantStatus: http.StatusUnauthorized,
@ -1787,7 +1966,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "downstream client does not exist when using active directory upstream", name: "downstream client does not exist when using active directory upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"client_id": "invalid-client"}), path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"client_id": "invalid-client"}),
wantStatus: http.StatusUnauthorized, wantStatus: http.StatusUnauthorized,
@ -1843,7 +2022,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "response type is unsupported when using LDAP cli upstream", name: "response type is unsupported when using LDAP cli upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"response_type": "unsupported"}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"response_type": "unsupported"}),
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -1855,7 +2034,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "response type is unsupported when using LDAP browser upstream", name: "response type is unsupported when using LDAP browser upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"response_type": "unsupported"}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"response_type": "unsupported"}),
wantStatus: http.StatusSeeOther, wantStatus: http.StatusSeeOther,
@ -1865,7 +2044,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "response type is unsupported when using LDAP browser upstream with dynamic client", name: "response type is unsupported when using LDAP browser upstream with dynamic client",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources,
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{ path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{
@ -1880,7 +2059,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "response type is unsupported when using active directory cli upstream", name: "response type is unsupported when using active directory cli upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"response_type": "unsupported"}), path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"response_type": "unsupported"}),
customUsernameHeader: ptr.To(oidcUpstreamUsername), customUsernameHeader: ptr.To(oidcUpstreamUsername),
@ -1892,7 +2071,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "response type is unsupported when using active directory browser upstream", name: "response type is unsupported when using active directory browser upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"response_type": "unsupported"}), path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"response_type": "unsupported"}),
wantStatus: http.StatusSeeOther, wantStatus: http.StatusSeeOther,
@ -1902,7 +2081,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "response type is unsupported when using active directory browser upstream with dynamic client", name: "response type is unsupported when using active directory browser upstream with dynamic client",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources,
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForADUpstream(map[string]string{ path: modifiedHappyGetRequestPathForADUpstream(map[string]string{
@ -1989,7 +2168,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "downstream scopes do not match what is configured for client using LDAP upstream", name: "downstream scopes do not match what is configured for client using LDAP upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"scope": "openid tuna"}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"scope": "openid tuna"}),
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -2001,7 +2180,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "downstream scopes do not match what is configured for client using Active Directory upstream", name: "downstream scopes do not match what is configured for client using Active Directory upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"scope": "openid tuna"}), path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"scope": "openid tuna"}),
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -2056,7 +2235,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing response type in request using LDAP cli upstream", name: "missing response type in request using LDAP cli upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"response_type": ""}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"response_type": ""}),
customUsernameHeader: ptr.To(oidcUpstreamUsername), customUsernameHeader: ptr.To(oidcUpstreamUsername),
@ -2068,7 +2247,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing response type in request using LDAP browser upstream", name: "missing response type in request using LDAP browser upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"response_type": ""}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"response_type": ""}),
wantStatus: http.StatusSeeOther, wantStatus: http.StatusSeeOther,
@ -2078,7 +2257,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing response type in request using LDAP browser upstream with dynamic client", name: "missing response type in request using LDAP browser upstream with dynamic client",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources,
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep, "response_type": ""}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep, "response_type": ""}),
@ -2089,7 +2268,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing response type in request using Active Directory cli upstream", name: "missing response type in request using Active Directory cli upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"response_type": ""}), path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"response_type": ""}),
customUsernameHeader: ptr.To(oidcUpstreamUsername), customUsernameHeader: ptr.To(oidcUpstreamUsername),
@ -2101,7 +2280,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing response type in request using Active Directory browser upstream", name: "missing response type in request using Active Directory browser upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"response_type": ""}), path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"response_type": ""}),
wantStatus: http.StatusSeeOther, wantStatus: http.StatusSeeOther,
@ -2111,7 +2290,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing response type in request using Active Directory browser upstream with dynamic client", name: "missing response type in request using Active Directory browser upstream with dynamic client",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder().Build()),
kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources,
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep, "response_type": ""}), path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep, "response_type": ""}),
@ -2147,7 +2326,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing client id in request using LDAP upstream", name: "missing client id in request using LDAP upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"client_id": ""}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"client_id": ""}),
wantStatus: http.StatusUnauthorized, wantStatus: http.StatusUnauthorized,
@ -2201,7 +2380,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing PKCE code_challenge in request using LDAP upstream", // See https://tools.ietf.org/html/rfc7636#section-4.4.1 name: "missing PKCE code_challenge in request using LDAP upstream", // See https://tools.ietf.org/html/rfc7636#section-4.4.1
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"code_challenge": ""}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"code_challenge": ""}),
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -2259,7 +2438,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "invalid value for PKCE code_challenge_method in request using LDAP upstream", // https://tools.ietf.org/html/rfc7636#section-4.3 name: "invalid value for PKCE code_challenge_method in request using LDAP upstream", // https://tools.ietf.org/html/rfc7636#section-4.3
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"code_challenge_method": "this-is-not-a-valid-pkce-alg"}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"code_challenge_method": "this-is-not-a-valid-pkce-alg"}),
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -2317,7 +2496,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "when PKCE code_challenge_method in request is `plain` using LDAP upstream", // https://tools.ietf.org/html/rfc7636#section-4.3 name: "when PKCE code_challenge_method in request is `plain` using LDAP upstream", // https://tools.ietf.org/html/rfc7636#section-4.3
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"code_challenge_method": "plain"}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"code_challenge_method": "plain"}),
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -2375,7 +2554,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "missing PKCE code_challenge_method in request using LDAP upstream", // See https://tools.ietf.org/html/rfc7636#section-4.4.1 name: "missing PKCE code_challenge_method in request using LDAP upstream", // See https://tools.ietf.org/html/rfc7636#section-4.4.1
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"code_challenge_method": ""}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"code_challenge_method": ""}),
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -2441,7 +2620,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
// This is just one of the many OIDC validations run by fosite. This test is to ensure that we are running // This is just one of the many OIDC validations run by fosite. This test is to ensure that we are running
// through that part of the fosite library when using an LDAP upstream. // through that part of the fosite library when using an LDAP upstream.
name: "prompt param is not allowed to have none and another legal value at the same time using LDAP upstream", name: "prompt param is not allowed to have none and another legal value at the same time using LDAP upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"prompt": "none login"}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"prompt": "none login"}),
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -2518,7 +2697,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "happy path: downstream OIDC validations are skipped when the openid scope was not requested using LDAP upstream", name: "happy path: downstream OIDC validations are skipped when the openid scope was not requested using LDAP upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
// The following prompt value is illegal when openid is requested, but note that openid is not requested. // The following prompt value is illegal when openid is requested, but note that openid is not requested.
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"prompt": "none login", "scope": "email"}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"prompt": "none login", "scope": "email"}),
@ -2560,7 +2739,9 @@ func TestAuthorizationEndpoint(t *testing.T) {
wantDownstreamNonce: downstreamNonce, wantDownstreamNonce: downstreamNonce,
wantDownstreamPKCEChallenge: downstreamPKCEChallenge, wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod, wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: expectedHappyOIDCPasswordGrantCustomSessionWithUsernameAndGroups( wantDownstreamCustomSessionData: withUsernameAndGroupsInCustomSession(
expectedHappyOIDCPasswordGrantCustomSession,
oidcUpstreamIssuer+"?sub="+oidcUpstreamSubjectQueryEscaped,
oidcUpstreamIssuer+"?sub="+oidcUpstreamSubjectQueryEscaped, oidcUpstreamIssuer+"?sub="+oidcUpstreamSubjectQueryEscaped,
nil, nil,
), ),
@ -2589,7 +2770,9 @@ func TestAuthorizationEndpoint(t *testing.T) {
wantDownstreamNonce: downstreamNonce, wantDownstreamNonce: downstreamNonce,
wantDownstreamPKCEChallenge: downstreamPKCEChallenge, wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod, wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: expectedHappyOIDCPasswordGrantCustomSessionWithUsernameAndGroups( wantDownstreamCustomSessionData: withUsernameAndGroupsInCustomSession(
expectedHappyOIDCPasswordGrantCustomSession,
"joe@whitehouse.gov",
"joe@whitehouse.gov", "joe@whitehouse.gov",
oidcUpstreamGroupMembership, oidcUpstreamGroupMembership,
), ),
@ -2619,7 +2802,9 @@ func TestAuthorizationEndpoint(t *testing.T) {
wantDownstreamNonce: downstreamNonce, wantDownstreamNonce: downstreamNonce,
wantDownstreamPKCEChallenge: downstreamPKCEChallenge, wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod, wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: expectedHappyOIDCPasswordGrantCustomSessionWithUsernameAndGroups( wantDownstreamCustomSessionData: withUsernameAndGroupsInCustomSession(
expectedHappyOIDCPasswordGrantCustomSession,
"joe@whitehouse.gov",
"joe@whitehouse.gov", "joe@whitehouse.gov",
oidcUpstreamGroupMembership, oidcUpstreamGroupMembership,
), ),
@ -2650,7 +2835,9 @@ func TestAuthorizationEndpoint(t *testing.T) {
wantDownstreamNonce: downstreamNonce, wantDownstreamNonce: downstreamNonce,
wantDownstreamPKCEChallenge: downstreamPKCEChallenge, wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod, wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: expectedHappyOIDCPasswordGrantCustomSessionWithUsernameAndGroups( wantDownstreamCustomSessionData: withUsernameAndGroupsInCustomSession(
expectedHappyOIDCPasswordGrantCustomSession,
"joe",
"joe", "joe",
oidcUpstreamGroupMembership, oidcUpstreamGroupMembership,
), ),
@ -2713,7 +2900,9 @@ func TestAuthorizationEndpoint(t *testing.T) {
wantDownstreamNonce: downstreamNonce, wantDownstreamNonce: downstreamNonce,
wantDownstreamPKCEChallenge: downstreamPKCEChallenge, wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod, wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: expectedHappyOIDCPasswordGrantCustomSessionWithUsernameAndGroups( wantDownstreamCustomSessionData: withUsernameAndGroupsInCustomSession(
expectedHappyOIDCPasswordGrantCustomSession,
oidcUpstreamSubject,
oidcUpstreamSubject, oidcUpstreamSubject,
oidcUpstreamGroupMembership, oidcUpstreamGroupMembership,
), ),
@ -2741,7 +2930,9 @@ func TestAuthorizationEndpoint(t *testing.T) {
wantDownstreamNonce: downstreamNonce, wantDownstreamNonce: downstreamNonce,
wantDownstreamPKCEChallenge: downstreamPKCEChallenge, wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod, wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: expectedHappyOIDCPasswordGrantCustomSessionWithUsernameAndGroups( wantDownstreamCustomSessionData: withUsernameAndGroupsInCustomSession(
expectedHappyOIDCPasswordGrantCustomSession,
oidcUpstreamUsername,
oidcUpstreamUsername, oidcUpstreamUsername,
[]string{"notAnArrayGroup1 notAnArrayGroup2"}, []string{"notAnArrayGroup1 notAnArrayGroup2"},
), ),
@ -2769,7 +2960,9 @@ func TestAuthorizationEndpoint(t *testing.T) {
wantDownstreamNonce: downstreamNonce, wantDownstreamNonce: downstreamNonce,
wantDownstreamPKCEChallenge: downstreamPKCEChallenge, wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod, wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: expectedHappyOIDCPasswordGrantCustomSessionWithUsernameAndGroups( wantDownstreamCustomSessionData: withUsernameAndGroupsInCustomSession(
expectedHappyOIDCPasswordGrantCustomSession,
oidcUpstreamUsername,
oidcUpstreamUsername, oidcUpstreamUsername,
[]string{"group1", "group2"}, []string{"group1", "group2"},
), ),
@ -2811,7 +3004,9 @@ func TestAuthorizationEndpoint(t *testing.T) {
wantDownstreamNonce: downstreamNonce, wantDownstreamNonce: downstreamNonce,
wantDownstreamPKCEChallenge: downstreamPKCEChallenge, wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod, wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
wantDownstreamCustomSessionData: expectedHappyOIDCPasswordGrantCustomSessionWithUsernameAndGroups( wantDownstreamCustomSessionData: withUsernameAndGroupsInCustomSession(
expectedHappyOIDCPasswordGrantCustomSession,
oidcUpstreamUsername,
oidcUpstreamUsername, oidcUpstreamUsername,
nil, nil,
), ),
@ -3026,7 +3221,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
{ {
name: "downstream state does not have enough entropy using LDAP upstream", name: "downstream state does not have enough entropy using LDAP upstream",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()),
method: http.MethodGet, method: http.MethodGet,
path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"state": "short"}), path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"state": "short"}),
customUsernameHeader: ptr.To(happyLDAPUsername), customUsernameHeader: ptr.To(happyLDAPUsername),
@ -3115,6 +3310,15 @@ func TestAuthorizationEndpoint(t *testing.T) {
wantContentType: plainContentType, wantContentType: plainContentType,
wantBodyString: `{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. 'pinniped_idp_name' param error: identity provider not found: this federation domain does not have a default identity provider"}`, wantBodyString: `{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. 'pinniped_idp_name' param error: identity provider not found: this federation domain does not have a default identity provider"}`,
}, },
{
name: "could not find requested IDP display name",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()),
method: http.MethodGet,
path: happyGetRequestPathForLDAPUpstream, // includes param to request a different IDP display name than what is available
wantStatus: http.StatusBadRequest,
wantContentType: plainContentType,
wantBodyString: `{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. 'pinniped_idp_name' param error: did not find IDP with name 'some-ldap-idp'"}`,
},
{ {
name: "post with invalid form in the body", name: "post with invalid form in the body",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()),

View File

@ -467,10 +467,6 @@ type TestFederationDomainIdentityProvidersListerFinder struct {
defaultIDPDisplayName string defaultIDPDisplayName string
} }
func (t *TestFederationDomainIdentityProvidersListerFinder) SetDefaultIDPDisplayName(displayName string) {
t.defaultIDPDisplayName = displayName
}
func (t *TestFederationDomainIdentityProvidersListerFinder) GetOIDCIdentityProviders() []*resolvedprovider.FederationDomainResolvedOIDCIdentityProvider { func (t *TestFederationDomainIdentityProvidersListerFinder) GetOIDCIdentityProviders() []*resolvedprovider.FederationDomainResolvedOIDCIdentityProvider {
fdIDPs := make([]*resolvedprovider.FederationDomainResolvedOIDCIdentityProvider, len(t.upstreamOIDCIdentityProviders)) fdIDPs := make([]*resolvedprovider.FederationDomainResolvedOIDCIdentityProvider, len(t.upstreamOIDCIdentityProviders))
for i, testIDP := range t.upstreamOIDCIdentityProviders { for i, testIDP := range t.upstreamOIDCIdentityProviders {
@ -570,6 +566,7 @@ type UpstreamIDPListerBuilder struct {
upstreamOIDCIdentityProviders []*TestUpstreamOIDCIdentityProvider upstreamOIDCIdentityProviders []*TestUpstreamOIDCIdentityProvider
upstreamLDAPIdentityProviders []*TestUpstreamLDAPIdentityProvider upstreamLDAPIdentityProviders []*TestUpstreamLDAPIdentityProvider
upstreamActiveDirectoryIdentityProviders []*TestUpstreamLDAPIdentityProvider upstreamActiveDirectoryIdentityProviders []*TestUpstreamLDAPIdentityProvider
defaultIDPDisplayName string
} }
func (b *UpstreamIDPListerBuilder) WithOIDC(upstreamOIDCIdentityProviders ...*TestUpstreamOIDCIdentityProvider) *UpstreamIDPListerBuilder { func (b *UpstreamIDPListerBuilder) WithOIDC(upstreamOIDCIdentityProviders ...*TestUpstreamOIDCIdentityProvider) *UpstreamIDPListerBuilder {
@ -587,11 +584,17 @@ func (b *UpstreamIDPListerBuilder) WithActiveDirectory(upstreamActiveDirectoryId
return b return b
} }
func (b *UpstreamIDPListerBuilder) WithDefaultIDPDisplayName(defaultIDPDisplayName string) *UpstreamIDPListerBuilder {
b.defaultIDPDisplayName = defaultIDPDisplayName
return b
}
func (b *UpstreamIDPListerBuilder) BuildFederationDomainIdentityProvidersListerFinder() *TestFederationDomainIdentityProvidersListerFinder { func (b *UpstreamIDPListerBuilder) BuildFederationDomainIdentityProvidersListerFinder() *TestFederationDomainIdentityProvidersListerFinder {
return &TestFederationDomainIdentityProvidersListerFinder{ return &TestFederationDomainIdentityProvidersListerFinder{
upstreamOIDCIdentityProviders: b.upstreamOIDCIdentityProviders, upstreamOIDCIdentityProviders: b.upstreamOIDCIdentityProviders,
upstreamLDAPIdentityProviders: b.upstreamLDAPIdentityProviders, upstreamLDAPIdentityProviders: b.upstreamLDAPIdentityProviders,
upstreamActiveDirectoryIdentityProviders: b.upstreamActiveDirectoryIdentityProviders, upstreamActiveDirectoryIdentityProviders: b.upstreamActiveDirectoryIdentityProviders,
defaultIDPDisplayName: b.defaultIDPDisplayName,
} }
} }

View File

@ -0,0 +1,14 @@
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package testutil
import "fmt"
func AddPrefixToEach(prefix string, addToEach []string) []string {
result := make([]string, len(addToEach))
for i, s := range addToEach {
result[i] = fmt.Sprintf("%s%s", prefix, s)
}
return result
}

View File

@ -61,14 +61,6 @@ func TestSupervisorLogin_Browser(t *testing.T) {
testlib.SkipTestWhenActiveDirectoryIsUnavailable(t, env) testlib.SkipTestWhenActiveDirectoryIsUnavailable(t, env)
} }
addPrefixToEach := func(prefix string, addToEach []string) []string {
result := make([]string, len(addToEach))
for i, s := range addToEach {
result[i] = fmt.Sprintf("%s%s", prefix, s)
}
return result
}
basicOIDCIdentityProviderSpec := func() idpv1alpha1.OIDCIdentityProviderSpec { basicOIDCIdentityProviderSpec := func() idpv1alpha1.OIDCIdentityProviderSpec {
return idpv1alpha1.OIDCIdentityProviderSpec{ return idpv1alpha1.OIDCIdentityProviderSpec{
Issuer: env.SupervisorUpstreamOIDC.Issuer, Issuer: env.SupervisorUpstreamOIDC.Issuer,
@ -1891,7 +1883,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
wantDownstreamIDTokenUsernameToMatch: func(_ string) string { wantDownstreamIDTokenUsernameToMatch: func(_ string) string {
return "^" + regexp.QuoteMeta("username-prefix:"+env.SupervisorUpstreamOIDC.Username) + "$" return "^" + regexp.QuoteMeta("username-prefix:"+env.SupervisorUpstreamOIDC.Username) + "$"
}, },
wantDownstreamIDTokenGroups: addPrefixToEach("group-prefix:", env.SupervisorUpstreamOIDC.ExpectedGroups), wantDownstreamIDTokenGroups: testutil.AddPrefixToEach("group-prefix:", env.SupervisorUpstreamOIDC.ExpectedGroups),
editRefreshSessionDataWithoutBreaking: func(t *testing.T, sessionData *psession.PinnipedSession, _, _ string) []string { editRefreshSessionDataWithoutBreaking: func(t *testing.T, sessionData *psession.PinnipedSession, _, _ string) []string {
// Even if we update the groups to some names that did not come from the OIDC server, // Even if we update the groups to some names that did not come from the OIDC server,
// we expect that it will revert to the real groups from the OIDC server after we refresh. // we expect that it will revert to the real groups from the OIDC server after we refresh.
@ -1901,7 +1893,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
sessionData.Custom.UpstreamGroups = initialGroupMembership // upstream group names in session sessionData.Custom.UpstreamGroups = initialGroupMembership // upstream group names in session
sessionData.Fosite.Claims.Extra["groups"] = initialGroupMembership // downstream group names in session sessionData.Fosite.Claims.Extra["groups"] = initialGroupMembership // downstream group names in session
} }
return addPrefixToEach("group-prefix:", env.SupervisorUpstreamOIDC.ExpectedGroups) return testutil.AddPrefixToEach("group-prefix:", env.SupervisorUpstreamOIDC.ExpectedGroups)
}, },
breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) { breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) {
customSessionData := pinnipedSession.Custom customSessionData := pinnipedSession.Custom
@ -1958,7 +1950,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
initialGroupMembership := []string{"some-wrong-group", "some-other-group"} initialGroupMembership := []string{"some-wrong-group", "some-other-group"}
sessionData.Custom.UpstreamGroups = initialGroupMembership // upstream group names in session sessionData.Custom.UpstreamGroups = initialGroupMembership // upstream group names in session
sessionData.Fosite.Claims.Extra["groups"] = initialGroupMembership // downstream group names in session sessionData.Fosite.Claims.Extra["groups"] = initialGroupMembership // downstream group names in session
return addPrefixToEach("group-prefix:", env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs) return testutil.AddPrefixToEach("group-prefix:", env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs)
}, },
breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) { breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) {
customSessionData := pinnipedSession.Custom customSessionData := pinnipedSession.Custom
@ -1976,7 +1968,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
wantDownstreamIDTokenUsernameToMatch: func(_ string) string { wantDownstreamIDTokenUsernameToMatch: func(_ string) string {
return "^" + regexp.QuoteMeta("username-prefix:"+env.SupervisorUpstreamLDAP.TestUserMailAttributeValue) + "$" return "^" + regexp.QuoteMeta("username-prefix:"+env.SupervisorUpstreamLDAP.TestUserMailAttributeValue) + "$"
}, },
wantDownstreamIDTokenGroups: addPrefixToEach("group-prefix:", env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs), wantDownstreamIDTokenGroups: testutil.AddPrefixToEach("group-prefix:", env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs),
}, },
{ {
name: "ldap browser flow with email as username and groups names as DNs and using an LDAP provider which supports TLS with identity transformations", name: "ldap browser flow with email as username and groups names as DNs and using an LDAP provider which supports TLS with identity transformations",
@ -2023,7 +2015,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
initialGroupMembership := []string{"some-wrong-group", "some-other-group"} initialGroupMembership := []string{"some-wrong-group", "some-other-group"}
sessionData.Custom.UpstreamGroups = initialGroupMembership // upstream group names in session sessionData.Custom.UpstreamGroups = initialGroupMembership // upstream group names in session
sessionData.Fosite.Claims.Extra["groups"] = initialGroupMembership // downstream group names in session sessionData.Fosite.Claims.Extra["groups"] = initialGroupMembership // downstream group names in session
return addPrefixToEach("group-prefix:", env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs) return testutil.AddPrefixToEach("group-prefix:", env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs)
}, },
breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) { breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) {
customSessionData := pinnipedSession.Custom customSessionData := pinnipedSession.Custom
@ -2041,7 +2033,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
wantDownstreamIDTokenUsernameToMatch: func(_ string) string { wantDownstreamIDTokenUsernameToMatch: func(_ string) string {
return "^" + regexp.QuoteMeta("username-prefix:"+env.SupervisorUpstreamLDAP.TestUserMailAttributeValue) + "$" return "^" + regexp.QuoteMeta("username-prefix:"+env.SupervisorUpstreamLDAP.TestUserMailAttributeValue) + "$"
}, },
wantDownstreamIDTokenGroups: addPrefixToEach("group-prefix:", env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs), wantDownstreamIDTokenGroups: testutil.AddPrefixToEach("group-prefix:", env.SupervisorUpstreamLDAP.TestUserDirectGroupsDNs),
}, },
{ {
name: "active directory CLI flow with all default options with identity transformations", name: "active directory CLI flow with all default options with identity transformations",
@ -2091,7 +2083,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
initialGroupMembership := []string{"some-wrong-group", "some-other-group"} initialGroupMembership := []string{"some-wrong-group", "some-other-group"}
sessionData.Custom.UpstreamGroups = initialGroupMembership // upstream group names in session sessionData.Custom.UpstreamGroups = initialGroupMembership // upstream group names in session
sessionData.Fosite.Claims.Extra["groups"] = initialGroupMembership // downstream group names in session sessionData.Fosite.Claims.Extra["groups"] = initialGroupMembership // downstream group names in session
return addPrefixToEach("group-prefix:", env.SupervisorUpstreamActiveDirectory.TestUserIndirectGroupsSAMAccountPlusDomainNames) return testutil.AddPrefixToEach("group-prefix:", env.SupervisorUpstreamActiveDirectory.TestUserIndirectGroupsSAMAccountPlusDomainNames)
}, },
breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) { breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) {
customSessionData := pinnipedSession.Custom customSessionData := pinnipedSession.Custom
@ -2111,7 +2103,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
wantDownstreamIDTokenUsernameToMatch: func(_ string) string { wantDownstreamIDTokenUsernameToMatch: func(_ string) string {
return "^" + regexp.QuoteMeta("username-prefix:"+env.SupervisorUpstreamActiveDirectory.TestUserPrincipalNameValue) + "$" return "^" + regexp.QuoteMeta("username-prefix:"+env.SupervisorUpstreamActiveDirectory.TestUserPrincipalNameValue) + "$"
}, },
wantDownstreamIDTokenGroups: addPrefixToEach("group-prefix:", env.SupervisorUpstreamActiveDirectory.TestUserIndirectGroupsSAMAccountPlusDomainNames), wantDownstreamIDTokenGroups: testutil.AddPrefixToEach("group-prefix:", env.SupervisorUpstreamActiveDirectory.TestUserIndirectGroupsSAMAccountPlusDomainNames),
}, },
{ {
name: "active directory browser flow with all default options with identity transformations", name: "active directory browser flow with all default options with identity transformations",
@ -2158,7 +2150,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
initialGroupMembership := []string{"some-wrong-group", "some-other-group"} initialGroupMembership := []string{"some-wrong-group", "some-other-group"}
sessionData.Custom.UpstreamGroups = initialGroupMembership // upstream group names in session sessionData.Custom.UpstreamGroups = initialGroupMembership // upstream group names in session
sessionData.Fosite.Claims.Extra["groups"] = initialGroupMembership // downstream group names in session sessionData.Fosite.Claims.Extra["groups"] = initialGroupMembership // downstream group names in session
return addPrefixToEach("group-prefix:", env.SupervisorUpstreamActiveDirectory.TestUserIndirectGroupsSAMAccountPlusDomainNames) return testutil.AddPrefixToEach("group-prefix:", env.SupervisorUpstreamActiveDirectory.TestUserIndirectGroupsSAMAccountPlusDomainNames)
}, },
breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) { breakRefreshSessionData: func(t *testing.T, pinnipedSession *psession.PinnipedSession, _, _ string) {
customSessionData := pinnipedSession.Custom customSessionData := pinnipedSession.Custom
@ -2178,7 +2170,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
wantDownstreamIDTokenUsernameToMatch: func(_ string) string { wantDownstreamIDTokenUsernameToMatch: func(_ string) string {
return "^" + regexp.QuoteMeta("username-prefix:"+env.SupervisorUpstreamActiveDirectory.TestUserPrincipalNameValue) + "$" return "^" + regexp.QuoteMeta("username-prefix:"+env.SupervisorUpstreamActiveDirectory.TestUserPrincipalNameValue) + "$"
}, },
wantDownstreamIDTokenGroups: addPrefixToEach("group-prefix:", env.SupervisorUpstreamActiveDirectory.TestUserIndirectGroupsSAMAccountPlusDomainNames), wantDownstreamIDTokenGroups: testutil.AddPrefixToEach("group-prefix:", env.SupervisorUpstreamActiveDirectory.TestUserIndirectGroupsSAMAccountPlusDomainNames),
}, },
} }