From 32aa015d5bbd7aeb93d3223a45c396a9eabf76cb Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Mon, 5 Jun 2023 14:40:39 -0700 Subject: [PATCH] Fixup unit tests for the previous commit --- .../federation_domain_watcher_test.go | 69 +++++++++++-------- .../garbage_collector_test.go | 30 ++++---- .../accesstoken/accesstoken_test.go | 30 ++++---- .../authorizationcode/authorizationcode.go | 44 +++++++----- .../authorizationcode_test.go | 34 ++++----- .../openidconnect/openidconnect_test.go | 8 +-- internal/fositestorage/pkce/pkce_test.go | 8 +-- .../refreshtoken/refreshtoken_test.go | 32 +++++---- .../provider/federation_domain_issuer_test.go | 10 ++- internal/testutil/psession.go | 12 ++-- pkg/oidcclient/login_test.go | 47 +++++++------ 11 files changed, 180 insertions(+), 144 deletions(-) diff --git a/internal/controller/supervisorconfig/federation_domain_watcher_test.go b/internal/controller/supervisorconfig/federation_domain_watcher_test.go index bf19af46..980ecac6 100644 --- a/internal/controller/supervisorconfig/federation_domain_watcher_test.go +++ b/internal/controller/supervisorconfig/federation_domain_watcher_test.go @@ -1,4 +1,4 @@ -// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package supervisorconfig @@ -42,11 +42,17 @@ func TestInformerFilters(t *testing.T) { r = require.New(t) observableWithInformerOption = testutil.NewObservableWithInformerOption() federationDomainInformer := pinnipedinformers.NewSharedInformerFactoryWithOptions(nil, 0).Config().V1alpha1().FederationDomains() + oidcIdentityProviderInformer := pinnipedinformers.NewSharedInformerFactoryWithOptions(nil, 0).IDP().V1alpha1().OIDCIdentityProviders() + ldapIdentityProviderInformer := pinnipedinformers.NewSharedInformerFactoryWithOptions(nil, 0).IDP().V1alpha1().LDAPIdentityProviders() + adIdentityProviderInformer := pinnipedinformers.NewSharedInformerFactoryWithOptions(nil, 0).IDP().V1alpha1().ActiveDirectoryIdentityProviders() _ = NewFederationDomainWatcherController( nil, nil, nil, federationDomainInformer, + oidcIdentityProviderInformer, + ldapIdentityProviderInformer, + adIdentityProviderInformer, observableWithInformerOption.WithInformer, // make it possible to observe the behavior of the Filters ) configMapInformerFilter = observableWithInformerOption.GetFilterForInformer(federationDomainInformer) @@ -100,8 +106,8 @@ func TestSync(t *testing.T) { var r *require.Assertions var subject controllerlib.Controller - var federationDomainInformerClient *pinnipedfake.Clientset - var federationDomainInformers pinnipedinformers.SharedInformerFactory + var pinnipedInformerClient *pinnipedfake.Clientset + var pinnipedInformers pinnipedinformers.SharedInformerFactory var pinnipedAPIClient *pinnipedfake.Clientset var cancelContext context.Context var cancelContextCancelFunc context.CancelFunc @@ -118,7 +124,10 @@ func TestSync(t *testing.T) { providersSetter, clocktesting.NewFakeClock(frozenNow), pinnipedAPIClient, - federationDomainInformers.Config().V1alpha1().FederationDomains(), + pinnipedInformers.Config().V1alpha1().FederationDomains(), + pinnipedInformers.IDP().V1alpha1().OIDCIdentityProviders(), + pinnipedInformers.IDP().V1alpha1().LDAPIdentityProviders(), + pinnipedInformers.IDP().V1alpha1().ActiveDirectoryIdentityProviders(), controllerlib.WithInformer, ) @@ -133,7 +142,7 @@ func TestSync(t *testing.T) { } // Must start informers before calling TestRunSynchronously() - federationDomainInformers.Start(cancelContext.Done()) + pinnipedInformers.Start(cancelContext.Done()) controllerlib.TestRunSynchronously(t, subject) } @@ -145,8 +154,8 @@ func TestSync(t *testing.T) { cancelContext, cancelContextCancelFunc = context.WithCancel(context.Background()) - federationDomainInformerClient = pinnipedfake.NewSimpleClientset() - federationDomainInformers = pinnipedinformers.NewSharedInformerFactory(federationDomainInformerClient, 0) + pinnipedInformerClient = pinnipedfake.NewSimpleClientset() + pinnipedInformers = pinnipedinformers.NewSharedInformerFactory(pinnipedInformerClient, 0) pinnipedAPIClient = pinnipedfake.NewSimpleClientset() federationDomainGVR = schema.GroupVersionResource{ @@ -172,14 +181,14 @@ func TestSync(t *testing.T) { Spec: v1alpha1.FederationDomainSpec{Issuer: "https://issuer1.com"}, } r.NoError(pinnipedAPIClient.Tracker().Add(federationDomain1)) - r.NoError(federationDomainInformerClient.Tracker().Add(federationDomain1)) + r.NoError(pinnipedInformerClient.Tracker().Add(federationDomain1)) federationDomain2 = &v1alpha1.FederationDomain{ ObjectMeta: metav1.ObjectMeta{Name: "config2", Namespace: namespace}, Spec: v1alpha1.FederationDomainSpec{Issuer: "https://issuer2.com"}, } r.NoError(pinnipedAPIClient.Tracker().Add(federationDomain2)) - r.NoError(federationDomainInformerClient.Tracker().Add(federationDomain2)) + r.NoError(pinnipedInformerClient.Tracker().Add(federationDomain2)) }) it("calls the ProvidersSetter", func() { @@ -187,10 +196,10 @@ func TestSync(t *testing.T) { err := controllerlib.TestSync(t, subject, *syncContext) r.NoError(err) - provider1, err := provider.NewFederationDomainIssuer(federationDomain1.Spec.Issuer) + provider1, err := provider.NewFederationDomainIssuer(federationDomain1.Spec.Issuer, []*provider.FederationDomainIdentityProvider{}) r.NoError(err) - provider2, err := provider.NewFederationDomainIssuer(federationDomain2.Spec.Issuer) + provider2, err := provider.NewFederationDomainIssuer(federationDomain2.Spec.Issuer, []*provider.FederationDomainIdentityProvider{}) r.NoError(err) r.True(providersSetter.SetProvidersWasCalled) @@ -250,7 +259,7 @@ func TestSync(t *testing.T) { federationDomain1.Status.LastUpdateTime = timePtr(metav1.NewTime(frozenNow)) r.NoError(pinnipedAPIClient.Tracker().Update(federationDomainGVR, federationDomain1, federationDomain1.Namespace)) - r.NoError(federationDomainInformerClient.Tracker().Update(federationDomainGVR, federationDomain1, federationDomain1.Namespace)) + r.NoError(pinnipedInformerClient.Tracker().Update(federationDomainGVR, federationDomain1, federationDomain1.Namespace)) }) it("only updates the out-of-date FederationDomain", func() { @@ -288,10 +297,10 @@ func TestSync(t *testing.T) { err := controllerlib.TestSync(t, subject, *syncContext) r.NoError(err) - provider1, err := provider.NewFederationDomainIssuer(federationDomain1.Spec.Issuer) + provider1, err := provider.NewFederationDomainIssuer(federationDomain1.Spec.Issuer, []*provider.FederationDomainIdentityProvider{}) r.NoError(err) - provider2, err := provider.NewFederationDomainIssuer(federationDomain2.Spec.Issuer) + provider2, err := provider.NewFederationDomainIssuer(federationDomain2.Spec.Issuer, []*provider.FederationDomainIdentityProvider{}) r.NoError(err) r.True(providersSetter.SetProvidersWasCalled) @@ -326,10 +335,10 @@ func TestSync(t *testing.T) { err := controllerlib.TestSync(t, subject, *syncContext) r.EqualError(err, "could not update status: some update error") - provider1, err := provider.NewFederationDomainIssuer(federationDomain1.Spec.Issuer) + provider1, err := provider.NewFederationDomainIssuer(federationDomain1.Spec.Issuer, []*provider.FederationDomainIdentityProvider{}) r.NoError(err) - provider2, err := provider.NewFederationDomainIssuer(federationDomain2.Spec.Issuer) + provider2, err := provider.NewFederationDomainIssuer(federationDomain2.Spec.Issuer, []*provider.FederationDomainIdentityProvider{}) r.NoError(err) r.True(providersSetter.SetProvidersWasCalled) @@ -393,7 +402,7 @@ func TestSync(t *testing.T) { Spec: v1alpha1.FederationDomainSpec{Issuer: "https://issuer.com"}, } r.NoError(pinnipedAPIClient.Tracker().Add(federationDomain)) - r.NoError(federationDomainInformerClient.Tracker().Add(federationDomain)) + r.NoError(pinnipedInformerClient.Tracker().Add(federationDomain)) }) when("there is a conflict while updating an FederationDomain", func() { @@ -530,14 +539,14 @@ func TestSync(t *testing.T) { Spec: v1alpha1.FederationDomainSpec{Issuer: "https://valid-issuer.com"}, } r.NoError(pinnipedAPIClient.Tracker().Add(validFederationDomain)) - r.NoError(federationDomainInformerClient.Tracker().Add(validFederationDomain)) + r.NoError(pinnipedInformerClient.Tracker().Add(validFederationDomain)) invalidFederationDomain = &v1alpha1.FederationDomain{ ObjectMeta: metav1.ObjectMeta{Name: "invalid-config", Namespace: namespace}, Spec: v1alpha1.FederationDomainSpec{Issuer: "https://invalid-issuer.com?some=query"}, } r.NoError(pinnipedAPIClient.Tracker().Add(invalidFederationDomain)) - r.NoError(federationDomainInformerClient.Tracker().Add(invalidFederationDomain)) + r.NoError(pinnipedInformerClient.Tracker().Add(invalidFederationDomain)) }) it("calls the ProvidersSetter with the valid provider", func() { @@ -545,7 +554,7 @@ func TestSync(t *testing.T) { err := controllerlib.TestSync(t, subject, *syncContext) r.NoError(err) - validProvider, err := provider.NewFederationDomainIssuer(validFederationDomain.Spec.Issuer) + validProvider, err := provider.NewFederationDomainIssuer(validFederationDomain.Spec.Issuer, []*provider.FederationDomainIdentityProvider{}) r.NoError(err) r.True(providersSetter.SetProvidersWasCalled) @@ -619,7 +628,7 @@ func TestSync(t *testing.T) { err := controllerlib.TestSync(t, subject, *syncContext) r.EqualError(err, "could not update status: some update error") - validProvider, err := provider.NewFederationDomainIssuer(validFederationDomain.Spec.Issuer) + validProvider, err := provider.NewFederationDomainIssuer(validFederationDomain.Spec.Issuer, []*provider.FederationDomainIdentityProvider{}) r.NoError(err) r.True(providersSetter.SetProvidersWasCalled) @@ -688,20 +697,20 @@ func TestSync(t *testing.T) { Spec: v1alpha1.FederationDomainSpec{Issuer: "https://iSSueR-duPlicAte.cOm/a"}, } r.NoError(pinnipedAPIClient.Tracker().Add(federationDomainDuplicate1)) - r.NoError(federationDomainInformerClient.Tracker().Add(federationDomainDuplicate1)) + r.NoError(pinnipedInformerClient.Tracker().Add(federationDomainDuplicate1)) federationDomainDuplicate2 = &v1alpha1.FederationDomain{ ObjectMeta: metav1.ObjectMeta{Name: "duplicate2", Namespace: namespace}, Spec: v1alpha1.FederationDomainSpec{Issuer: "https://issuer-duplicate.com/a"}, } r.NoError(pinnipedAPIClient.Tracker().Add(federationDomainDuplicate2)) - r.NoError(federationDomainInformerClient.Tracker().Add(federationDomainDuplicate2)) + r.NoError(pinnipedInformerClient.Tracker().Add(federationDomainDuplicate2)) federationDomain = &v1alpha1.FederationDomain{ ObjectMeta: metav1.ObjectMeta{Name: "not-duplicate", Namespace: namespace}, Spec: v1alpha1.FederationDomainSpec{Issuer: "https://issuer-duplicate.com/A"}, // different path } r.NoError(pinnipedAPIClient.Tracker().Add(federationDomain)) - r.NoError(federationDomainInformerClient.Tracker().Add(federationDomain)) + r.NoError(pinnipedInformerClient.Tracker().Add(federationDomain)) }) it("calls the ProvidersSetter with the non-duplicate", func() { @@ -709,7 +718,7 @@ func TestSync(t *testing.T) { err := controllerlib.TestSync(t, subject, *syncContext) r.NoError(err) - nonDuplicateProvider, err := provider.NewFederationDomainIssuer(federationDomain.Spec.Issuer) + nonDuplicateProvider, err := provider.NewFederationDomainIssuer(federationDomain.Spec.Issuer, []*provider.FederationDomainIdentityProvider{}) r.NoError(err) r.True(providersSetter.SetProvidersWasCalled) @@ -838,7 +847,7 @@ func TestSync(t *testing.T) { }, } r.NoError(pinnipedAPIClient.Tracker().Add(federationDomainSameIssuerAddress1)) - r.NoError(federationDomainInformerClient.Tracker().Add(federationDomainSameIssuerAddress1)) + r.NoError(pinnipedInformerClient.Tracker().Add(federationDomainSameIssuerAddress1)) federationDomainSameIssuerAddress2 = &v1alpha1.FederationDomain{ ObjectMeta: metav1.ObjectMeta{Name: "provider2", Namespace: namespace}, Spec: v1alpha1.FederationDomainSpec{ @@ -849,7 +858,7 @@ func TestSync(t *testing.T) { }, } r.NoError(pinnipedAPIClient.Tracker().Add(federationDomainSameIssuerAddress2)) - r.NoError(federationDomainInformerClient.Tracker().Add(federationDomainSameIssuerAddress2)) + r.NoError(pinnipedInformerClient.Tracker().Add(federationDomainSameIssuerAddress2)) federationDomainDifferentIssuerAddress = &v1alpha1.FederationDomain{ ObjectMeta: metav1.ObjectMeta{Name: "differentIssuerAddressProvider", Namespace: namespace}, @@ -859,7 +868,7 @@ func TestSync(t *testing.T) { }, } r.NoError(pinnipedAPIClient.Tracker().Add(federationDomainDifferentIssuerAddress)) - r.NoError(federationDomainInformerClient.Tracker().Add(federationDomainDifferentIssuerAddress)) + r.NoError(pinnipedInformerClient.Tracker().Add(federationDomainDifferentIssuerAddress)) // Also add one with a URL that cannot be parsed to make sure that the error handling // for the duplicate issuers and secret names are not confused by invalid URLs. @@ -874,7 +883,7 @@ func TestSync(t *testing.T) { }, } r.NoError(pinnipedAPIClient.Tracker().Add(federationDomainWithInvalidIssuerURL)) - r.NoError(federationDomainInformerClient.Tracker().Add(federationDomainWithInvalidIssuerURL)) + r.NoError(pinnipedInformerClient.Tracker().Add(federationDomainWithInvalidIssuerURL)) }) it("calls the ProvidersSetter with the non-duplicate", func() { @@ -882,7 +891,7 @@ func TestSync(t *testing.T) { err := controllerlib.TestSync(t, subject, *syncContext) r.NoError(err) - nonDuplicateProvider, err := provider.NewFederationDomainIssuer(federationDomainDifferentIssuerAddress.Spec.Issuer) + nonDuplicateProvider, err := provider.NewFederationDomainIssuer(federationDomainDifferentIssuerAddress.Spec.Issuer, []*provider.FederationDomainIdentityProvider{}) r.NoError(err) r.True(providersSetter.SetProvidersWasCalled) diff --git a/internal/controller/supervisorstorage/garbage_collector_test.go b/internal/controller/supervisorstorage/garbage_collector_test.go index 2266725b..4eabbad5 100644 --- a/internal/controller/supervisorstorage/garbage_collector_test.go +++ b/internal/controller/supervisorstorage/garbage_collector_test.go @@ -264,7 +264,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { when("there are valid, expired authcode secrets which contain upstream refresh tokens", func() { it.Before(func() { activeOIDCAuthcodeSession := &authorizationcode.Session{ - Version: "4", + Version: "5", Active: true, Request: &fosite.Request{ ID: "request-id-1", @@ -309,7 +309,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { r.NoError(kubeClient.Tracker().Add(activeOIDCAuthcodeSessionSecret)) inactiveOIDCAuthcodeSession := &authorizationcode.Session{ - Version: "4", + Version: "5", Active: false, Request: &fosite.Request{ ID: "request-id-2", @@ -388,7 +388,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { when("there are valid, expired authcode secrets which contain upstream access tokens", func() { it.Before(func() { activeOIDCAuthcodeSession := &authorizationcode.Session{ - Version: "4", + Version: "5", Active: true, Request: &fosite.Request{ ID: "request-id-1", @@ -433,7 +433,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { r.NoError(kubeClient.Tracker().Add(activeOIDCAuthcodeSessionSecret)) inactiveOIDCAuthcodeSession := &authorizationcode.Session{ - Version: "4", + Version: "5", Active: false, Request: &fosite.Request{ ID: "request-id-2", @@ -512,7 +512,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { when("there is an invalid, expired authcode secret", func() { it.Before(func() { invalidOIDCAuthcodeSession := &authorizationcode.Session{ - Version: "4", + Version: "5", Active: true, Request: &fosite.Request{ ID: "", // it is invalid for there to be a missing request ID @@ -581,7 +581,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { when("there is a valid, expired authcode secret but its upstream name does not match any existing upstream", func() { it.Before(func() { wrongProviderNameOIDCAuthcodeSession := &authorizationcode.Session{ - Version: "4", + Version: "5", Active: true, Request: &fosite.Request{ ID: "request-id-1", @@ -652,7 +652,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { when("there is a valid, expired authcode secret but its upstream UID does not match any existing upstream", func() { it.Before(func() { wrongProviderNameOIDCAuthcodeSession := &authorizationcode.Session{ - Version: "4", + Version: "5", Active: true, Request: &fosite.Request{ ID: "request-id-1", @@ -723,7 +723,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { when("there is a valid, recently expired authcode secret but the upstream revocation fails", func() { it.Before(func() { activeOIDCAuthcodeSession := &authorizationcode.Session{ - Version: "4", + Version: "5", Active: true, Request: &fosite.Request{ ID: "request-id-1", @@ -828,7 +828,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { when("there is a valid, long-since expired authcode secret but the upstream revocation fails", func() { it.Before(func() { activeOIDCAuthcodeSession := &authorizationcode.Session{ - Version: "4", + Version: "5", Active: true, Request: &fosite.Request{ ID: "request-id-1", @@ -907,7 +907,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { when("there are valid, expired access token secrets which contain upstream refresh tokens", func() { it.Before(func() { offlineAccessGrantedOIDCAccessTokenSession := &accesstoken.Session{ - Version: "4", + Version: "5", Request: &fosite.Request{ GrantedScope: fosite.Arguments{"scope1", "scope2", "offline_access"}, ID: "request-id-1", @@ -952,7 +952,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { r.NoError(kubeClient.Tracker().Add(offlineAccessGrantedOIDCAccessTokenSessionSecret)) offlineAccessNotGrantedOIDCAccessTokenSession := &accesstoken.Session{ - Version: "4", + Version: "5", Request: &fosite.Request{ GrantedScope: fosite.Arguments{"scope1", "scope2"}, ID: "request-id-2", @@ -1031,7 +1031,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { when("there are valid, expired access token secrets which contain upstream access tokens", func() { it.Before(func() { offlineAccessGrantedOIDCAccessTokenSession := &accesstoken.Session{ - Version: "4", + Version: "5", Request: &fosite.Request{ GrantedScope: fosite.Arguments{"scope1", "scope2", "offline_access"}, ID: "request-id-1", @@ -1076,7 +1076,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { r.NoError(kubeClient.Tracker().Add(offlineAccessGrantedOIDCAccessTokenSessionSecret)) offlineAccessNotGrantedOIDCAccessTokenSession := &accesstoken.Session{ - Version: "4", + Version: "5", Request: &fosite.Request{ GrantedScope: fosite.Arguments{"scope1", "scope2"}, ID: "request-id-2", @@ -1155,7 +1155,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { when("there are valid, expired refresh secrets which contain upstream refresh tokens", func() { it.Before(func() { oidcRefreshSession := &refreshtoken.Session{ - Version: "4", + Version: "5", Request: &fosite.Request{ ID: "request-id-1", Client: &clientregistry.Client{}, @@ -1232,7 +1232,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) { when("there are valid, expired refresh secrets which contain upstream access tokens", func() { it.Before(func() { oidcRefreshSession := &refreshtoken.Session{ - Version: "4", + Version: "5", Request: &fosite.Request{ ID: "request-id-1", Client: &clientregistry.Client{}, diff --git a/internal/fositestorage/accesstoken/accesstoken_test.go b/internal/fositestorage/accesstoken/accesstoken_test.go index 9f8e9da0..52a731f3 100644 --- a/internal/fositestorage/accesstoken/accesstoken_test.go +++ b/internal/fositestorage/accesstoken/accesstoken_test.go @@ -1,4 +1,4 @@ -// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package accesstoken @@ -54,7 +54,7 @@ func TestAccessTokenStorage(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"4"}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","upstreamUsername":"fake-upstream-username","upstreamGroups":["fake-upstream-group1","fake-upstream-group2"],"providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/access-token", @@ -123,7 +123,7 @@ func TestAccessTokenStorageRevocation(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"4"}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","upstreamUsername":"fake-upstream-username","upstreamGroups":["fake-upstream-group1","fake-upstream-group2"],"providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/access-token", @@ -196,7 +196,7 @@ func TestWrongVersion(t *testing.T) { _, err = storage.GetAccessTokenSession(ctx, "fancy-signature", nil) - require.EqualError(t, err, "access token request data has wrong version: access token session for fancy-signature has version not-the-right-version instead of 4") + require.EqualError(t, err, "access token request data has wrong version: access token session for fancy-signature has version not-the-right-version instead of 5") } func TestNilSessionRequest(t *testing.T) { @@ -214,7 +214,7 @@ func TestNilSessionRequest(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"nonsense-key": "nonsense-value","version":"4"}`), + "pinniped-storage-data": []byte(`{"nonsense-key": "nonsense-value","version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/access-token", @@ -298,13 +298,13 @@ func TestReadFromSecret(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","session":{"fosite":{"id_token_claims":{"jti": "xyz"},"headers":{"extra":{"myheader": "foo"}},"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token"}}}},"version":"4","active": true}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","session":{"fosite":{"id_token_claims":{"jti": "xyz"},"headers":{"extra":{"myheader": "foo"}},"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","upstreamUsername":"fake-upstream-username","upstreamGroups":["fake-upstream-group1","fake-upstream-group2"],"providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token"}}}},"version":"5","active": true}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/access-token", }, wantSession: &Session{ - Version: "4", + Version: "5", Request: &fosite.Request{ ID: "abcd-1", Client: &clientregistry.Client{}, @@ -316,10 +316,12 @@ func TestReadFromSecret(t *testing.T) { Headers: &jwt.Headers{Extra: map[string]interface{}{"myheader": "foo"}}, }, Custom: &psession.CustomSessionData{ - Username: "fake-username", - ProviderUID: "fake-provider-uid", - ProviderName: "fake-provider-name", - ProviderType: "fake-provider-type", + Username: "fake-username", + ProviderUID: "fake-provider-uid", + ProviderName: "fake-provider-name", + ProviderType: "fake-provider-type", + UpstreamUsername: "fake-upstream-username", + UpstreamGroups: []string{"fake-upstream-group1", "fake-upstream-group2"}, OIDC: &psession.OIDCSessionData{ UpstreamRefreshToken: "fake-upstream-refresh-token", }, @@ -339,7 +341,7 @@ func TestReadFromSecret(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1"},"version":"3","active": true}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1"},"version":"5","active": true}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/not-access-token", @@ -362,7 +364,7 @@ func TestReadFromSecret(t *testing.T) { }, Type: "storage.pinniped.dev/access-token", }, - wantErr: "access token request data has wrong version: access token session has version wrong-version-here instead of 4", + wantErr: "access token request data has wrong version: access token session has version wrong-version-here instead of 5", }, { name: "missing request", @@ -375,7 +377,7 @@ func TestReadFromSecret(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"version":"4","active": true}`), + "pinniped-storage-data": []byte(`{"version":"5","active": true}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/access-token", diff --git a/internal/fositestorage/authorizationcode/authorizationcode.go b/internal/fositestorage/authorizationcode/authorizationcode.go index abfa9e39..6c451acf 100644 --- a/internal/fositestorage/authorizationcode/authorizationcode.go +++ b/internal/fositestorage/authorizationcode/authorizationcode.go @@ -373,42 +373,48 @@ const ExpectedAuthorizeCodeSessionJSONFromFuzzing = `{ }, "custom": { "username": "Ĝ眧Ĭ", - "providerUID": "ʼn2ƋŢ觛ǂ焺nŐǛ", - "providerName": "ɥ闣ʬ橳(ý綃ʃʚƟ覣k眐4", - "providerType": "ȣ掘ʃƸ澺淗a紽ǒ|鰽", + "upstreamUsername": "ʼn2ƋŢ觛ǂ焺nŐǛ", + "upstreamGroups": [ + "闣ʬ橳(ý綃ʃʚƟ覣k眐4Ĉt", + "ʃƸ澺淗a紽ǒ|鰽ŋ猊Ia瓕巈環_ɑ" + ], + "providerUID": "ƴŤȱʀļÂ?墖", + "providerName": "7就伒犘c钡", + "providerType": "k|鬌R蜚蠣麹概÷驣7Ʀ澉1æɽ誮", "warnings": [ - "t毇妬\u003e6鉢緋uƴŤȱʀļÂ", - "虝27就伒犘c钡ɏȫ齁š" + "鷞aŚB碠k9帴ʘ赱", + "ď逳鞪?3)藵睋邔\u0026Ű惫蜀Ģ¡圔" ], "oidc": { - "upstreamRefreshToken": "OpKȱ藚ɏ¬Ê蒭堜]ȗ韚ʫ繕ȫ碰+ʫ", - "upstreamAccessToken": "k9帴", - "upstreamSubject": "磊ůď逳鞪?3)藵睋邔\u0026Ű惫蜀Ģ", - "upstreamIssuer": "4İ" + "upstreamRefreshToken": "墀jMʥ", + "upstreamAccessToken": "+î艔垎0", + "upstreamSubject": "ĝ", + "upstreamIssuer": "ǢIȽ" }, "ldap": { - "userDN": "×", + "userDN": "士b", "extraRefreshAttributes": { - "ʥ笿0D": "s" + "O灞浛a齙\\蹼偦歛ơ 皦pSǬŝ": "Džķ?吭匞饫Ƽĝ\"zvư", + "f跞@)¿,ɭS隑ip偶宾儮猷": "面@yȝƋ鬯犦獢9c5¤" } }, "activedirectory": { - "userDN": "ĝ", + "userDN": "置b", "extraRefreshAttributes": { - "IȽ齤士bEǎ": "跞@)¿,ɭS隑ip偶宾儮猷V麹", - "ȝƋ鬯犦獢9c5¤.岵": "浛a齙\\蹼偦歛" + "MN\u0026錝D肁Ŷɽ蔒PR}Ųʓl{鼐": "$+溪ŸȢŒų崓ļ憽", + "ĩŦʀ宍D挟": "q萮左/篣AÚƄŕ~čfVLPC諡}", + "姧骦:駝重EȫʆɵʮGɃ": "囤1+,Ȳ齠@ɍB鳛Nč乿ƔǴę鏶" } } } }, "requestedAudience": [ - " 皦pSǬŝ社Vƅȭǝ*擦28Dž", - "vư" + "ň" ], "grantedAudience": [ - "置b", - "筫MN\u0026錝D肁Ŷɽ蔒PR}Ųʓl{" + "â融貵捠ʼn", + "d鞕ȸ腿tʏƲ%}ſ¯Ɣ 籌Tǘ乚Ȥ2" ] }, - "version": "4" + "version": "5" }` diff --git a/internal/fositestorage/authorizationcode/authorizationcode_test.go b/internal/fositestorage/authorizationcode/authorizationcode_test.go index 05f20671..35580001 100644 --- a/internal/fositestorage/authorizationcode/authorizationcode_test.go +++ b/internal/fositestorage/authorizationcode/authorizationcode_test.go @@ -1,4 +1,4 @@ -// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package authorizationcode @@ -66,7 +66,7 @@ func TestAuthorizationCodeStorage(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"active":true,"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"4"}`), + "pinniped-storage-data": []byte(`{"active":true,"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","upstreamUsername":"fake-upstream-username","upstreamGroups":["fake-upstream-group1","fake-upstream-group2"],"providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/authcode", @@ -86,7 +86,7 @@ func TestAuthorizationCodeStorage(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"active":false,"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"4"}`), + "pinniped-storage-data": []byte(`{"active":false,"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","upstreamUsername":"fake-upstream-username","upstreamGroups":["fake-upstream-group1","fake-upstream-group2"],"providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/authcode", @@ -204,7 +204,7 @@ func TestWrongVersion(t *testing.T) { _, err = storage.GetAuthorizeCodeSession(ctx, "fancy-signature", nil) - require.EqualError(t, err, "authorization request data has wrong version: authorization code session for fancy-signature has version not-the-right-version instead of 4") + require.EqualError(t, err, "authorization request data has wrong version: authorization code session for fancy-signature has version not-the-right-version instead of 5") } func TestNilSessionRequest(t *testing.T) { @@ -219,7 +219,7 @@ func TestNilSessionRequest(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"nonsense-key": "nonsense-value", "version":"4", "active": true}`), + "pinniped-storage-data": []byte(`{"nonsense-key": "nonsense-value", "version":"5", "active": true}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/authcode", @@ -386,7 +386,7 @@ func TestFuzzAndJSONNewValidEmptyAuthorizeCodeSession(t *testing.T) { // set these to match CreateAuthorizeCodeSession so that .JSONEq works validSession.Active = true - validSession.Version = "4" + validSession.Version = "5" // update this when you update the storage version in the production code validSessionJSONBytes, err := json.MarshalIndent(validSession, "", "\t") require.NoError(t, err) @@ -395,7 +395,7 @@ func TestFuzzAndJSONNewValidEmptyAuthorizeCodeSession(t *testing.T) { // the fuzzed session and storage session should have identical JSON require.JSONEq(t, authorizeCodeSessionJSONFromFuzzing, authorizeCodeSessionJSONFromStorage) - // t.Log("actual value from fuzzing", authorizeCodeSessionJSONFromFuzzing) // can be useful when updating expected value + t.Log("actual value from fuzzing", authorizeCodeSessionJSONFromFuzzing) // can be useful when updating expected value // while the fuzzer will panic if AuthorizeRequest changes in a way that cannot be fuzzed, // if it adds a new field that can be fuzzed, this check will fail @@ -421,13 +421,13 @@ func TestReadFromSecret(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","session":{"fosite":{"id_token_claims":{"jti": "xyz"},"headers":{"extra":{"myheader": "foo"}},"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token"}}}},"version":"4","active": true}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","session":{"fosite":{"id_token_claims":{"jti": "xyz"},"headers":{"extra":{"myheader": "foo"}},"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","upstreamUsername":"fake-upstream-username","upstreamGroups":["fake-upstream-group1","fake-upstream-group2"],"providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token"}}}},"version":"5","active": true}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/authcode", }, wantSession: &Session{ - Version: "4", + Version: "5", Active: true, Request: &fosite.Request{ ID: "abcd-1", @@ -440,10 +440,12 @@ func TestReadFromSecret(t *testing.T) { Headers: &jwt.Headers{Extra: map[string]interface{}{"myheader": "foo"}}, }, Custom: &psession.CustomSessionData{ - Username: "fake-username", - ProviderUID: "fake-provider-uid", - ProviderName: "fake-provider-name", - ProviderType: "fake-provider-type", + Username: "fake-username", + ProviderUID: "fake-provider-uid", + ProviderName: "fake-provider-name", + ProviderType: "fake-provider-type", + UpstreamUsername: "fake-upstream-username", + UpstreamGroups: []string{"fake-upstream-group1", "fake-upstream-group2"}, OIDC: &psession.OIDCSessionData{ UpstreamRefreshToken: "fake-upstream-refresh-token", }, @@ -463,7 +465,7 @@ func TestReadFromSecret(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1"},"version":"3","active": true}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1"},"version":"5","active": true}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/not-authcode", @@ -486,7 +488,7 @@ func TestReadFromSecret(t *testing.T) { }, Type: "storage.pinniped.dev/authcode", }, - wantErr: "authorization request data has wrong version: authorization code session has version wrong-version-here instead of 4", + wantErr: "authorization request data has wrong version: authorization code session has version wrong-version-here instead of 5", }, { name: "missing request", @@ -499,7 +501,7 @@ func TestReadFromSecret(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"version":"4","active": true}`), + "pinniped-storage-data": []byte(`{"version":"5","active": true}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/authcode", diff --git a/internal/fositestorage/openidconnect/openidconnect_test.go b/internal/fositestorage/openidconnect/openidconnect_test.go index 7297710b..e4740ac7 100644 --- a/internal/fositestorage/openidconnect/openidconnect_test.go +++ b/internal/fositestorage/openidconnect/openidconnect_test.go @@ -1,4 +1,4 @@ -// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package openidconnect @@ -52,7 +52,7 @@ func TestOpenIdConnectStorage(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"4"}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","upstreamUsername":"fake-upstream-username","upstreamGroups":["fake-upstream-group1","fake-upstream-group2"],"providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/oidc", @@ -137,7 +137,7 @@ func TestWrongVersion(t *testing.T) { _, err = storage.GetOpenIDConnectSession(ctx, "fancy-code.fancy-signature", nil) - require.EqualError(t, err, "oidc request data has wrong version: oidc session for fancy-signature has version not-the-right-version instead of 4") + require.EqualError(t, err, "oidc request data has wrong version: oidc session for fancy-signature has version not-the-right-version instead of 5") } func TestNilSessionRequest(t *testing.T) { @@ -152,7 +152,7 @@ func TestNilSessionRequest(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"nonsense-key": "nonsense-value","version":"4"}`), + "pinniped-storage-data": []byte(`{"nonsense-key": "nonsense-value","version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/oidc", diff --git a/internal/fositestorage/pkce/pkce_test.go b/internal/fositestorage/pkce/pkce_test.go index 46461611..f0a24fd4 100644 --- a/internal/fositestorage/pkce/pkce_test.go +++ b/internal/fositestorage/pkce/pkce_test.go @@ -1,4 +1,4 @@ -// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package pkce @@ -52,7 +52,7 @@ func TestPKCEStorage(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"4"}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","upstreamUsername":"fake-upstream-username","upstreamGroups":["fake-upstream-group1","fake-upstream-group2"],"providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/pkce", @@ -140,7 +140,7 @@ func TestWrongVersion(t *testing.T) { _, err = storage.GetPKCERequestSession(ctx, "fancy-signature", nil) - require.EqualError(t, err, "pkce request data has wrong version: pkce session for fancy-signature has version not-the-right-version instead of 4") + require.EqualError(t, err, "pkce request data has wrong version: pkce session for fancy-signature has version not-the-right-version instead of 5") } func TestNilSessionRequest(t *testing.T) { @@ -158,7 +158,7 @@ func TestNilSessionRequest(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"nonsense-key": "nonsense-value","version":"4"}`), + "pinniped-storage-data": []byte(`{"nonsense-key": "nonsense-value","version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/pkce", diff --git a/internal/fositestorage/refreshtoken/refreshtoken_test.go b/internal/fositestorage/refreshtoken/refreshtoken_test.go index e785347d..8e2826b9 100644 --- a/internal/fositestorage/refreshtoken/refreshtoken_test.go +++ b/internal/fositestorage/refreshtoken/refreshtoken_test.go @@ -1,4 +1,4 @@ -// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package refreshtoken @@ -53,7 +53,7 @@ func TestRefreshTokenStorage(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"4"}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","upstreamUsername":"fake-upstream-username","upstreamGroups":["fake-upstream-group1","fake-upstream-group2"],"providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/refresh-token", @@ -123,7 +123,7 @@ func TestRefreshTokenStorageRevocation(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"4"}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","upstreamUsername":"fake-upstream-username","upstreamGroups":["fake-upstream-group1","fake-upstream-group2"],"providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/refresh-token", @@ -178,7 +178,7 @@ func TestRefreshTokenStorageRevokeRefreshTokenMaybeGracePeriod(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"4"}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","requestedAt":"0001-01-01T00:00:00Z","client":{"id":"pinny","redirect_uris":null,"grant_types":null,"response_types":null,"scopes":null,"audience":null,"public":true,"jwks_uri":"where","jwks":null,"token_endpoint_auth_method":"something","request_uris":null,"request_object_signing_alg":"","token_endpoint_auth_signing_alg":""},"scopes":null,"grantedScopes":null,"form":{"key":["val"]},"session":{"fosite":{"id_token_claims":null,"headers":null,"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","upstreamUsername":"fake-upstream-username","upstreamGroups":["fake-upstream-group1","fake-upstream-group2"],"providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","warnings":null,"oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token","upstreamAccessToken":"","upstreamSubject":"some-subject","upstreamIssuer":"some-issuer"}}},"requestedAudience":null,"grantedAudience":null},"version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/refresh-token", @@ -252,7 +252,7 @@ func TestWrongVersion(t *testing.T) { _, err = storage.GetRefreshTokenSession(ctx, "fancy-signature", nil) - require.EqualError(t, err, "refresh token request data has wrong version: refresh token session for fancy-signature has version not-the-right-version instead of 4") + require.EqualError(t, err, "refresh token request data has wrong version: refresh token session for fancy-signature has version not-the-right-version instead of 5") } func TestNilSessionRequest(t *testing.T) { @@ -270,7 +270,7 @@ func TestNilSessionRequest(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"nonsense-key": "nonsense-value","version":"4"}`), + "pinniped-storage-data": []byte(`{"nonsense-key": "nonsense-value","version":"5"}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/refresh-token", @@ -354,13 +354,13 @@ func TestReadFromSecret(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","session":{"fosite":{"id_token_claims":{"jti": "xyz"},"headers":{"extra":{"myheader": "foo"}},"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token"}}}},"version":"4","active": true}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1","session":{"fosite":{"id_token_claims":{"jti": "xyz"},"headers":{"extra":{"myheader": "foo"}},"expires_at":null,"username":"snorlax","subject":"panda"},"custom":{"username":"fake-username","upstreamUsername":"fake-upstream-username","upstreamGroups":["fake-upstream-group1","fake-upstream-group2"],"providerUID":"fake-provider-uid","providerName":"fake-provider-name","providerType":"fake-provider-type","oidc":{"upstreamRefreshToken":"fake-upstream-refresh-token"}}}},"version":"5","active": true}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/refresh-token", }, wantSession: &Session{ - Version: "4", + Version: "5", Request: &fosite.Request{ ID: "abcd-1", Client: &clientregistry.Client{}, @@ -372,10 +372,12 @@ func TestReadFromSecret(t *testing.T) { Headers: &jwt.Headers{Extra: map[string]interface{}{"myheader": "foo"}}, }, Custom: &psession.CustomSessionData{ - Username: "fake-username", - ProviderUID: "fake-provider-uid", - ProviderName: "fake-provider-name", - ProviderType: "fake-provider-type", + Username: "fake-username", + ProviderUID: "fake-provider-uid", + ProviderName: "fake-provider-name", + ProviderType: "fake-provider-type", + UpstreamUsername: "fake-upstream-username", + UpstreamGroups: []string{"fake-upstream-group1", "fake-upstream-group2"}, OIDC: &psession.OIDCSessionData{ UpstreamRefreshToken: "fake-upstream-refresh-token", }, @@ -395,7 +397,7 @@ func TestReadFromSecret(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1"},"version":"4","active": true}`), + "pinniped-storage-data": []byte(`{"request":{"id":"abcd-1"},"version":"5","active": true}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/not-refresh-token", @@ -418,7 +420,7 @@ func TestReadFromSecret(t *testing.T) { }, Type: "storage.pinniped.dev/refresh-token", }, - wantErr: "refresh token request data has wrong version: refresh token session has version wrong-version-here instead of 4", + wantErr: "refresh token request data has wrong version: refresh token session has version wrong-version-here instead of 5", }, { name: "missing request", @@ -431,7 +433,7 @@ func TestReadFromSecret(t *testing.T) { }, }, Data: map[string][]byte{ - "pinniped-storage-data": []byte(`{"version":"4","active": true}`), + "pinniped-storage-data": []byte(`{"version":"5","active": true}`), "pinniped-storage-version": []byte("1"), }, Type: "storage.pinniped.dev/refresh-token", diff --git a/internal/oidc/provider/federation_domain_issuer_test.go b/internal/oidc/provider/federation_domain_issuer_test.go index 7f10dd33..b80bff19 100644 --- a/internal/oidc/provider/federation_domain_issuer_test.go +++ b/internal/oidc/provider/federation_domain_issuer_test.go @@ -82,7 +82,15 @@ func TestFederationDomainIssuerValidations(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - _, err := NewFederationDomainIssuer(tt.issuer) + _, err := NewFederationDomainIssuer(tt.issuer, nil) + if tt.wantError != "" { + require.EqualError(t, err, tt.wantError) + } else { + require.NoError(t, err) + } + + // This alternate constructor should perform all the same validations on the issuer string. + _, err = NewFederationDomainIssuerWithDefaultIDP(tt.issuer, nil) if tt.wantError != "" { require.EqualError(t, err, tt.wantError) } else { diff --git a/internal/testutil/psession.go b/internal/testutil/psession.go index 88eb658b..8efbcf25 100644 --- a/internal/testutil/psession.go +++ b/internal/testutil/psession.go @@ -1,4 +1,4 @@ -// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved. +// Copyright 2021-2023 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package testutil @@ -24,10 +24,12 @@ func NewFakePinnipedSession() *psession.PinnipedSession { Subject: "panda", }, Custom: &psession.CustomSessionData{ - Username: "fake-username", - ProviderUID: "fake-provider-uid", - ProviderType: "fake-provider-type", - ProviderName: "fake-provider-name", + Username: "fake-username", + ProviderUID: "fake-provider-uid", + ProviderType: "fake-provider-type", + ProviderName: "fake-provider-name", + UpstreamUsername: "fake-upstream-username", + UpstreamGroups: []string{"fake-upstream-group1", "fake-upstream-group2"}, OIDC: &psession.OIDCSessionData{ UpstreamRefreshToken: "fake-upstream-refresh-token", UpstreamSubject: "some-subject", diff --git a/pkg/oidcclient/login_test.go b/pkg/oidcclient/login_test.go index fa896aa9..e0b08adc 100644 --- a/pkg/oidcclient/login_test.go +++ b/pkg/oidcclient/login_test.go @@ -321,10 +321,11 @@ func TestLogin(t *testing.T) { //nolint:gocyclo cache := &mockSessionCache{t: t, getReturnsToken: nil} cacheKey := SessionCacheKey{ - Issuer: successServer.URL, - ClientID: "test-client-id", - Scopes: []string{"test-scope"}, - RedirectURI: "http://localhost:0/callback", + Issuer: successServer.URL, + ClientID: "test-client-id", + Scopes: []string{"test-scope"}, + RedirectURI: "http://localhost:0/callback", + UpstreamProviderName: "some-upstream-name", } t.Cleanup(func() { require.Equal(t, []SessionCacheKey{cacheKey}, cache.sawGetKeys) @@ -916,7 +917,7 @@ func TestLogin(t *testing.T) { //nolint:gocyclo wantToken: &testToken, }, { - name: "upstream name and type are included in authorize request if upstream name is provided", + name: "upstream name and type are included in authorize request and session cache key if upstream name is provided", clientID: "test-client-id", opt: func(t *testing.T) Option { return func(h *handlerState) error { @@ -926,10 +927,11 @@ func TestLogin(t *testing.T) { //nolint:gocyclo cache := &mockSessionCache{t: t, getReturnsToken: nil} cacheKey := SessionCacheKey{ - Issuer: successServer.URL, - ClientID: "test-client-id", - Scopes: []string{"test-scope"}, - RedirectURI: "http://localhost:0/callback", + Issuer: successServer.URL, + ClientID: "test-client-id", + Scopes: []string{"test-scope"}, + RedirectURI: "http://localhost:0/callback", + UpstreamProviderName: "some-upstream-name", } t.Cleanup(func() { require.Equal(t, []SessionCacheKey{cacheKey}, cache.sawGetKeys) @@ -1207,10 +1209,11 @@ func TestLogin(t *testing.T) { //nolint:gocyclo cache := &mockSessionCache{t: t, getReturnsToken: nil} cacheKey := SessionCacheKey{ - Issuer: successServer.URL, - ClientID: "test-client-id", - Scopes: []string{"test-scope"}, - RedirectURI: "http://localhost:0/callback", + Issuer: successServer.URL, + ClientID: "test-client-id", + Scopes: []string{"test-scope"}, + RedirectURI: "http://localhost:0/callback", + UpstreamProviderName: "some-upstream-name", } t.Cleanup(func() { require.Equal(t, []SessionCacheKey{cacheKey}, cache.sawGetKeys) @@ -1314,10 +1317,11 @@ func TestLogin(t *testing.T) { //nolint:gocyclo cache := &mockSessionCache{t: t, getReturnsToken: nil} cacheKey := SessionCacheKey{ - Issuer: successServer.URL, - ClientID: "test-client-id", - Scopes: []string{"test-scope"}, - RedirectURI: "http://localhost:0/callback", + Issuer: successServer.URL, + ClientID: "test-client-id", + Scopes: []string{"test-scope"}, + RedirectURI: "http://localhost:0/callback", + UpstreamProviderName: "some-upstream-name", } t.Cleanup(func() { require.Equal(t, []SessionCacheKey{cacheKey}, cache.sawGetKeys) @@ -1425,10 +1429,11 @@ func TestLogin(t *testing.T) { //nolint:gocyclo cache := &mockSessionCache{t: t, getReturnsToken: nil} cacheKey := SessionCacheKey{ - Issuer: successServer.URL, - ClientID: "test-client-id", - Scopes: []string{"test-scope"}, - RedirectURI: "http://localhost:0/callback", + Issuer: successServer.URL, + ClientID: "test-client-id", + Scopes: []string{"test-scope"}, + RedirectURI: "http://localhost:0/callback", + UpstreamProviderName: "some-upstream-name", } t.Cleanup(func() { require.Equal(t, []SessionCacheKey{cacheKey}, cache.sawGetKeys)