add new unit tests in callback_handler_test.go
This commit is contained in:
parent
d4611b829d
commit
f653942065
@ -30,17 +30,16 @@ import (
|
||||
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/internal/authenticators"
|
||||
"go.pinniped.dev/internal/celtransformer"
|
||||
"go.pinniped.dev/internal/federationdomain/csrftoken"
|
||||
"go.pinniped.dev/internal/federationdomain/endpoints/jwks"
|
||||
"go.pinniped.dev/internal/federationdomain/oidc"
|
||||
"go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
|
||||
"go.pinniped.dev/internal/federationdomain/storage"
|
||||
"go.pinniped.dev/internal/here"
|
||||
"go.pinniped.dev/internal/idtransform"
|
||||
"go.pinniped.dev/internal/psession"
|
||||
"go.pinniped.dev/internal/testutil"
|
||||
"go.pinniped.dev/internal/testutil/oidctestutil"
|
||||
"go.pinniped.dev/internal/testutil/transformtestutil"
|
||||
"go.pinniped.dev/pkg/oidcclient/nonce"
|
||||
"go.pinniped.dev/pkg/oidcclient/pkce"
|
||||
)
|
||||
@ -612,23 +611,8 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo
|
||||
encodedIncomingCookieCSRFValue, err := happyCookieEncoder.Encode("csrf", incomingCookieCSRFValue)
|
||||
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)
|
||||
prefixUsernameAndGroupsPipeline := transformtestutil.NewPrefixingPipeline(t, transformationUsernamePrefix, transformationGroupsPrefix)
|
||||
rejectAuthPipeline := transformtestutil.NewRejectAllAuthPipeline(t)
|
||||
|
||||
type testCase struct {
|
||||
name string
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
"go.pinniped.dev/internal/psession"
|
||||
"go.pinniped.dev/internal/testutil"
|
||||
"go.pinniped.dev/internal/testutil/oidctestutil"
|
||||
"go.pinniped.dev/internal/testutil/transformtestutil"
|
||||
"go.pinniped.dev/pkg/oidcclient/nonce"
|
||||
oidcpkce "go.pinniped.dev/pkg/oidcclient/pkce"
|
||||
)
|
||||
@ -65,6 +66,9 @@ const (
|
||||
downstreamPKCEChallengeMethod = "S256"
|
||||
|
||||
htmlContentType = "text/html; charset=utf-8"
|
||||
|
||||
transformationUsernamePrefix = "username_prefix:"
|
||||
transformationGroupsPrefix = "groups_prefix:"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -102,13 +106,13 @@ var (
|
||||
UpstreamSubject: oidcUpstreamSubject,
|
||||
},
|
||||
}
|
||||
happyDownstreamCustomSessionDataWithUsernameAndGroups = func(wantUsername string, wantGroups []string) *psession.CustomSessionData {
|
||||
happyDownstreamCustomSessionDataWithUsernameAndGroups = func(wantDownstreamUsername, wantUpstreamUsername string, wantUpstreamGroups []string) *psession.CustomSessionData {
|
||||
copyOfCustomSession := *happyDownstreamCustomSessionData
|
||||
copyOfOIDC := *(happyDownstreamCustomSessionData.OIDC)
|
||||
copyOfCustomSession.OIDC = ©OfOIDC
|
||||
copyOfCustomSession.Username = wantUsername
|
||||
copyOfCustomSession.UpstreamUsername = wantUsername
|
||||
copyOfCustomSession.UpstreamGroups = wantGroups
|
||||
copyOfCustomSession.Username = wantDownstreamUsername
|
||||
copyOfCustomSession.UpstreamUsername = wantUpstreamUsername
|
||||
copyOfCustomSession.UpstreamGroups = wantUpstreamGroups
|
||||
return ©OfCustomSession
|
||||
}
|
||||
happyDownstreamAccessTokenCustomSessionData = &psession.CustomSessionData{
|
||||
@ -172,6 +176,9 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
require.NoError(t, kubeClient.Tracker().Add(secret))
|
||||
}
|
||||
|
||||
prefixUsernameAndGroupsPipeline := transformtestutil.NewPrefixingPipeline(t, transformationUsernamePrefix, transformationGroupsPrefix)
|
||||
rejectAuthPipeline := transformtestutil.NewRejectAllAuthPipeline(t)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
@ -439,7 +446,11 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
wantDownstreamClientID: downstreamPinnipedClientID,
|
||||
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
|
||||
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(oidcUpstreamIssuer+"?sub="+oidcUpstreamSubjectQueryEscaped, nil),
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(
|
||||
oidcUpstreamIssuer+"?sub="+oidcUpstreamSubjectQueryEscaped,
|
||||
oidcUpstreamIssuer+"?sub="+oidcUpstreamSubjectQueryEscaped,
|
||||
nil,
|
||||
),
|
||||
wantAuthcodeExchangeCall: &expectedAuthcodeExchange{
|
||||
performedByUpstreamName: happyUpstreamIDPName,
|
||||
args: happyExchangeAndValidateTokensArgs,
|
||||
@ -465,7 +476,11 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
wantDownstreamClientID: downstreamPinnipedClientID,
|
||||
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
|
||||
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups("joe@whitehouse.gov", oidcUpstreamGroupMembership),
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(
|
||||
"joe@whitehouse.gov",
|
||||
"joe@whitehouse.gov",
|
||||
oidcUpstreamGroupMembership,
|
||||
),
|
||||
wantAuthcodeExchangeCall: &expectedAuthcodeExchange{
|
||||
performedByUpstreamName: happyUpstreamIDPName,
|
||||
args: happyExchangeAndValidateTokensArgs,
|
||||
@ -493,7 +508,11 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
wantDownstreamClientID: downstreamPinnipedClientID,
|
||||
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
|
||||
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups("joe@whitehouse.gov", oidcUpstreamGroupMembership),
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(
|
||||
"joe@whitehouse.gov",
|
||||
"joe@whitehouse.gov",
|
||||
oidcUpstreamGroupMembership,
|
||||
),
|
||||
wantAuthcodeExchangeCall: &expectedAuthcodeExchange{
|
||||
performedByUpstreamName: happyUpstreamIDPName,
|
||||
args: happyExchangeAndValidateTokensArgs,
|
||||
@ -522,7 +541,11 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
wantDownstreamClientID: downstreamPinnipedClientID,
|
||||
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
|
||||
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups("joe", oidcUpstreamGroupMembership),
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(
|
||||
"joe",
|
||||
"joe",
|
||||
oidcUpstreamGroupMembership,
|
||||
),
|
||||
wantAuthcodeExchangeCall: &expectedAuthcodeExchange{
|
||||
performedByUpstreamName: happyUpstreamIDPName,
|
||||
args: happyExchangeAndValidateTokensArgs,
|
||||
@ -653,7 +676,11 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
wantDownstreamClientID: downstreamPinnipedClientID,
|
||||
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
|
||||
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(oidcUpstreamSubject, oidcUpstreamGroupMembership),
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(
|
||||
oidcUpstreamSubject,
|
||||
oidcUpstreamSubject,
|
||||
oidcUpstreamGroupMembership,
|
||||
),
|
||||
wantAuthcodeExchangeCall: &expectedAuthcodeExchange{
|
||||
performedByUpstreamName: happyUpstreamIDPName,
|
||||
args: happyExchangeAndValidateTokensArgs,
|
||||
@ -679,7 +706,11 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
wantDownstreamClientID: downstreamPinnipedClientID,
|
||||
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
|
||||
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(oidcUpstreamUsername, []string{"notAnArrayGroup1 notAnArrayGroup2"}),
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(
|
||||
oidcUpstreamUsername,
|
||||
oidcUpstreamUsername,
|
||||
[]string{"notAnArrayGroup1 notAnArrayGroup2"},
|
||||
),
|
||||
wantAuthcodeExchangeCall: &expectedAuthcodeExchange{
|
||||
performedByUpstreamName: happyUpstreamIDPName,
|
||||
args: happyExchangeAndValidateTokensArgs,
|
||||
@ -705,7 +736,11 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
wantDownstreamClientID: downstreamPinnipedClientID,
|
||||
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
|
||||
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(oidcUpstreamUsername, []string{"group1", "group2"}),
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(
|
||||
oidcUpstreamUsername,
|
||||
oidcUpstreamUsername,
|
||||
[]string{"group1", "group2"},
|
||||
),
|
||||
wantAuthcodeExchangeCall: &expectedAuthcodeExchange{
|
||||
performedByUpstreamName: happyUpstreamIDPName,
|
||||
args: happyExchangeAndValidateTokensArgs,
|
||||
@ -857,6 +892,35 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
args: happyExchangeAndValidateTokensArgs,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "using identity transformations which modify the username and group names",
|
||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
||||
WithOIDC(happyUpstream().WithTransformsForFederationDomain(prefixUsernameAndGroupsPipeline).Build()),
|
||||
method: http.MethodGet,
|
||||
path: newRequestPath().WithState(happyState).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantRedirectLocationRegexp: happyDownstreamRedirectLocationRegexp,
|
||||
wantBody: "",
|
||||
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
|
||||
wantDownstreamIDTokenUsername: transformationUsernamePrefix + oidcUpstreamUsername,
|
||||
wantDownstreamIDTokenGroups: testutil.AddPrefixToEach(transformationGroupsPrefix, oidcUpstreamGroupMembership),
|
||||
wantDownstreamRequestedScopes: happyDownstreamScopesRequested,
|
||||
wantDownstreamGrantedScopes: happyDownstreamScopesGranted,
|
||||
wantDownstreamNonce: downstreamNonce,
|
||||
wantDownstreamClientID: downstreamPinnipedClientID,
|
||||
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
|
||||
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(
|
||||
transformationUsernamePrefix+oidcUpstreamUsername,
|
||||
oidcUpstreamUsername,
|
||||
oidcUpstreamGroupMembership,
|
||||
),
|
||||
wantAuthcodeExchangeCall: &expectedAuthcodeExchange{
|
||||
performedByUpstreamName: happyUpstreamIDPName,
|
||||
args: happyExchangeAndValidateTokensArgs,
|
||||
},
|
||||
},
|
||||
|
||||
// Pre-upstream-exchange verification
|
||||
{
|
||||
@ -1168,7 +1232,7 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "the OIDCIdentityProvider CRD has been deleted",
|
||||
name: "the OIDCIdentityProvider resource has been deleted",
|
||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(otherUpstreamOIDCIdentityProvider),
|
||||
method: http.MethodGet,
|
||||
path: newRequestPath().WithState(happyState).String(),
|
||||
@ -1260,7 +1324,11 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
wantDownstreamClientID: downstreamPinnipedClientID,
|
||||
wantDownstreamPKCEChallenge: downstreamPKCEChallenge,
|
||||
wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod,
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(oidcUpstreamUsername, nil),
|
||||
wantDownstreamCustomSessionData: happyDownstreamCustomSessionDataWithUsernameAndGroups(
|
||||
oidcUpstreamUsername,
|
||||
oidcUpstreamUsername,
|
||||
nil,
|
||||
),
|
||||
wantAuthcodeExchangeCall: &expectedAuthcodeExchange{
|
||||
performedByUpstreamName: happyUpstreamIDPName,
|
||||
args: happyExchangeAndValidateTokensArgs,
|
||||
@ -1442,7 +1510,23 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
args: happyExchangeAndValidateTokensArgs,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "using identity transformations which reject the authentication",
|
||||
idps: oidctestutil.NewUpstreamIDPListerBuilder().
|
||||
WithOIDC(happyUpstream().WithTransformsForFederationDomain(rejectAuthPipeline).Build()),
|
||||
method: http.MethodGet,
|
||||
path: newRequestPath().WithState(happyState).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusUnprocessableEntity,
|
||||
wantContentType: htmlContentType,
|
||||
wantBody: "Unprocessable Entity: configured identity policy rejected this authentication: authentication was rejected by a configured policy\n",
|
||||
wantAuthcodeExchangeCall: &expectedAuthcodeExchange{
|
||||
performedByUpstreamName: happyUpstreamIDPName,
|
||||
args: happyExchangeAndValidateTokensArgs,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
|
||||
|
58
internal/testutil/transformtestutil/transformtestutil.go
Normal file
58
internal/testutil/transformtestutil/transformtestutil.go
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package transformtestutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"go.pinniped.dev/internal/celtransformer"
|
||||
"go.pinniped.dev/internal/idtransform"
|
||||
)
|
||||
|
||||
func NewPrefixingPipeline(t *testing.T, usernamePrefix, groupsPrefix string) *idtransform.TransformationPipeline {
|
||||
t.Helper()
|
||||
|
||||
transformer, err := celtransformer.NewCELTransformer(5 * time.Second)
|
||||
require.NoError(t, err)
|
||||
|
||||
p := idtransform.NewTransformationPipeline()
|
||||
|
||||
userTransform, err := transformer.CompileTransformation(
|
||||
&celtransformer.UsernameTransformation{Expression: fmt.Sprintf(`"%s" + username`, usernamePrefix)},
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
p.AppendTransformation(userTransform)
|
||||
|
||||
groupsTransform, err := transformer.CompileTransformation(
|
||||
&celtransformer.GroupsTransformation{Expression: fmt.Sprintf(`groups.map(g, "%s" + g)`, groupsPrefix)},
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
p.AppendTransformation(groupsTransform)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func NewRejectAllAuthPipeline(t *testing.T) *idtransform.TransformationPipeline {
|
||||
t.Helper()
|
||||
|
||||
transformer, err := celtransformer.NewCELTransformer(5 * time.Second)
|
||||
require.NoError(t, err)
|
||||
|
||||
p := idtransform.NewTransformationPipeline()
|
||||
|
||||
compiledTransform, err := transformer.CompileTransformation(
|
||||
&celtransformer.AllowAuthenticationPolicy{Expression: `false`},
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
p.AppendTransformation(compiledTransform)
|
||||
|
||||
return p
|
||||
}
|
Loading…
Reference in New Issue
Block a user