From 84041e0c55c5b92b6380ba84247b48a8735a2774 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Wed, 19 Jul 2023 14:56:46 -0700 Subject: [PATCH] add unit test for ApplyIdentityTransformations helper --- internal/celtransformer/celformer.go | 2 +- internal/celtransformer/celformer_test.go | 2 +- .../federation_domain_watcher_test.go | 2 +- .../downstreamsession/downstream_session.go | 3 +- .../downstream_session_test.go | 86 +++++++++++++++++++ 5 files changed, 90 insertions(+), 5 deletions(-) diff --git a/internal/celtransformer/celformer.go b/internal/celtransformer/celformer.go index 085af4502..e88b5bfda 100644 --- a/internal/celtransformer/celformer.go +++ b/internal/celtransformer/celformer.go @@ -29,7 +29,7 @@ const ( constStringVariableName = "strConst" constStringListVariableName = "strListConst" - DefaultPolicyRejectedAuthMessage = "Authentication was rejected by a configured policy" + DefaultPolicyRejectedAuthMessage = "authentication was rejected by a configured policy" ) // CELTransformer can compile any number of transformation expression pipelines. diff --git a/internal/celtransformer/celformer_test.go b/internal/celtransformer/celformer_test.go index a38a1b236..10a148b1e 100644 --- a/internal/celtransformer/celformer_test.go +++ b/internal/celtransformer/celformer_test.go @@ -101,7 +101,7 @@ func TestTransformer(t *testing.T) { wantUsername: "ryan", wantGroups: []string{"admins", "developers", "other"}, wantAuthRejected: true, - wantAuthRejectedMessage: `Authentication was rejected by a configured policy`, + wantAuthRejectedMessage: `authentication was rejected by a configured policy`, }, { name: "any transformations can use the username and group variables", diff --git a/internal/controller/supervisorconfig/federation_domain_watcher_test.go b/internal/controller/supervisorconfig/federation_domain_watcher_test.go index 4bf20fafb..41287aeab 100644 --- a/internal/controller/supervisorconfig/federation_domain_watcher_test.go +++ b/internal/controller/supervisorconfig/federation_domain_watcher_test.go @@ -1953,7 +1953,7 @@ func TestTestFederationDomainWatcherControllerSync(t *testing.T) { Username: "rejectMeWithDefaultMessage", Expects: configv1alpha1.FederationDomainTransformsExampleExpects{ Rejected: true, - Message: "Authentication was rejected by a configured policy", // this is the default message + Message: "authentication was rejected by a configured policy", // this is the default message }, }, }, diff --git a/internal/federationdomain/downstreamsession/downstream_session.go b/internal/federationdomain/downstreamsession/downstream_session.go index 6a5f70fe8..c7f3b4e8e 100644 --- a/internal/federationdomain/downstreamsession/downstream_session.go +++ b/internal/federationdomain/downstreamsession/downstream_session.go @@ -41,7 +41,6 @@ const ( emailVerifiedClaimInvalidFormatErr = constable.Error("email_verified claim in upstream ID token has invalid format") emailVerifiedClaimFalseErr = constable.Error("email_verified claim in upstream ID token has false value") idTransformUnexpectedErr = constable.Error("configured identity transformation or policy resulted in unexpected error") - idTransformPolicyErr = constable.Error("configured identity policy rejected this authentication") ) // MakeDownstreamSession creates a downstream OIDC session. @@ -262,7 +261,7 @@ func ApplyIdentityTransformations( } if !transformationResult.AuthenticationAllowed { plog.Debug("authentication rejected by configured policy", "inputUsername", username, "inputGroups", groups) - return "", nil, idTransformPolicyErr + return "", nil, fmt.Errorf("configured identity policy rejected this authentication: %s", transformationResult.RejectedAuthenticationMessage) } plog.Debug("identity transformation successfully applied during authentication", "originalUsername", username, diff --git a/internal/federationdomain/downstreamsession/downstream_session_test.go b/internal/federationdomain/downstreamsession/downstream_session_test.go index d6effd4b1..ea584934f 100644 --- a/internal/federationdomain/downstreamsession/downstream_session_test.go +++ b/internal/federationdomain/downstreamsession/downstream_session_test.go @@ -4,10 +4,14 @@ package downstreamsession import ( + "context" "testing" + "time" "github.com/stretchr/testify/require" + "go.pinniped.dev/internal/celtransformer" + "go.pinniped.dev/internal/idtransform" "go.pinniped.dev/internal/testutil/oidctestutil" ) @@ -70,3 +74,85 @@ func TestMapAdditionalClaimsFromUpstreamIDToken(t *testing.T) { }) } } + +func TestApplyIdentityTransformations(t *testing.T) { + tests := []struct { + name string + transforms []celtransformer.CELTransformation + username string + groups []string + wantUsername string + wantGroups []string + wantErr string + }{ + { + name: "unexpected errors", + transforms: []celtransformer.CELTransformation{ + &celtransformer.UsernameTransformation{Expression: `""`}, + }, + username: "ryan", + groups: []string{"a", "b"}, + wantErr: "configured identity transformation or policy resulted in unexpected error", + }, + { + name: "auth disallowed by policy with implicit rejection message", + transforms: []celtransformer.CELTransformation{ + &celtransformer.AllowAuthenticationPolicy{Expression: `false`}, + }, + username: "ryan", + groups: []string{"a", "b"}, + wantErr: "configured identity policy rejected this authentication: authentication was rejected by a configured policy", + }, + { + name: "auth disallowed by policy with explicit rejection message", + transforms: []celtransformer.CELTransformation{ + &celtransformer.AllowAuthenticationPolicy{ + Expression: `false`, + RejectedAuthenticationMessage: "this is the stated reason", + }, + }, + username: "ryan", + groups: []string{"a", "b"}, + wantErr: "configured identity policy rejected this authentication: this is the stated reason", + }, + { + name: "successful auth", + transforms: []celtransformer.CELTransformation{ + &celtransformer.UsernameTransformation{Expression: `"pre:" + username`}, + &celtransformer.GroupsTransformation{Expression: `groups.map(g, "pre:" + g)`}, + }, + username: "ryan", + groups: []string{"a", "b"}, + wantUsername: "pre:ryan", + wantGroups: []string{"pre:a", "pre:b"}, + }, + } + + for _, test := range tests { + tt := test + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + transformer, err := celtransformer.NewCELTransformer(5 * time.Second) + require.NoError(t, err) + + pipeline := idtransform.NewTransformationPipeline() + for _, transform := range tt.transforms { + compiledTransform, err := transformer.CompileTransformation(transform, nil) + require.NoError(t, err) + pipeline.AppendTransformation(compiledTransform) + } + + gotUsername, gotGroups, err := ApplyIdentityTransformations(context.Background(), pipeline, tt.username, tt.groups) + if tt.wantErr != "" { + require.EqualError(t, err, tt.wantErr) + require.Empty(t, gotUsername) + require.Nil(t, gotGroups) + } else { + require.NoError(t, err) + require.Equal(t, tt.wantUsername, gotUsername) + require.Equal(t, tt.wantGroups, gotGroups) + } + }) + } +}