add units tests to post_login_handler_test.go
This commit is contained in:
parent
f653942065
commit
7f70fcf679
@ -27,6 +27,7 @@ import (
|
|||||||
"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"
|
||||||
|
"go.pinniped.dev/internal/testutil/transformtestutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPostLoginEndpoint(t *testing.T) {
|
func TestPostLoginEndpoint(t *testing.T) {
|
||||||
@ -61,6 +62,9 @@ func TestPostLoginEndpoint(t *testing.T) {
|
|||||||
passParam = "password"
|
passParam = "password"
|
||||||
badUserPassErrParamValue = "login_error"
|
badUserPassErrParamValue = "login_error"
|
||||||
internalErrParamValue = "internal_error"
|
internalErrParamValue = "internal_error"
|
||||||
|
|
||||||
|
transformationUsernamePrefix = "username_prefix:"
|
||||||
|
transformationGroupsPrefix = "groups_prefix:"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -87,6 +91,12 @@ func TestPostLoginEndpoint(t *testing.T) {
|
|||||||
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Parameter 'prompt' was set to 'none', but contains other values as well which is not allowed.",
|
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Parameter 'prompt' was set to 'none', but contains other values as well which is not allowed.",
|
||||||
"state": happyDownstreamState,
|
"state": happyDownstreamState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fositeConfiguredPolicyRejectedAuthErrorQuery = 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": happyDownstreamState,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
happyDownstreamScopesRequested := []string{"openid", "username", "groups"}
|
happyDownstreamScopesRequested := []string{"openid", "username", "groups"}
|
||||||
@ -172,19 +182,21 @@ func TestPostLoginEndpoint(t *testing.T) {
|
|||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
upstreamLDAPIdentityProvider := oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().
|
upstreamLDAPIdentityProviderBuilder := oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().
|
||||||
WithName(ldapUpstreamName).
|
WithName(ldapUpstreamName).
|
||||||
WithResourceUID(ldapUpstreamResourceUID).
|
WithResourceUID(ldapUpstreamResourceUID).
|
||||||
WithURL(parsedUpstreamLDAPURL).
|
WithURL(parsedUpstreamLDAPURL).
|
||||||
WithAuthenticateFunc(ldapAuthenticateFunc).
|
WithAuthenticateFunc(ldapAuthenticateFunc)
|
||||||
Build()
|
|
||||||
|
|
||||||
upstreamActiveDirectoryIdentityProvider := oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().
|
upstreamLDAPIdentityProvider := upstreamLDAPIdentityProviderBuilder.Build()
|
||||||
|
|
||||||
|
upstreamActiveDirectoryIdentityProviderBuilder := oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().
|
||||||
WithName(activeDirectoryUpstreamName).
|
WithName(activeDirectoryUpstreamName).
|
||||||
WithResourceUID(activeDirectoryUpstreamResourceUID).
|
WithResourceUID(activeDirectoryUpstreamResourceUID).
|
||||||
WithURL(parsedUpstreamLDAPURL).
|
WithURL(parsedUpstreamLDAPURL).
|
||||||
WithAuthenticateFunc(ldapAuthenticateFunc).
|
WithAuthenticateFunc(ldapAuthenticateFunc)
|
||||||
Build()
|
|
||||||
|
upstreamActiveDirectoryIdentityProvider := upstreamActiveDirectoryIdentityProviderBuilder.Build()
|
||||||
|
|
||||||
erroringUpstreamLDAPIdentityProvider := oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().
|
erroringUpstreamLDAPIdentityProvider := oidctestutil.NewTestUpstreamLDAPIdentityProviderBuilder().
|
||||||
WithName(ldapUpstreamName).
|
WithName(ldapUpstreamName).
|
||||||
@ -224,6 +236,26 @@ func TestPostLoginEndpoint(t *testing.T) {
|
|||||||
ActiveDirectory: nil,
|
ActiveDirectory: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
withUsernameAndGroupsInCustomSession := func(expectedCustomSessionData *psession.CustomSessionData, wantDownstreamUsername string, wantUpstreamUsername string, wantUpstreamGroups []string) *psession.CustomSessionData {
|
||||||
|
copyOfCustomSession := *expectedCustomSessionData
|
||||||
|
if expectedCustomSessionData.LDAP != nil {
|
||||||
|
copyOfLDAP := *(expectedCustomSessionData.LDAP)
|
||||||
|
copyOfCustomSession.LDAP = ©OfLDAP
|
||||||
|
}
|
||||||
|
if expectedCustomSessionData.OIDC != nil {
|
||||||
|
copyOfOIDC := *(expectedCustomSessionData.OIDC)
|
||||||
|
copyOfCustomSession.OIDC = ©OfOIDC
|
||||||
|
}
|
||||||
|
if expectedCustomSessionData.ActiveDirectory != nil {
|
||||||
|
copyOfActiveDirectory := *(expectedCustomSessionData.ActiveDirectory)
|
||||||
|
copyOfCustomSession.ActiveDirectory = ©OfActiveDirectory
|
||||||
|
}
|
||||||
|
copyOfCustomSession.Username = wantDownstreamUsername
|
||||||
|
copyOfCustomSession.UpstreamUsername = wantUpstreamUsername
|
||||||
|
copyOfCustomSession.UpstreamGroups = wantUpstreamGroups
|
||||||
|
return ©OfCustomSession
|
||||||
|
}
|
||||||
|
|
||||||
// Note that fosite puts the granted scopes as a param in the redirect URI even though the spec doesn't seem to require it
|
// Note that fosite puts the granted scopes as a param in the redirect URI even though the spec doesn't seem to require it
|
||||||
happyAuthcodeDownstreamRedirectLocationRegexp := downstreamRedirectURI + `\?code=([^&]+)&scope=openid\+username\+groups&state=` + happyDownstreamState
|
happyAuthcodeDownstreamRedirectLocationRegexp := downstreamRedirectURI + `\?code=([^&]+)&scope=openid\+username\+groups&state=` + happyDownstreamState
|
||||||
|
|
||||||
@ -252,6 +284,9 @@ func TestPostLoginEndpoint(t *testing.T) {
|
|||||||
require.NoError(t, kubeClient.Tracker().Add(secret))
|
require.NoError(t, kubeClient.Tracker().Add(secret))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prefixUsernameAndGroupsPipeline := transformtestutil.NewPrefixingPipeline(t, transformationUsernamePrefix, transformationGroupsPrefix)
|
||||||
|
rejectAuthPipeline := transformtestutil.NewRejectAllAuthPipeline(t)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
idps *oidctestutil.UpstreamIDPListerBuilder
|
idps *oidctestutil.UpstreamIDPListerBuilder
|
||||||
@ -315,6 +350,34 @@ func TestPostLoginEndpoint(t *testing.T) {
|
|||||||
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||||
wantDownstreamCustomSessionData: expectedHappyLDAPUpstreamCustomSession,
|
wantDownstreamCustomSessionData: expectedHappyLDAPUpstreamCustomSession,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "happy LDAP login with identity transformations which modify the username and group names",
|
||||||
|
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
||||||
|
WithLDAP(upstreamLDAPIdentityProviderBuilder.WithTransformsForFederationDomain(prefixUsernameAndGroupsPipeline).Build()). // should pick this one
|
||||||
|
WithActiveDirectory(erroringUpstreamLDAPIdentityProvider),
|
||||||
|
decodedState: happyLDAPDecodedState,
|
||||||
|
formParams: happyUsernamePasswordFormParams,
|
||||||
|
wantStatus: http.StatusSeeOther,
|
||||||
|
wantContentType: htmlContentType,
|
||||||
|
wantBodyString: "",
|
||||||
|
wantRedirectLocationRegexp: happyAuthcodeDownstreamRedirectLocationRegexp,
|
||||||
|
wantDownstreamIDTokenSubject: upstreamLDAPURL + "&sub=" + happyLDAPUID,
|
||||||
|
wantDownstreamIDTokenUsername: transformationUsernamePrefix + happyLDAPUsernameFromAuthenticator,
|
||||||
|
wantDownstreamIDTokenGroups: testutil.AddPrefixToEach(transformationGroupsPrefix, happyLDAPGroups),
|
||||||
|
wantDownstreamRequestedScopes: happyDownstreamScopesRequested,
|
||||||
|
wantDownstreamRedirectURI: downstreamRedirectURI,
|
||||||
|
wantDownstreamGrantedScopes: happyDownstreamScopesGranted,
|
||||||
|
wantDownstreamNonce: downstreamNonce,
|
||||||
|
wantDownstreamClient: downstreamPinnipedCLIClientID,
|
||||||
|
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
|
||||||
|
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||||
|
wantDownstreamCustomSessionData: withUsernameAndGroupsInCustomSession(
|
||||||
|
expectedHappyLDAPUpstreamCustomSession,
|
||||||
|
transformationUsernamePrefix+happyLDAPUsernameFromAuthenticator,
|
||||||
|
happyLDAPUsernameFromAuthenticator,
|
||||||
|
happyLDAPGroups,
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "happy LDAP login with dynamic client",
|
name: "happy LDAP login with dynamic client",
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
||||||
@ -362,6 +425,34 @@ func TestPostLoginEndpoint(t *testing.T) {
|
|||||||
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||||
wantDownstreamCustomSessionData: expectedHappyActiveDirectoryUpstreamCustomSession,
|
wantDownstreamCustomSessionData: expectedHappyActiveDirectoryUpstreamCustomSession,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "happy AD login with identity transformations which modify the username and group names",
|
||||||
|
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
||||||
|
WithLDAP(erroringUpstreamLDAPIdentityProvider).
|
||||||
|
WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder.WithTransformsForFederationDomain(prefixUsernameAndGroupsPipeline).Build()), // should pick this one
|
||||||
|
decodedState: happyActiveDirectoryDecodedState,
|
||||||
|
formParams: happyUsernamePasswordFormParams,
|
||||||
|
wantStatus: http.StatusSeeOther,
|
||||||
|
wantContentType: htmlContentType,
|
||||||
|
wantBodyString: "",
|
||||||
|
wantRedirectLocationRegexp: happyAuthcodeDownstreamRedirectLocationRegexp,
|
||||||
|
wantDownstreamIDTokenSubject: upstreamLDAPURL + "&sub=" + happyLDAPUID,
|
||||||
|
wantDownstreamIDTokenUsername: transformationUsernamePrefix + happyLDAPUsernameFromAuthenticator,
|
||||||
|
wantDownstreamIDTokenGroups: testutil.AddPrefixToEach(transformationGroupsPrefix, happyLDAPGroups),
|
||||||
|
wantDownstreamRequestedScopes: happyDownstreamScopesRequested,
|
||||||
|
wantDownstreamRedirectURI: downstreamRedirectURI,
|
||||||
|
wantDownstreamGrantedScopes: happyDownstreamScopesGranted,
|
||||||
|
wantDownstreamNonce: downstreamNonce,
|
||||||
|
wantDownstreamClient: downstreamPinnipedCLIClientID,
|
||||||
|
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
|
||||||
|
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||||
|
wantDownstreamCustomSessionData: withUsernameAndGroupsInCustomSession(
|
||||||
|
expectedHappyActiveDirectoryUpstreamCustomSession,
|
||||||
|
transformationUsernamePrefix+happyLDAPUsernameFromAuthenticator,
|
||||||
|
happyLDAPUsernameFromAuthenticator,
|
||||||
|
happyLDAPGroups,
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "happy AD login with dynamic client",
|
name: "happy AD login with dynamic client",
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
||||||
@ -870,6 +961,28 @@ func TestPostLoginEndpoint(t *testing.T) {
|
|||||||
wantRedirectLocationString: urlWithQuery(downstreamRedirectURI, fositePromptHasNoneAndOtherValueErrorQuery),
|
wantRedirectLocationString: urlWithQuery(downstreamRedirectURI, fositePromptHasNoneAndOtherValueErrorQuery),
|
||||||
wantUnnecessaryStoredRecords: 1, // fosite already stored the authcode before it noticed the error
|
wantUnnecessaryStoredRecords: 1, // fosite already stored the authcode before it noticed the error
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "LDAP login using identity transformations which reject the authentication",
|
||||||
|
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
||||||
|
WithLDAP(upstreamLDAPIdentityProviderBuilder.WithTransformsForFederationDomain(rejectAuthPipeline).Build()),
|
||||||
|
decodedState: happyLDAPDecodedState,
|
||||||
|
formParams: happyUsernamePasswordFormParams,
|
||||||
|
wantStatus: http.StatusSeeOther,
|
||||||
|
wantContentType: htmlContentType,
|
||||||
|
wantBodyString: "",
|
||||||
|
wantRedirectLocationString: urlWithQuery(downstreamRedirectURI, fositeConfiguredPolicyRejectedAuthErrorQuery),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "AD login using identity transformations which reject the authentication",
|
||||||
|
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
||||||
|
WithActiveDirectory(upstreamActiveDirectoryIdentityProviderBuilder.WithTransformsForFederationDomain(rejectAuthPipeline).Build()),
|
||||||
|
decodedState: happyActiveDirectoryDecodedState,
|
||||||
|
formParams: happyUsernamePasswordFormParams,
|
||||||
|
wantStatus: http.StatusSeeOther,
|
||||||
|
wantContentType: htmlContentType,
|
||||||
|
wantBodyString: "",
|
||||||
|
wantRedirectLocationString: urlWithQuery(downstreamRedirectURI, fositeConfiguredPolicyRejectedAuthErrorQuery),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "downstream state does not have enough entropy",
|
name: "downstream state does not have enough entropy",
|
||||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider),
|
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider),
|
||||||
|
Loading…
Reference in New Issue
Block a user