reorganize federation domain packages to be more intuitive

Co-authored-by: Benjamin A. Petersen <ben@benjaminapetersen.me>
This commit is contained in:
Ryan Richard 2023-06-22 15:12:33 -07:00
parent 3160b5bad1
commit 86c791b8a6
101 changed files with 401 additions and 377 deletions

View File

@ -26,7 +26,7 @@ import (
"go.pinniped.dev/internal/controller/conditionsutil" "go.pinniped.dev/internal/controller/conditionsutil"
"go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers" "go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers"
"go.pinniped.dev/internal/controllerlib" "go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider" "go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/upstreamldap" "go.pinniped.dev/internal/upstreamldap"
) )

View File

@ -29,9 +29,9 @@ import (
"go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers" "go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers"
"go.pinniped.dev/internal/controllerlib" "go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/endpointaddr" "go.pinniped.dev/internal/endpointaddr"
"go.pinniped.dev/internal/federationdomain/dynamicupstreamprovider"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/mocks/mockldapconn" "go.pinniped.dev/internal/mocks/mockldapconn"
"go.pinniped.dev/internal/oidc/provider"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/internal/upstreamldap" "go.pinniped.dev/internal/upstreamldap"
) )
@ -2010,7 +2010,7 @@ func TestActiveDirectoryUpstreamWatcherControllerSync(t *testing.T) {
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0) pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakeKubeClient := fake.NewSimpleClientset(tt.inputSecrets...) fakeKubeClient := fake.NewSimpleClientset(tt.inputSecrets...)
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0) kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
cache := provider.NewDynamicUpstreamIDPProvider() cache := dynamicupstreamprovider.NewDynamicUpstreamIDPProvider()
cache.SetActiveDirectoryIdentityProviders([]upstreamprovider.UpstreamLDAPIdentityProviderI{ cache.SetActiveDirectoryIdentityProviders([]upstreamprovider.UpstreamLDAPIdentityProviderI{
upstreamldap.New(upstreamldap.ProviderConfig{Name: "initial-entry"}), upstreamldap.New(upstreamldap.ProviderConfig{Name: "initial-entry"}),
}) })

View File

@ -25,8 +25,8 @@ import (
"go.pinniped.dev/internal/celtransformer" "go.pinniped.dev/internal/celtransformer"
pinnipedcontroller "go.pinniped.dev/internal/controller" pinnipedcontroller "go.pinniped.dev/internal/controller"
"go.pinniped.dev/internal/controllerlib" "go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/federationdomain/federationdomainproviders"
"go.pinniped.dev/internal/idtransform" "go.pinniped.dev/internal/idtransform"
"go.pinniped.dev/internal/oidc/provider/federationdomainproviders"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
) )

View File

@ -27,8 +27,8 @@ import (
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake" pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions" pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/controllerlib" "go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/federationdomain/federationdomainproviders"
"go.pinniped.dev/internal/here" "go.pinniped.dev/internal/here"
"go.pinniped.dev/internal/oidc/provider/federationdomainproviders"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
) )

View File

@ -20,7 +20,7 @@ import (
"go.pinniped.dev/internal/controller/conditionsutil" "go.pinniped.dev/internal/controller/conditionsutil"
"go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers" "go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers"
"go.pinniped.dev/internal/controllerlib" "go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider" "go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/upstreamldap" "go.pinniped.dev/internal/upstreamldap"
) )

View File

@ -28,9 +28,9 @@ import (
"go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers" "go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers"
"go.pinniped.dev/internal/controllerlib" "go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/endpointaddr" "go.pinniped.dev/internal/endpointaddr"
"go.pinniped.dev/internal/federationdomain/dynamicupstreamprovider"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/mocks/mockldapconn" "go.pinniped.dev/internal/mocks/mockldapconn"
"go.pinniped.dev/internal/oidc/provider"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/internal/upstreamldap" "go.pinniped.dev/internal/upstreamldap"
) )
@ -1139,7 +1139,7 @@ func TestLDAPUpstreamWatcherControllerSync(t *testing.T) {
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0) pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakeKubeClient := fake.NewSimpleClientset(tt.inputSecrets...) fakeKubeClient := fake.NewSimpleClientset(tt.inputSecrets...)
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0) kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
cache := provider.NewDynamicUpstreamIDPProvider() cache := dynamicupstreamprovider.NewDynamicUpstreamIDPProvider()
cache.SetLDAPIdentityProviders([]upstreamprovider.UpstreamLDAPIdentityProviderI{ cache.SetLDAPIdentityProviders([]upstreamprovider.UpstreamLDAPIdentityProviderI{
upstreamldap.New(upstreamldap.ProviderConfig{Name: "initial-entry"}), upstreamldap.New(upstreamldap.ProviderConfig{Name: "initial-entry"}),
}) })

View File

@ -21,7 +21,7 @@ import (
pinnipedcontroller "go.pinniped.dev/internal/controller" pinnipedcontroller "go.pinniped.dev/internal/controller"
"go.pinniped.dev/internal/controller/conditionsutil" "go.pinniped.dev/internal/controller/conditionsutil"
"go.pinniped.dev/internal/controllerlib" "go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/oidc/oidcclientvalidator" "go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
"go.pinniped.dev/internal/oidcclientsecretstorage" "go.pinniped.dev/internal/oidcclientsecretstorage"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
) )

View File

@ -34,8 +34,8 @@ import (
"go.pinniped.dev/internal/controller/conditionsutil" "go.pinniped.dev/internal/controller/conditionsutil"
"go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers" "go.pinniped.dev/internal/controller/supervisorconfig/upstreamwatchers"
"go.pinniped.dev/internal/controllerlib" "go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/net/phttp" "go.pinniped.dev/internal/net/phttp"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/upstreamoidc" "go.pinniped.dev/internal/upstreamoidc"
) )
@ -94,7 +94,7 @@ type UpstreamOIDCIdentityProviderICache interface {
SetOIDCIdentityProviders([]upstreamprovider.UpstreamOIDCIdentityProviderI) SetOIDCIdentityProviders([]upstreamprovider.UpstreamOIDCIdentityProviderI)
} }
// lruValidatorCache caches the *oidc.Provider associated with a particular issuer/TLS configuration. // lruValidatorCache caches the *coreosoidc.Provider associated with a particular issuer/TLS configuration.
type lruValidatorCache struct{ cache *cache.Expiring } type lruValidatorCache struct{ cache *cache.Expiring }
type lruValidatorCacheEntry struct { type lruValidatorCacheEntry struct {

View File

@ -28,8 +28,8 @@ import (
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions" pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/certauthority" "go.pinniped.dev/internal/certauthority"
"go.pinniped.dev/internal/controllerlib" "go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/oidc/provider" "go.pinniped.dev/internal/federationdomain/dynamicupstreamprovider"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider" "go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/internal/testutil/oidctestutil" "go.pinniped.dev/internal/testutil/oidctestutil"
@ -81,7 +81,7 @@ func TestOIDCUpstreamWatcherControllerFilterSecret(t *testing.T) {
pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0) pinnipedInformers := pinnipedinformers.NewSharedInformerFactory(fakePinnipedClient, 0)
fakeKubeClient := fake.NewSimpleClientset() fakeKubeClient := fake.NewSimpleClientset()
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0) kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
cache := provider.NewDynamicUpstreamIDPProvider() cache := dynamicupstreamprovider.NewDynamicUpstreamIDPProvider()
cache.SetOIDCIdentityProviders([]upstreamprovider.UpstreamOIDCIdentityProviderI{ cache.SetOIDCIdentityProviders([]upstreamprovider.UpstreamOIDCIdentityProviderI{
&upstreamoidc.ProviderConfig{Name: "initial-entry"}, &upstreamoidc.ProviderConfig{Name: "initial-entry"},
}) })
@ -1416,7 +1416,7 @@ oidc: issuer did not match the issuer returned by provider, expected "` + testIs
fakeKubeClient := fake.NewSimpleClientset(tt.inputSecrets...) fakeKubeClient := fake.NewSimpleClientset(tt.inputSecrets...)
kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0) kubeInformers := informers.NewSharedInformerFactory(fakeKubeClient, 0)
testLog := testlogger.NewLegacy(t) //nolint:staticcheck // old test with lots of log statements testLog := testlogger.NewLegacy(t) //nolint:staticcheck // old test with lots of log statements
cache := provider.NewDynamicUpstreamIDPProvider() cache := dynamicupstreamprovider.NewDynamicUpstreamIDPProvider()
cache.SetOIDCIdentityProviders([]upstreamprovider.UpstreamOIDCIdentityProviderI{ cache.SetOIDCIdentityProviders([]upstreamprovider.UpstreamOIDCIdentityProviderI{
&upstreamoidc.ProviderConfig{Name: "initial-entry"}, &upstreamoidc.ProviderConfig{Name: "initial-entry"},
}) })

View File

@ -16,7 +16,7 @@ import (
"go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1" "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
"go.pinniped.dev/internal/constable" "go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider" "go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/upstreamldap" "go.pinniped.dev/internal/upstreamldap"
) )

View File

@ -21,13 +21,13 @@ import (
pinnipedcontroller "go.pinniped.dev/internal/controller" pinnipedcontroller "go.pinniped.dev/internal/controller"
"go.pinniped.dev/internal/controllerlib" "go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/crud" "go.pinniped.dev/internal/crud"
"go.pinniped.dev/internal/federationdomain/dynamicupstreamprovider"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/fositestorage/accesstoken" "go.pinniped.dev/internal/fositestorage/accesstoken"
"go.pinniped.dev/internal/fositestorage/authorizationcode" "go.pinniped.dev/internal/fositestorage/authorizationcode"
"go.pinniped.dev/internal/fositestorage/openidconnect" "go.pinniped.dev/internal/fositestorage/openidconnect"
"go.pinniped.dev/internal/fositestorage/pkce" "go.pinniped.dev/internal/fositestorage/pkce"
"go.pinniped.dev/internal/fositestorage/refreshtoken" "go.pinniped.dev/internal/fositestorage/refreshtoken"
"go.pinniped.dev/internal/oidc/provider"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
) )
@ -144,7 +144,7 @@ func (c *garbageCollectorController) Sync(ctx controllerlib.Context) error {
// cleaning them out of etcd storage. // cleaning them out of etcd storage.
fourHoursAgo := frozenClock.Now().Add(-4 * time.Hour) fourHoursAgo := frozenClock.Now().Add(-4 * time.Hour)
nowIsLessThanFourHoursBeyondSecretGCTime := garbageCollectAfterTime.After(fourHoursAgo) nowIsLessThanFourHoursBeyondSecretGCTime := garbageCollectAfterTime.After(fourHoursAgo)
if errors.As(revokeErr, &provider.RetryableRevocationError{}) && nowIsLessThanFourHoursBeyondSecretGCTime { if errors.As(revokeErr, &dynamicupstreamprovider.RetryableRevocationError{}) && nowIsLessThanFourHoursBeyondSecretGCTime {
// Hasn't been very long since secret expired, so skip deletion to try revocation again later. // Hasn't been very long since secret expired, so skip deletion to try revocation again later.
plog.Trace("garbage collector keeping Secret to retry upstream OIDC token revocation later", logKV(secret)...) plog.Trace("garbage collector keeping Secret to retry upstream OIDC token revocation later", logKV(secret)...)
continue continue

View File

@ -25,12 +25,12 @@ import (
clocktesting "k8s.io/utils/clock/testing" clocktesting "k8s.io/utils/clock/testing"
"go.pinniped.dev/internal/controllerlib" "go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/federationdomain/dynamicupstreamprovider"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/fositestorage/accesstoken" "go.pinniped.dev/internal/fositestorage/accesstoken"
"go.pinniped.dev/internal/fositestorage/authorizationcode" "go.pinniped.dev/internal/fositestorage/authorizationcode"
"go.pinniped.dev/internal/fositestorage/refreshtoken" "go.pinniped.dev/internal/fositestorage/refreshtoken"
"go.pinniped.dev/internal/oidc/clientregistry"
"go.pinniped.dev/internal/oidc/provider"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"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"
@ -138,7 +138,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) {
// Defer starting the informers until the last possible moment so that the // Defer starting the informers until the last possible moment so that the
// nested Before's can keep adding things to the informer caches. // nested Before's can keep adding things to the informer caches.
var startInformersAndController = func(idpCache provider.DynamicUpstreamIDPProvider) { var startInformersAndController = func(idpCache dynamicupstreamprovider.DynamicUpstreamIDPProvider) {
// Set this at the last second to allow for injection of server override. // Set this at the last second to allow for injection of server override.
subject = GarbageCollectorController( subject = GarbageCollectorController(
idpCache, idpCache,
@ -774,7 +774,7 @@ func TestGarbageCollectorControllerSync(t *testing.T) {
WithName("upstream-oidc-provider-name"). WithName("upstream-oidc-provider-name").
WithResourceUID("upstream-oidc-provider-uid"). WithResourceUID("upstream-oidc-provider-uid").
// make the upstream revocation fail in a retryable way // make the upstream revocation fail in a retryable way
WithRevokeTokenError(provider.NewRetryableRevocationError(errors.New("some retryable upstream revocation error"))) WithRevokeTokenError(dynamicupstreamprovider.NewRetryableRevocationError(errors.New("some retryable upstream revocation error")))
idpListerBuilder := oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(happyOIDCUpstream.Build()) idpListerBuilder := oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(happyOIDCUpstream.Build())
startInformersAndController(idpListerBuilder.BuildDynamicUpstreamIDPProvider()) startInformersAndController(idpListerBuilder.BuildDynamicUpstreamIDPProvider())

View File

@ -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 // SPDX-License-Identifier: Apache-2.0
// Package clientregistry defines Pinniped's OAuth2/OIDC clients. // Package clientregistry defines Pinniped's OAuth2/OIDC clients.
@ -18,7 +18,7 @@ import (
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1" configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc" oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
supervisorclient "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1" supervisorclient "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1"
"go.pinniped.dev/internal/oidc/oidcclientvalidator" "go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
"go.pinniped.dev/internal/oidcclientsecretstorage" "go.pinniped.dev/internal/oidcclientsecretstorage"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
) )

View File

@ -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 // SPDX-License-Identifier: Apache-2.0
package clientregistry package clientregistry
@ -21,7 +21,7 @@ import (
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1" configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake" supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/oidc/oidcclientvalidator" "go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
"go.pinniped.dev/internal/oidcclientsecretstorage" "go.pinniped.dev/internal/oidcclientsecretstorage"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
) )

View File

@ -1,4 +1,4 @@
// Copyright 2022 the Pinniped contributors. All Rights Reserved. // Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Package csp defines helpers related to HTML Content Security Policies. // Package csp defines helpers related to HTML Content Security Policies.

View File

@ -1,4 +1,4 @@
// Copyright 2022 the Pinniped contributors. All Rights Reserved. // Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package csp package csp

View File

@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package csrftoken package csrftoken

View File

@ -1,4 +1,4 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved. // Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package csrftoken package csrftoken

View File

@ -20,9 +20,9 @@ import (
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc" oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/authenticators" "go.pinniped.dev/internal/authenticators"
"go.pinniped.dev/internal/constable" "go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/idtransform" "go.pinniped.dev/internal/idtransform"
"go.pinniped.dev/internal/oidc"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
"go.pinniped.dev/pkg/oidcclient/oidctypes" "go.pinniped.dev/pkg/oidcclient/oidctypes"

View File

@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Package dynamiccodec provides a type that can encode information using a just-in-time signing and // Package dynamiccodec provides a type that can encode information using a just-in-time signing and
@ -10,7 +10,7 @@ import (
"github.com/gorilla/securecookie" "github.com/gorilla/securecookie"
"go.pinniped.dev/internal/oidc" "go.pinniped.dev/internal/federationdomain/oidc"
) )
var _ oidc.Codec = &Codec{} var _ oidc.Codec = &Codec{}

View File

@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package dynamiccodec package dynamiccodec

View File

@ -1,7 +1,7 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package provider package dynamictlscertprovider
import ( import (
"crypto/tls" "crypto/tls"

View File

@ -1,13 +1,13 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package provider package dynamicupstreamprovider
import ( import (
"fmt" "fmt"
"sync" "sync"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider" "go.pinniped.dev/internal/federationdomain/upstreamprovider"
) )
type DynamicUpstreamIDPProvider interface { type DynamicUpstreamIDPProvider interface {

View File

@ -16,17 +16,17 @@ import (
"golang.org/x/oauth2" "golang.org/x/oauth2"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc" oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/federationdomain/csrftoken"
"go.pinniped.dev/internal/federationdomain/downstreamsession"
"go.pinniped.dev/internal/federationdomain/endpoints/login"
"go.pinniped.dev/internal/federationdomain/federationdomainproviders"
"go.pinniped.dev/internal/federationdomain/formposthtml"
"go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/federationdomain/resolvedprovider"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/httputil/httperr" "go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/httputil/securityheader" "go.pinniped.dev/internal/httputil/securityheader"
"go.pinniped.dev/internal/idtransform" "go.pinniped.dev/internal/idtransform"
"go.pinniped.dev/internal/oidc"
"go.pinniped.dev/internal/oidc/csrftoken"
"go.pinniped.dev/internal/oidc/downstreamsession"
"go.pinniped.dev/internal/oidc/login"
"go.pinniped.dev/internal/oidc/provider/federationdomainproviders"
"go.pinniped.dev/internal/oidc/provider/formposthtml"
"go.pinniped.dev/internal/oidc/provider/resolvedprovider"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
"go.pinniped.dev/pkg/oidcclient/nonce" "go.pinniped.dev/pkg/oidcclient/nonce"

View File

@ -30,11 +30,12 @@ import (
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake" supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1" "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1"
"go.pinniped.dev/internal/authenticators" "go.pinniped.dev/internal/authenticators"
"go.pinniped.dev/internal/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/here"
"go.pinniped.dev/internal/oidc"
"go.pinniped.dev/internal/oidc/csrftoken"
"go.pinniped.dev/internal/oidc/jwks"
"go.pinniped.dev/internal/oidc/oidcclientvalidator"
"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"
@ -232,18 +233,18 @@ func TestAuthorizationEndpoint(t *testing.T) {
jwksProviderIsUnused := jwks.NewDynamicJWKSProvider() jwksProviderIsUnused := jwks.NewDynamicJWKSProvider()
timeoutsConfiguration := oidc.DefaultOIDCTimeoutsConfiguration() timeoutsConfiguration := oidc.DefaultOIDCTimeoutsConfiguration()
createOauthHelperWithRealStorage := func(secretsClient v1.SecretInterface, oidcClientsClient v1alpha1.OIDCClientInterface) (fosite.OAuth2Provider, *oidc.KubeStorage) { createOauthHelperWithRealStorage := func(secretsClient v1.SecretInterface, oidcClientsClient v1alpha1.OIDCClientInterface) (fosite.OAuth2Provider, *storage.KubeStorage) {
// Configure fosite the same way that the production code would when using Kube storage. // Configure fosite the same way that the production code would when using Kube storage.
// Inject this into our test subject at the last second so we get a fresh storage for every test. // Inject this into our test subject at the last second so we get a fresh storage for every test.
// Use lower minimum required bcrypt cost than we would use in production to keep unit the tests fast. // Use lower minimum required bcrypt cost than we would use in production to keep unit the tests fast.
kubeOauthStore := oidc.NewKubeStorage(secretsClient, oidcClientsClient, timeoutsConfiguration, bcrypt.MinCost) kubeOauthStore := storage.NewKubeStorage(secretsClient, oidcClientsClient, timeoutsConfiguration, bcrypt.MinCost)
return oidc.FositeOauth2Helper(kubeOauthStore, downstreamIssuer, hmacSecretFunc, jwksProviderIsUnused, timeoutsConfiguration), kubeOauthStore return oidc.FositeOauth2Helper(kubeOauthStore, downstreamIssuer, hmacSecretFunc, jwksProviderIsUnused, timeoutsConfiguration), kubeOauthStore
} }
createOauthHelperWithNullStorage := func(secretsClient v1.SecretInterface, oidcClientsClient v1alpha1.OIDCClientInterface) (fosite.OAuth2Provider, *oidc.NullStorage) { createOauthHelperWithNullStorage := func(secretsClient v1.SecretInterface, oidcClientsClient v1alpha1.OIDCClientInterface) (fosite.OAuth2Provider, *storage.NullStorage) {
// Configure fosite the same way that the production code would, using NullStorage to turn off storage. // Configure fosite the same way that the production code would, using NullStorage to turn off storage.
// Use lower minimum required bcrypt cost than we would use in production to keep unit the tests fast. // Use lower minimum required bcrypt cost than we would use in production to keep unit the tests fast.
nullOauthStore := oidc.NewNullStorage(secretsClient, oidcClientsClient, bcrypt.MinCost) nullOauthStore := storage.NewNullStorage(secretsClient, oidcClientsClient, bcrypt.MinCost)
return oidc.FositeOauth2Helper(nullOauthStore, downstreamIssuer, hmacSecretFunc, jwksProviderIsUnused, timeoutsConfiguration), nullOauthStore return oidc.FositeOauth2Helper(nullOauthStore, downstreamIssuer, hmacSecretFunc, jwksProviderIsUnused, timeoutsConfiguration), nullOauthStore
} }
@ -3175,7 +3176,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
}, },
} }
runOneTestCase := func(t *testing.T, test testCase, subject http.Handler, kubeOauthStore *oidc.KubeStorage, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset, secretsClient v1.SecretInterface) { runOneTestCase := func(t *testing.T, test testCase, subject http.Handler, kubeOauthStore *storage.KubeStorage, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset, secretsClient v1.SecretInterface) {
if test.kubeResources != nil { if test.kubeResources != nil {
test.kubeResources(t, supervisorClient, kubeClient) test.kubeResources(t, supervisorClient, kubeClient)
} }

View File

@ -10,12 +10,12 @@ import (
"github.com/ory/fosite" "github.com/ory/fosite"
"go.pinniped.dev/internal/federationdomain/downstreamsession"
"go.pinniped.dev/internal/federationdomain/federationdomainproviders"
"go.pinniped.dev/internal/federationdomain/formposthtml"
"go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/httputil/httperr" "go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/httputil/securityheader" "go.pinniped.dev/internal/httputil/securityheader"
"go.pinniped.dev/internal/oidc"
"go.pinniped.dev/internal/oidc/downstreamsession"
"go.pinniped.dev/internal/oidc/provider/federationdomainproviders"
"go.pinniped.dev/internal/oidc/provider/formposthtml"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
) )

View File

@ -21,9 +21,10 @@ import (
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1" configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake" supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/oidc" "go.pinniped.dev/internal/federationdomain/endpoints/jwks"
"go.pinniped.dev/internal/oidc/jwks" "go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/oidc/oidcclientvalidator" "go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
"go.pinniped.dev/internal/federationdomain/storage"
"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"
@ -1451,7 +1452,7 @@ func TestCallbackEndpoint(t *testing.T) {
// Inject this into our test subject at the last second so we get a fresh storage for every test. // Inject this into our test subject at the last second so we get a fresh storage for every test.
timeoutsConfiguration := oidc.DefaultOIDCTimeoutsConfiguration() timeoutsConfiguration := oidc.DefaultOIDCTimeoutsConfiguration()
// Use lower minimum required bcrypt cost than we would use in production to keep unit the tests fast. // Use lower minimum required bcrypt cost than we would use in production to keep unit the tests fast.
oauthStore := oidc.NewKubeStorage(secrets, oidcClientsClient, timeoutsConfiguration, bcrypt.MinCost) oauthStore := storage.NewKubeStorage(secrets, oidcClientsClient, timeoutsConfiguration, bcrypt.MinCost)
hmacSecretFunc := func() []byte { return []byte("some secret - must have at least 32 bytes") } hmacSecretFunc := func() []byte { return []byte("some secret - must have at least 32 bytes") }
require.GreaterOrEqual(t, len(hmacSecretFunc()), 32, "fosite requires that hmac secrets have at least 32 bytes") require.GreaterOrEqual(t, len(hmacSecretFunc()), 32, "fosite requires that hmac secrets have at least 32 bytes")
jwksProviderIsUnused := jwks.NewDynamicJWKSProvider() jwksProviderIsUnused := jwks.NewDynamicJWKSProvider()

View File

@ -11,7 +11,7 @@ import (
"go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1" "go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc" oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/oidc" "go.pinniped.dev/internal/federationdomain/oidc"
) )
// Metadata holds all fields (that we care about) from the OpenID Provider Metadata section in the // Metadata holds all fields (that we care about) from the OpenID Provider Metadata section in the

View File

@ -10,8 +10,8 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/here" "go.pinniped.dev/internal/here"
"go.pinniped.dev/internal/oidc"
) )
func TestDiscovery(t *testing.T) { func TestDiscovery(t *testing.T) {

View File

@ -11,7 +11,7 @@ import (
"sort" "sort"
"go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1" "go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
"go.pinniped.dev/internal/oidc/provider/federationdomainproviders" "go.pinniped.dev/internal/federationdomain/federationdomainproviders"
) )
// NewHandler returns an http.Handler that serves the upstream IDP discovery endpoint. // NewHandler returns an http.Handler that serves the upstream IDP discovery endpoint.

View File

@ -10,8 +10,8 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/here" "go.pinniped.dev/internal/here"
"go.pinniped.dev/internal/oidc"
"go.pinniped.dev/internal/testutil/oidctestutil" "go.pinniped.dev/internal/testutil/oidctestutil"
) )

View File

@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package jwks package jwks

View File

@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Package discovery provides a handler for the OIDC discovery endpoint. // Package discovery provides a handler for the OIDC discovery endpoint.

View File

@ -1,4 +1,4 @@
// Copyright 2020 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package jwks package jwks

View File

@ -1,4 +1,4 @@
// Copyright 2022 the Pinniped contributors. All Rights Reserved. // Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package login package login
@ -6,8 +6,8 @@ package login
import ( import (
"net/http" "net/http"
"go.pinniped.dev/internal/oidc" "go.pinniped.dev/internal/federationdomain/endpoints/login/loginhtml"
"go.pinniped.dev/internal/oidc/login/loginhtml" "go.pinniped.dev/internal/federationdomain/oidc"
) )
const ( const (

View File

@ -10,9 +10,9 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.pinniped.dev/internal/oidc" "go.pinniped.dev/internal/federationdomain/endpoints/login/loginhtml"
"go.pinniped.dev/internal/oidc/idplister" "go.pinniped.dev/internal/federationdomain/idplister"
"go.pinniped.dev/internal/oidc/login/loginhtml" "go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
) )

View File

@ -1,4 +1,4 @@
// Copyright 2022 the Pinniped contributors. All Rights Reserved. // Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package login package login
@ -8,11 +8,11 @@ import (
"net/url" "net/url"
idpdiscoveryv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1" idpdiscoveryv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
"go.pinniped.dev/internal/federationdomain/endpoints/login/loginhtml"
"go.pinniped.dev/internal/federationdomain/formposthtml"
"go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/httputil/httperr" "go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/httputil/securityheader" "go.pinniped.dev/internal/httputil/securityheader"
"go.pinniped.dev/internal/oidc"
"go.pinniped.dev/internal/oidc/login/loginhtml"
"go.pinniped.dev/internal/oidc/provider/formposthtml"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
) )

View File

@ -1,4 +1,4 @@
// Copyright 2022 the Pinniped contributors. All Rights Reserved. // Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package login package login
@ -13,8 +13,8 @@ import (
"github.com/gorilla/securecookie" "github.com/gorilla/securecookie"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/httputil/httperr" "go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/oidc"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/internal/testutil/oidctestutil" "go.pinniped.dev/internal/testutil/oidctestutil"
) )

View File

@ -1,4 +1,4 @@
/* Copyright 2022 the Pinniped contributors. All Rights Reserved. */ /* Copyright 2022-2023 the Pinniped contributors. All Rights Reserved. */
/* SPDX-License-Identifier: Apache-2.0 */ /* SPDX-License-Identifier: Apache-2.0 */
html { html {

View File

@ -1,5 +1,5 @@
<!-- <!--
Copyright 2022 the Pinniped contributors. All Rights Reserved. Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Notes: Notes:

View File

@ -1,4 +1,4 @@
// Copyright 2022 the Pinniped contributors. All Rights Reserved. // Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Package loginhtml defines HTML templates used by the Supervisor. // Package loginhtml defines HTML templates used by the Supervisor.
@ -11,7 +11,7 @@ import (
"github.com/tdewolff/minify/v2/minify" "github.com/tdewolff/minify/v2/minify"
"go.pinniped.dev/internal/oidc/provider/csp" "go.pinniped.dev/internal/federationdomain/csp"
) )
//nolint:gochecknoglobals // This package uses globals to ensure that all parsing and minifying happens at init. //nolint:gochecknoglobals // This package uses globals to ensure that all parsing and minifying happens at init.

View File

@ -1,4 +1,4 @@
// Copyright 2022 the Pinniped contributors. All Rights Reserved. // Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package loginhtml package loginhtml
@ -8,9 +8,9 @@ import (
"fmt" "fmt"
"testing" "testing"
"go.pinniped.dev/internal/testutil"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.pinniped.dev/internal/testutil"
) )
var ( var (

View File

@ -9,10 +9,10 @@ import (
"github.com/ory/fosite" "github.com/ory/fosite"
"go.pinniped.dev/internal/federationdomain/downstreamsession"
"go.pinniped.dev/internal/federationdomain/federationdomainproviders"
"go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/httputil/httperr" "go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/oidc"
"go.pinniped.dev/internal/oidc/downstreamsession"
"go.pinniped.dev/internal/oidc/provider/federationdomainproviders"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
) )

View File

@ -20,9 +20,10 @@ import (
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1" configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake" supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/authenticators" "go.pinniped.dev/internal/authenticators"
"go.pinniped.dev/internal/oidc" "go.pinniped.dev/internal/federationdomain/endpoints/jwks"
"go.pinniped.dev/internal/oidc/jwks" "go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/oidc/oidcclientvalidator" "go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
"go.pinniped.dev/internal/federationdomain/storage"
"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"
@ -978,7 +979,7 @@ func TestPostLoginEndpoint(t *testing.T) {
// Inject this into our test subject at the last second so we get a fresh storage for every test. // Inject this into our test subject at the last second so we get a fresh storage for every test.
timeoutsConfiguration := oidc.DefaultOIDCTimeoutsConfiguration() timeoutsConfiguration := oidc.DefaultOIDCTimeoutsConfiguration()
// Use lower minimum required bcrypt cost than we would use in production to keep unit the tests fast. // Use lower minimum required bcrypt cost than we would use in production to keep unit the tests fast.
kubeOauthStore := oidc.NewKubeStorage(secretsClient, oidcClientsClient, timeoutsConfiguration, bcrypt.MinCost) kubeOauthStore := storage.NewKubeStorage(secretsClient, oidcClientsClient, timeoutsConfiguration, bcrypt.MinCost)
hmacSecretFunc := func() []byte { return []byte("some secret - must have at least 32 bytes") } hmacSecretFunc := func() []byte { return []byte("some secret - must have at least 32 bytes") }
require.GreaterOrEqual(t, len(hmacSecretFunc()), 32, "fosite requires that hmac secrets have at least 32 bytes") require.GreaterOrEqual(t, len(hmacSecretFunc()), 32, "fosite requires that hmac secrets have at least 32 bytes")
jwksProviderIsUnused := jwks.NewDynamicJWKSProvider() jwksProviderIsUnused := jwks.NewDynamicJWKSProvider()

View File

@ -18,13 +18,13 @@ import (
"k8s.io/utils/strings/slices" "k8s.io/utils/strings/slices"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc" oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/federationdomain/downstreamsession"
"go.pinniped.dev/internal/federationdomain/federationdomainproviders"
"go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/federationdomain/resolvedprovider"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/httputil/httperr" "go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/idtransform" "go.pinniped.dev/internal/idtransform"
"go.pinniped.dev/internal/oidc"
"go.pinniped.dev/internal/oidc/downstreamsession"
"go.pinniped.dev/internal/oidc/provider/federationdomainproviders"
"go.pinniped.dev/internal/oidc/provider/resolvedprovider"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
) )

View File

@ -24,7 +24,7 @@ import (
"github.com/ory/fosite" "github.com/ory/fosite"
fositeoauth2 "github.com/ory/fosite/handler/oauth2" fositeoauth2 "github.com/ory/fosite/handler/oauth2"
"github.com/ory/fosite/handler/openid" "github.com/ory/fosite/handler/openid"
"github.com/ory/fosite/handler/pkce" fositepkce "github.com/ory/fosite/handler/pkce"
"github.com/ory/fosite/token/jwt" "github.com/ory/fosite/token/jwt"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -42,19 +42,20 @@ import (
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1" configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake" supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/crud" "go.pinniped.dev/internal/crud"
"go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/federationdomain/endpoints/jwks"
"go.pinniped.dev/internal/federationdomain/federationdomainproviders"
"go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
"go.pinniped.dev/internal/federationdomain/storage"
"go.pinniped.dev/internal/fositestorage/accesstoken" "go.pinniped.dev/internal/fositestorage/accesstoken"
"go.pinniped.dev/internal/fositestorage/authorizationcode" "go.pinniped.dev/internal/fositestorage/authorizationcode"
"go.pinniped.dev/internal/fositestorage/openidconnect" "go.pinniped.dev/internal/fositestorage/openidconnect"
storagepkce "go.pinniped.dev/internal/fositestorage/pkce" "go.pinniped.dev/internal/fositestorage/pkce"
"go.pinniped.dev/internal/fositestorage/refreshtoken" "go.pinniped.dev/internal/fositestorage/refreshtoken"
"go.pinniped.dev/internal/fositestoragei" "go.pinniped.dev/internal/fositestoragei"
"go.pinniped.dev/internal/here" "go.pinniped.dev/internal/here"
"go.pinniped.dev/internal/httputil/httperr" "go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/oidc"
"go.pinniped.dev/internal/oidc/clientregistry"
"go.pinniped.dev/internal/oidc/jwks"
"go.pinniped.dev/internal/oidc/oidcclientvalidator"
"go.pinniped.dev/internal/oidc/provider/federationdomainproviders"
"go.pinniped.dev/internal/oidcclientsecretstorage" "go.pinniped.dev/internal/oidcclientsecretstorage"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
@ -955,7 +956,7 @@ func TestTokenEndpointWhenAuthcodeIsUsedTwice(t *testing.T) {
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: openidconnect.TypeLabelValue}, 1) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: openidconnect.TypeLabelValue}, 1)
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: accesstoken.TypeLabelValue}, 0) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: accesstoken.TypeLabelValue}, 0)
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: refreshtoken.TypeLabelValue}, 0) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: refreshtoken.TypeLabelValue}, 0)
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: storagepkce.TypeLabelValue}, 0) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: pkce.TypeLabelValue}, 0)
// Assert the number of all secrets, excluding any OIDCClient's storage secret, since those are not related to session storage. // Assert the number of all secrets, excluding any OIDCClient's storage secret, since those are not related to session storage.
testutil.RequireNumberOfSecretsExcludingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: oidcclientsecretstorage.TypeLabelValue}, 2) testutil.RequireNumberOfSecretsExcludingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: oidcclientsecretstorage.TypeLabelValue}, 2)
}) })
@ -1005,7 +1006,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
authcodeExchange authcodeExchangeInputs authcodeExchange authcodeExchangeInputs
modifyRequestParams func(t *testing.T, params url.Values) modifyRequestParams func(t *testing.T, params url.Values)
modifyRequestHeaders func(r *http.Request) modifyRequestHeaders func(r *http.Request)
modifyStorage func(t *testing.T, storage *oidc.KubeStorage, secrets v1.SecretInterface, pendingRequest *http.Request) modifyStorage func(t *testing.T, storage *storage.KubeStorage, secrets v1.SecretInterface, pendingRequest *http.Request)
requestedAudience string requestedAudience string
kubeResources func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) kubeResources func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset)
@ -1452,7 +1453,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
name: "valid access token, but it was already deleted from storage", name: "valid access token, but it was already deleted from storage",
authcodeExchange: doValidAuthCodeExchange, authcodeExchange: doValidAuthCodeExchange,
requestedAudience: "some-workload-cluster", requestedAudience: "some-workload-cluster",
modifyStorage: func(t *testing.T, storage *oidc.KubeStorage, secrets v1.SecretInterface, pendingRequest *http.Request) { modifyStorage: func(t *testing.T, storage *storage.KubeStorage, secrets v1.SecretInterface, pendingRequest *http.Request) {
parts := strings.Split(pendingRequest.Form.Get("subject_token"), ".") parts := strings.Split(pendingRequest.Form.Get("subject_token"), ".")
require.Len(t, parts, 2) require.Len(t, parts, 2)
require.NoError(t, storage.DeleteAccessTokenSession(context.Background(), parts[1])) require.NoError(t, storage.DeleteAccessTokenSession(context.Background(), parts[1]))
@ -1465,7 +1466,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
name: "valid access token, but it has already expired", name: "valid access token, but it has already expired",
authcodeExchange: doValidAuthCodeExchange, authcodeExchange: doValidAuthCodeExchange,
requestedAudience: "some-workload-cluster", requestedAudience: "some-workload-cluster",
modifyStorage: func(t *testing.T, storage *oidc.KubeStorage, secrets v1.SecretInterface, pendingRequest *http.Request) { modifyStorage: func(t *testing.T, storage *storage.KubeStorage, secrets v1.SecretInterface, pendingRequest *http.Request) {
// The fosite storage APIs don't offer a way to update an access token, so we will instead find the underlying // The fosite storage APIs don't offer a way to update an access token, so we will instead find the underlying
// storage Secret and update it in a more manual way. First get the access token's signature. // storage Secret and update it in a more manual way. First get the access token's signature.
parts := strings.Split(pendingRequest.Form.Get("subject_token"), ".") parts := strings.Split(pendingRequest.Form.Get("subject_token"), ".")
@ -1955,7 +1956,7 @@ func TestRefreshGrant(t *testing.T) {
kubeResources func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset) kubeResources func(t *testing.T, supervisorClient *supervisorfake.Clientset, kubeClient *fake.Clientset)
authcodeExchange authcodeExchangeInputs authcodeExchange authcodeExchangeInputs
refreshRequest refreshRequestInputs refreshRequest refreshRequestInputs
modifyRefreshTokenStorage func(t *testing.T, oauthStore *oidc.KubeStorage, secrets v1.SecretInterface, refreshToken string) modifyRefreshTokenStorage func(t *testing.T, oauthStore *storage.KubeStorage, secrets v1.SecretInterface, refreshToken string)
}{ }{
{ {
name: "happy path refresh grant with openid scope granted (id token returned)", name: "happy path refresh grant with openid scope granted (id token returned)",
@ -2869,7 +2870,7 @@ func TestRefreshGrant(t *testing.T) {
name: "when a valid refresh token is sent in the refresh request, but the token has already expired", name: "when a valid refresh token is sent in the refresh request, but the token has already expired",
idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()), idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()),
authcodeExchange: happyAuthcodeExchangeInputsForOIDCUpstream, authcodeExchange: happyAuthcodeExchangeInputsForOIDCUpstream,
modifyRefreshTokenStorage: func(t *testing.T, oauthStore *oidc.KubeStorage, secrets v1.SecretInterface, refreshToken string) { modifyRefreshTokenStorage: func(t *testing.T, oauthStore *storage.KubeStorage, secrets v1.SecretInterface, refreshToken string) {
// The fosite storage APIs don't offer a way to update a refresh token, so we will instead find the underlying // The fosite storage APIs don't offer a way to update a refresh token, so we will instead find the underlying
// storage Secret and update it in a more manual way. First get the refresh token's signature. // storage Secret and update it in a more manual way. First get the refresh token's signature.
refreshTokenSignature := getFositeDataSignature(t, refreshToken) refreshTokenSignature := getFositeDataSignature(t, refreshToken)
@ -3832,7 +3833,7 @@ func TestRefreshGrant(t *testing.T) {
Build(), Build(),
), ),
authcodeExchange: happyAuthcodeExchangeInputsForLDAPUpstream, authcodeExchange: happyAuthcodeExchangeInputsForLDAPUpstream,
modifyRefreshTokenStorage: func(t *testing.T, oauthStore *oidc.KubeStorage, secrets v1.SecretInterface, refreshToken string) { modifyRefreshTokenStorage: func(t *testing.T, oauthStore *storage.KubeStorage, secrets v1.SecretInterface, refreshToken string) {
refreshTokenSignature := getFositeDataSignature(t, refreshToken) refreshTokenSignature := getFositeDataSignature(t, refreshToken)
firstRequester, err := oauthStore.GetRefreshTokenSession(context.Background(), refreshTokenSignature, nil) firstRequester, err := oauthStore.GetRefreshTokenSession(context.Background(), refreshTokenSignature, nil)
require.NoError(t, err) require.NoError(t, err)
@ -3870,7 +3871,7 @@ func TestRefreshGrant(t *testing.T) {
happyLDAPCustomSessionData, happyLDAPCustomSessionData,
), ),
}, },
modifyRefreshTokenStorage: func(t *testing.T, oauthStore *oidc.KubeStorage, secrets v1.SecretInterface, refreshToken string) { modifyRefreshTokenStorage: func(t *testing.T, oauthStore *storage.KubeStorage, secrets v1.SecretInterface, refreshToken string) {
refreshTokenSignature := getFositeDataSignature(t, refreshToken) refreshTokenSignature := getFositeDataSignature(t, refreshToken)
firstRequester, err := oauthStore.GetRefreshTokenSession(context.Background(), refreshTokenSignature, nil) firstRequester, err := oauthStore.GetRefreshTokenSession(context.Background(), refreshTokenSignature, nil)
require.NoError(t, err) require.NoError(t, err)
@ -3908,7 +3909,7 @@ func TestRefreshGrant(t *testing.T) {
happyLDAPCustomSessionData, happyLDAPCustomSessionData,
), ),
}, },
modifyRefreshTokenStorage: func(t *testing.T, oauthStore *oidc.KubeStorage, secrets v1.SecretInterface, refreshToken string) { modifyRefreshTokenStorage: func(t *testing.T, oauthStore *storage.KubeStorage, secrets v1.SecretInterface, refreshToken string) {
refreshTokenSignature := getFositeDataSignature(t, refreshToken) refreshTokenSignature := getFositeDataSignature(t, refreshToken)
firstRequester, err := oauthStore.GetRefreshTokenSession(context.Background(), refreshTokenSignature, nil) firstRequester, err := oauthStore.GetRefreshTokenSession(context.Background(), refreshTokenSignature, nil)
require.NoError(t, err) require.NoError(t, err)
@ -3988,7 +3989,7 @@ func TestRefreshGrant(t *testing.T) {
Build(), Build(),
), ),
authcodeExchange: happyAuthcodeExchangeInputsForLDAPUpstream, authcodeExchange: happyAuthcodeExchangeInputsForLDAPUpstream,
modifyRefreshTokenStorage: func(t *testing.T, oauthStore *oidc.KubeStorage, secrets v1.SecretInterface, refreshToken string) { modifyRefreshTokenStorage: func(t *testing.T, oauthStore *storage.KubeStorage, secrets v1.SecretInterface, refreshToken string) {
refreshTokenSignature := getFositeDataSignature(t, refreshToken) refreshTokenSignature := getFositeDataSignature(t, refreshToken)
firstRequester, err := oauthStore.GetRefreshTokenSession(context.Background(), refreshTokenSignature, nil) firstRequester, err := oauthStore.GetRefreshTokenSession(context.Background(), refreshTokenSignature, nil)
require.NoError(t, err) require.NoError(t, err)
@ -4178,7 +4179,7 @@ func exchangeAuthcodeForTokens(
authCode string, authCode string,
jwtSigningKey *ecdsa.PrivateKey, jwtSigningKey *ecdsa.PrivateKey,
secrets v1.SecretInterface, secrets v1.SecretInterface,
oauthStore *oidc.KubeStorage, oauthStore *storage.KubeStorage,
) { ) {
authRequest := deepCopyRequestForm(happyAuthRequest) authRequest := deepCopyRequestForm(happyAuthRequest)
if test.modifyAuthRequest != nil { if test.modifyAuthRequest != nil {
@ -4196,7 +4197,7 @@ func exchangeAuthcodeForTokens(
var oauthHelper fosite.OAuth2Provider var oauthHelper fosite.OAuth2Provider
// Use lower minimum required bcrypt cost than we would use in production to keep unit the tests fast. // Use lower minimum required bcrypt cost than we would use in production to keep unit the tests fast.
oauthStore = oidc.NewKubeStorage(secrets, oidcClientsClient, oidc.DefaultOIDCTimeoutsConfiguration(), bcrypt.MinCost) oauthStore = storage.NewKubeStorage(secrets, oidcClientsClient, oidc.DefaultOIDCTimeoutsConfiguration(), bcrypt.MinCost)
if test.makeJwksSigningKeyAndProvider == nil { if test.makeJwksSigningKeyAndProvider == nil {
test.makeJwksSigningKeyAndProvider = generateJWTSigningKeyAndJWKSProvider test.makeJwksSigningKeyAndProvider = generateJWTSigningKeyAndJWKSProvider
@ -4214,7 +4215,7 @@ func exchangeAuthcodeForTokens(
} }
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: authorizationcode.TypeLabelValue}, 1) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: authorizationcode.TypeLabelValue}, 1)
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: storagepkce.TypeLabelValue}, 1) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: pkce.TypeLabelValue}, 1)
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: openidconnect.TypeLabelValue}, expectedNumberOfIDSessionsStored) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: openidconnect.TypeLabelValue}, expectedNumberOfIDSessionsStored)
// Assert the number of all secrets, excluding any OIDCClient's storage secret, since those are not related to session storage. // Assert the number of all secrets, excluding any OIDCClient's storage secret, since those are not related to session storage.
testutil.RequireNumberOfSecretsExcludingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: oidcclientsecretstorage.TypeLabelValue}, 2+expectedNumberOfIDSessionsStored) testutil.RequireNumberOfSecretsExcludingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: oidcclientsecretstorage.TypeLabelValue}, 2+expectedNumberOfIDSessionsStored)
@ -4259,7 +4260,7 @@ func requireTokenEndpointBehavior(
wantNonceValueInIDToken bool, wantNonceValueInIDToken bool,
tokenEndpointResponse *httptest.ResponseRecorder, tokenEndpointResponse *httptest.ResponseRecorder,
authCode string, authCode string,
oauthStore *oidc.KubeStorage, oauthStore *storage.KubeStorage,
jwtSigningKey *ecdsa.PrivateKey, jwtSigningKey *ecdsa.PrivateKey,
secrets v1.SecretInterface, secrets v1.SecretInterface,
requestTime time.Time, requestTime time.Time,
@ -4298,7 +4299,7 @@ func requireTokenEndpointBehavior(
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: authorizationcode.TypeLabelValue}, 1) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: authorizationcode.TypeLabelValue}, 1)
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: accesstoken.TypeLabelValue}, 1) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: accesstoken.TypeLabelValue}, 1)
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: storagepkce.TypeLabelValue}, 0) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: pkce.TypeLabelValue}, 0)
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: refreshtoken.TypeLabelValue}, expectedNumberOfRefreshTokenSessionsStored) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: refreshtoken.TypeLabelValue}, expectedNumberOfRefreshTokenSessionsStored)
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: openidconnect.TypeLabelValue}, expectedNumberOfIDSessionsStored) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secrets, labels.Set{crud.SecretLabelKey: openidconnect.TypeLabelValue}, expectedNumberOfIDSessionsStored)
// Assert the number of all secrets, excluding any OIDCClient's storage secret, since those are not related to session storage. // Assert the number of all secrets, excluding any OIDCClient's storage secret, since those are not related to session storage.
@ -4650,7 +4651,7 @@ func requireInvalidAccessTokenStorage(
func requireInvalidPKCEStorage( func requireInvalidPKCEStorage(
t *testing.T, t *testing.T,
code string, code string,
storage pkce.PKCERequestStorage, storage fositepkce.PKCERequestStorage,
) { ) {
t.Helper() t.Helper()

View File

@ -1,7 +1,7 @@
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package oidc package tokenexchange
import ( import (
"context" "context"
@ -27,8 +27,8 @@ type stsParams struct {
requestedAudience string requestedAudience string
} }
func TokenExchangeFactory(config fosite.Configurator, storage interface{}, strategy interface{}) interface{} { func HandlerFactory(config fosite.Configurator, storage interface{}, strategy interface{}) interface{} {
return &TokenExchangeHandler{ return &tokenExchangeHandler{
idTokenStrategy: strategy.(openid.OpenIDConnectTokenStrategy), idTokenStrategy: strategy.(openid.OpenIDConnectTokenStrategy),
accessTokenStrategy: strategy.(oauth2.AccessTokenStrategy), accessTokenStrategy: strategy.(oauth2.AccessTokenStrategy),
accessTokenStorage: storage.(oauth2.AccessTokenStorage), accessTokenStorage: storage.(oauth2.AccessTokenStorage),
@ -36,23 +36,23 @@ func TokenExchangeFactory(config fosite.Configurator, storage interface{}, strat
} }
} }
type TokenExchangeHandler struct { type tokenExchangeHandler struct {
idTokenStrategy openid.OpenIDConnectTokenStrategy idTokenStrategy openid.OpenIDConnectTokenStrategy
accessTokenStrategy oauth2.AccessTokenStrategy accessTokenStrategy oauth2.AccessTokenStrategy
accessTokenStorage oauth2.AccessTokenStorage accessTokenStorage oauth2.AccessTokenStorage
fositeConfig fosite.Configurator fositeConfig fosite.Configurator
} }
var _ fosite.TokenEndpointHandler = (*TokenExchangeHandler)(nil) var _ fosite.TokenEndpointHandler = (*tokenExchangeHandler)(nil)
func (t *TokenExchangeHandler) HandleTokenEndpointRequest(ctx context.Context, requester fosite.AccessRequester) error { func (t *tokenExchangeHandler) HandleTokenEndpointRequest(ctx context.Context, requester fosite.AccessRequester) error {
if !t.CanHandleTokenEndpointRequest(ctx, requester) { if !t.CanHandleTokenEndpointRequest(ctx, requester) {
return errors.WithStack(fosite.ErrUnknownRequest) return errors.WithStack(fosite.ErrUnknownRequest)
} }
return nil return nil
} }
func (t *TokenExchangeHandler) PopulateTokenEndpointResponse(ctx context.Context, requester fosite.AccessRequester, responder fosite.AccessResponder) error { func (t *tokenExchangeHandler) PopulateTokenEndpointResponse(ctx context.Context, requester fosite.AccessRequester, responder fosite.AccessResponder) error {
// Skip this request if it's for a different grant type. // Skip this request if it's for a different grant type.
if err := t.HandleTokenEndpointRequest(ctx, requester); err != nil { if err := t.HandleTokenEndpointRequest(ctx, requester); err != nil {
return errors.WithStack(err) return errors.WithStack(err)
@ -108,7 +108,7 @@ func (t *TokenExchangeHandler) PopulateTokenEndpointResponse(ctx context.Context
return nil return nil
} }
func (t *TokenExchangeHandler) mintJWT(ctx context.Context, requester fosite.Requester, audience string) (string, error) { func (t *tokenExchangeHandler) mintJWT(ctx context.Context, requester fosite.Requester, audience string) (string, error) {
downscoped := fosite.NewAccessRequest(requester.GetSession()) downscoped := fosite.NewAccessRequest(requester.GetSession())
downscoped.Client.(*fosite.DefaultClient).ID = audience downscoped.Client.(*fosite.DefaultClient).ID = audience
@ -119,7 +119,7 @@ func (t *TokenExchangeHandler) mintJWT(ctx context.Context, requester fosite.Req
return t.idTokenStrategy.GenerateIDToken(ctx, idTokenLifespan, downscoped) return t.idTokenStrategy.GenerateIDToken(ctx, idTokenLifespan, downscoped)
} }
func (t *TokenExchangeHandler) validateSession(requester fosite.Requester) error { func (t *tokenExchangeHandler) validateSession(requester fosite.Requester) error {
pSession, ok := requester.GetSession().(*psession.PinnipedSession) pSession, ok := requester.GetSession().(*psession.PinnipedSession)
if !ok { if !ok {
// This shouldn't really happen. // This shouldn't really happen.
@ -135,7 +135,7 @@ func (t *TokenExchangeHandler) validateSession(requester fosite.Requester) error
return nil return nil
} }
func (t *TokenExchangeHandler) validateParams(params url.Values) (*stsParams, error) { func (t *tokenExchangeHandler) validateParams(params url.Values) (*stsParams, error) {
var result stsParams var result stsParams
// Validate some required parameters. // Validate some required parameters.
@ -189,7 +189,7 @@ func (t *TokenExchangeHandler) validateParams(params url.Values) (*stsParams, er
return &result, nil return &result, nil
} }
func (t *TokenExchangeHandler) validateAccessToken(ctx context.Context, requester fosite.AccessRequester, accessToken string) (fosite.Requester, error) { func (t *tokenExchangeHandler) validateAccessToken(ctx context.Context, requester fosite.AccessRequester, accessToken string) (fosite.Requester, error) {
// Look up the access token's stored session data. // Look up the access token's stored session data.
signature := t.accessTokenStrategy.AccessTokenSignature(ctx, accessToken) signature := t.accessTokenStrategy.AccessTokenSignature(ctx, accessToken)
originalRequester, err := t.accessTokenStorage.GetAccessTokenSession(ctx, signature, requester.GetSession()) originalRequester, err := t.accessTokenStorage.GetAccessTokenSession(ctx, signature, requester.GetSession())
@ -204,10 +204,10 @@ func (t *TokenExchangeHandler) validateAccessToken(ctx context.Context, requeste
return originalRequester, nil return originalRequester, nil
} }
func (t *TokenExchangeHandler) CanSkipClientAuth(_ context.Context, _ fosite.AccessRequester) bool { func (t *tokenExchangeHandler) CanSkipClientAuth(_ context.Context, _ fosite.AccessRequester) bool {
return false return false
} }
func (t *TokenExchangeHandler) CanHandleTokenEndpointRequest(_ context.Context, requester fosite.AccessRequester) bool { func (t *tokenExchangeHandler) CanHandleTokenEndpointRequest(_ context.Context, requester fosite.AccessRequester) bool {
return requester.GetGrantTypes().ExactOne(oidcapi.GrantTypeTokenExchange) return requester.GetGrantTypes().ExactOne(oidcapi.GrantTypeTokenExchange)
} }

View File

@ -1,9 +1,10 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package manager package endpointsmanager
import ( import (
"go.pinniped.dev/internal/httputil/requestutil"
"net/http" "net/http"
"strings" "strings"
"sync" "sync"
@ -11,20 +12,20 @@ import (
corev1client "k8s.io/client-go/kubernetes/typed/core/v1" corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
"go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1" "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1"
"go.pinniped.dev/internal/httputil/requestutil" "go.pinniped.dev/internal/federationdomain/csrftoken"
"go.pinniped.dev/internal/oidc" "go.pinniped.dev/internal/federationdomain/dynamiccodec"
"go.pinniped.dev/internal/oidc/auth" "go.pinniped.dev/internal/federationdomain/endpoints/auth"
"go.pinniped.dev/internal/oidc/callback" "go.pinniped.dev/internal/federationdomain/endpoints/callback"
"go.pinniped.dev/internal/oidc/csrftoken" "go.pinniped.dev/internal/federationdomain/endpoints/discovery"
"go.pinniped.dev/internal/oidc/discovery" "go.pinniped.dev/internal/federationdomain/endpoints/idpdiscovery"
"go.pinniped.dev/internal/oidc/dynamiccodec" "go.pinniped.dev/internal/federationdomain/endpoints/jwks"
"go.pinniped.dev/internal/oidc/idpdiscovery" "go.pinniped.dev/internal/federationdomain/endpoints/login"
"go.pinniped.dev/internal/oidc/idplister" "go.pinniped.dev/internal/federationdomain/endpoints/token"
"go.pinniped.dev/internal/oidc/jwks" "go.pinniped.dev/internal/federationdomain/federationdomainproviders"
"go.pinniped.dev/internal/oidc/login" "go.pinniped.dev/internal/federationdomain/idplister"
"go.pinniped.dev/internal/oidc/oidcclientvalidator" "go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/oidc/provider/federationdomainproviders" "go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
"go.pinniped.dev/internal/oidc/token" "go.pinniped.dev/internal/federationdomain/storage"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/secret" "go.pinniped.dev/internal/secret"
"go.pinniped.dev/pkg/oidcclient/nonce" "go.pinniped.dev/pkg/oidcclient/nonce"
@ -101,7 +102,7 @@ func (m *Manager) SetFederationDomains(federationDomains ...*federationdomainpro
// Use NullStorage for the authorize endpoint because we do not actually want to store anything until // Use NullStorage for the authorize endpoint because we do not actually want to store anything until
// the upstream callback endpoint is called later. // the upstream callback endpoint is called later.
oauthHelperWithNullStorage := oidc.FositeOauth2Helper( oauthHelperWithNullStorage := oidc.FositeOauth2Helper(
oidc.NewNullStorage(m.secretsClient, m.oidcClientsClient, oidcclientvalidator.DefaultMinBcryptCost), storage.NewNullStorage(m.secretsClient, m.oidcClientsClient, oidcclientvalidator.DefaultMinBcryptCost),
issuerURL, issuerURL,
tokenHMACKeyGetter, tokenHMACKeyGetter,
nil, nil,
@ -110,7 +111,7 @@ func (m *Manager) SetFederationDomains(federationDomains ...*federationdomainpro
// For all the other endpoints, make another oauth helper with exactly the same settings except use real storage. // For all the other endpoints, make another oauth helper with exactly the same settings except use real storage.
oauthHelperWithKubeStorage := oidc.FositeOauth2Helper( oauthHelperWithKubeStorage := oidc.FositeOauth2Helper(
oidc.NewKubeStorage(m.secretsClient, m.oidcClientsClient, timeoutsConfiguration, oidcclientvalidator.DefaultMinBcryptCost), storage.NewKubeStorage(m.secretsClient, m.oidcClientsClient, timeoutsConfiguration, oidcclientvalidator.DefaultMinBcryptCost),
issuerURL, issuerURL,
tokenHMACKeyGetter, tokenHMACKeyGetter,
m.dynamicJWKSProvider, m.dynamicJWKSProvider,

View File

@ -1,7 +1,7 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package manager package endpointsmanager
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
@ -20,12 +20,12 @@ import (
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake" supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
"go.pinniped.dev/internal/federationdomain/endpoints/discovery"
"go.pinniped.dev/internal/federationdomain/endpoints/jwks"
"go.pinniped.dev/internal/federationdomain/federationdomainproviders"
"go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/here" "go.pinniped.dev/internal/here"
"go.pinniped.dev/internal/idtransform" "go.pinniped.dev/internal/idtransform"
"go.pinniped.dev/internal/oidc"
"go.pinniped.dev/internal/oidc/discovery"
"go.pinniped.dev/internal/oidc/jwks"
"go.pinniped.dev/internal/oidc/provider/federationdomainproviders"
"go.pinniped.dev/internal/secret" "go.pinniped.dev/internal/secret"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/internal/testutil/oidctestutil" "go.pinniped.dev/internal/testutil/oidctestutil"

View File

@ -9,9 +9,9 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"go.pinniped.dev/internal/federationdomain/idplister"
"go.pinniped.dev/internal/federationdomain/resolvedprovider"
"go.pinniped.dev/internal/idtransform" "go.pinniped.dev/internal/idtransform"
"go.pinniped.dev/internal/oidc/idplister"
"go.pinniped.dev/internal/oidc/provider/resolvedprovider"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
) )

View File

@ -1,4 +1,4 @@
/* Copyright 2021 the Pinniped contributors. All Rights Reserved. */ /* Copyright 2021-2023 the Pinniped contributors. All Rights Reserved. */
/* SPDX-License-Identifier: Apache-2.0 */ /* SPDX-License-Identifier: Apache-2.0 */
body { body {

View File

@ -1,5 +1,5 @@
<!-- <!--
Copyright 2021 the Pinniped contributors. All Rights Reserved. Copyright 2021-2023 the Pinniped contributors. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
--><!DOCTYPE html> --><!DOCTYPE html>
<html lang="en"> <html lang="en">

View File

@ -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 // SPDX-License-Identifier: Apache-2.0
window.onload = () => { window.onload = () => {

View File

@ -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 // SPDX-License-Identifier: Apache-2.0
// Package formposthtml defines HTML templates used by the Supervisor. // Package formposthtml defines HTML templates used by the Supervisor.
@ -11,7 +11,7 @@ import (
"github.com/tdewolff/minify/v2/minify" "github.com/tdewolff/minify/v2/minify"
"go.pinniped.dev/internal/oidc/provider/csp" "go.pinniped.dev/internal/federationdomain/csp"
) )
//nolint:gochecknoglobals // This package uses globals to ensure that all parsing and minifying happens at init. //nolint:gochecknoglobals // This package uses globals to ensure that all parsing and minifying happens at init.

View File

@ -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 // SPDX-License-Identifier: Apache-2.0
package formposthtml package formposthtml

View File

@ -4,7 +4,7 @@
package idplister package idplister
import ( import (
"go.pinniped.dev/internal/oidc/provider/upstreamprovider" "go.pinniped.dev/internal/federationdomain/upstreamprovider"
) )
type UpstreamOIDCIdentityProvidersLister interface { type UpstreamOIDCIdentityProvidersLister interface {

View File

@ -1,7 +1,8 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Package oidc contains common OIDC functionality needed by Pinniped. // Package oidc contains common OIDC functionality needed by FederationDomains to implement
// downstream OIDC functionality.
package oidc package oidc
import ( import (
@ -18,10 +19,13 @@ import (
errorsx "github.com/pkg/errors" errorsx "github.com/pkg/errors"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc" oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/federationdomain/csrftoken"
"go.pinniped.dev/internal/federationdomain/endpoints/jwks"
"go.pinniped.dev/internal/federationdomain/endpoints/tokenexchange"
"go.pinniped.dev/internal/federationdomain/formposthtml"
"go.pinniped.dev/internal/federationdomain/strategy"
"go.pinniped.dev/internal/federationdomain/timeouts"
"go.pinniped.dev/internal/httputil/httperr" "go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/oidc/csrftoken"
"go.pinniped.dev/internal/oidc/jwks"
"go.pinniped.dev/internal/oidc/provider/formposthtml"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
"go.pinniped.dev/pkg/oidcclient/nonce" "go.pinniped.dev/pkg/oidcclient/nonce"
@ -99,81 +103,13 @@ type UpstreamStateParamData struct {
FormatVersion string `json:"v"` FormatVersion string `json:"v"`
} }
type TimeoutsConfiguration struct {
// The length of time that our state param that we encrypt and pass to the upstream OIDC IDP should be considered
// valid. If a state param generated by the authorize endpoint is sent to the callback endpoint after this much
// time has passed, then the callback endpoint should reject it. This allows us to set a limit on how long
// the end user has to finish their login with the upstream IDP, including the time that it takes to fumble
// with password manager and two-factor authenticator apps, and also accounting for taking a coffee break while
// the browser is sitting at the upstream IDP's login page.
UpstreamStateParamLifespan time.Duration
// How long an authcode issued by the callback endpoint is valid. This determines how much time the end user
// has to come back to exchange the authcode for tokens at the token endpoint.
AuthorizeCodeLifespan time.Duration
// The lifetime of an downstream access token issued by the token endpoint. Access tokens should generally
// be fairly short-lived.
AccessTokenLifespan time.Duration
// The lifetime of an downstream ID token issued by the token endpoint. This should generally be the same
// as the AccessTokenLifespan, or longer if it would be useful for the user's proof of identity to be valid
// for longer than their proof of authorization.
IDTokenLifespan time.Duration
// The lifetime of an downstream refresh token issued by the token endpoint. This should generally be
// significantly longer than the access token lifetime, so it can be used to refresh the access token
// multiple times. Once the refresh token expires, the user's session is over and they will need
// to start a new authorization request, which will require them to log in again with the upstream IDP
// in their web browser.
RefreshTokenLifespan time.Duration
// AuthorizationCodeSessionStorageLifetime is the length of time after which an authcode is allowed to be garbage
// collected from storage. Authcodes are kept in storage after they are redeemed to allow the system to mark the
// authcode as already used, so it can reject any future uses of the same authcode with special case handling which
// include revoking the access and refresh tokens associated with the session. Therefore, this should be
// significantly longer than the AuthorizeCodeLifespan, and there is probably no reason to make it longer than
// the sum of the AuthorizeCodeLifespan and the RefreshTokenLifespan.
AuthorizationCodeSessionStorageLifetime time.Duration
// PKCESessionStorageLifetime is the length of time after which PKCE data is allowed to be garbage collected from
// storage. PKCE sessions are closely related to authorization code sessions. After the authcode is successfully
// redeemed, the PKCE session is explicitly deleted. After the authcode expires, the PKCE session is no longer needed,
// but it is not explicitly deleted. Therefore, this can be just slightly longer than the AuthorizeCodeLifespan. We'll
// avoid making it exactly the same as AuthorizeCodeLifespan to avoid any chance of the garbage collector deleting it
// while it is being used.
PKCESessionStorageLifetime time.Duration
// OIDCSessionStorageLifetime is the length of time after which the OIDC session data related to an authcode
// is allowed to be garbage collected from storage. Due to a bug in an underlying library, these are not explicitly
// deleted. Similar to the PKCE session, they are not needed anymore after the corresponding authcode has expired.
// Therefore, this can be just slightly longer than the AuthorizeCodeLifespan. We'll avoid making it exactly the same
// as AuthorizeCodeLifespan to avoid any chance of the garbage collector deleting it while it is being used.
OIDCSessionStorageLifetime time.Duration
// AccessTokenSessionStorageLifetime is the length of time after which an access token's session data is allowed
// to be garbage collected from storage. These must exist in storage for as long as the refresh token is valid
// or else the refresh flow will not work properly. So this must be longer than RefreshTokenLifespan.
AccessTokenSessionStorageLifetime time.Duration
// RefreshTokenSessionStorageLifetime is the length of time after which a refresh token's session data is allowed
// to be garbage collected from storage. These must exist in storage for as long as the refresh token is valid.
// Therefore, this can be just slightly longer than the RefreshTokenLifespan. We'll avoid making it exactly the same
// as RefreshTokenLifespan to avoid any chance of the garbage collector deleting it while it is being used.
// If an expired token is still stored when the user tries to refresh it, then they will get a more specific
// error message telling them that the token is expired, rather than a more generic error that is returned
// when the token does not exist. If this is desirable, then the RefreshTokenSessionStorageLifetime can be made
// to be significantly larger than RefreshTokenLifespan, at the cost of slower cleanup.
RefreshTokenSessionStorageLifetime time.Duration
}
// Get the defaults for the Supervisor server. // Get the defaults for the Supervisor server.
func DefaultOIDCTimeoutsConfiguration() TimeoutsConfiguration { func DefaultOIDCTimeoutsConfiguration() timeouts.Configuration {
accessTokenLifespan := 2 * time.Minute accessTokenLifespan := 2 * time.Minute
authorizationCodeLifespan := 10 * time.Minute authorizationCodeLifespan := 10 * time.Minute
refreshTokenLifespan := 9 * time.Hour refreshTokenLifespan := 9 * time.Hour
return TimeoutsConfiguration{ return timeouts.Configuration{
UpstreamStateParamLifespan: 90 * time.Minute, UpstreamStateParamLifespan: 90 * time.Minute,
AuthorizeCodeLifespan: authorizationCodeLifespan, AuthorizeCodeLifespan: authorizationCodeLifespan,
AccessTokenLifespan: accessTokenLifespan, AccessTokenLifespan: accessTokenLifespan,
@ -192,7 +128,7 @@ func FositeOauth2Helper(
issuer string, issuer string,
hmacSecretOfLengthAtLeast32Func func() []byte, hmacSecretOfLengthAtLeast32Func func() []byte,
jwksProvider jwks.DynamicJWKSProvider, jwksProvider jwks.DynamicJWKSProvider,
timeoutsConfiguration TimeoutsConfiguration, timeoutsConfiguration timeouts.Configuration,
) fosite.OAuth2Provider { ) fosite.OAuth2Provider {
isRedirectURISecureStrict := func(_ context.Context, uri *url.URL) bool { isRedirectURISecureStrict := func(_ context.Context, uri *url.URL) bool {
return fosite.IsRedirectURISecureStrict(uri) return fosite.IsRedirectURISecureStrict(uri)
@ -234,15 +170,15 @@ func FositeOauth2Helper(
oauthStore, oauthStore,
&compose.CommonStrategy{ &compose.CommonStrategy{
// Note that Fosite requires the HMAC secret to be at least 32 bytes. // Note that Fosite requires the HMAC secret to be at least 32 bytes.
CoreStrategy: newDynamicOauth2HMACStrategy(oauthConfig, hmacSecretOfLengthAtLeast32Func), CoreStrategy: strategy.NewDynamicOauth2HMACStrategy(oauthConfig, hmacSecretOfLengthAtLeast32Func),
OpenIDConnectTokenStrategy: newDynamicOpenIDConnectECDSAStrategy(oauthConfig, jwksProvider), OpenIDConnectTokenStrategy: strategy.NewDynamicOpenIDConnectECDSAStrategy(oauthConfig, jwksProvider),
}, },
compose.OAuth2AuthorizeExplicitFactory, compose.OAuth2AuthorizeExplicitFactory,
compose.OAuth2RefreshTokenGrantFactory, compose.OAuth2RefreshTokenGrantFactory,
compose.OpenIDConnectExplicitFactory, compose.OpenIDConnectExplicitFactory,
compose.OpenIDConnectRefreshFactory, compose.OpenIDConnectRefreshFactory,
compose.OAuth2PKCEFactory, compose.OAuth2PKCEFactory,
TokenExchangeFactory, // handle the "urn:ietf:params:oauth:grant-type:token-exchange" grant type tokenexchange.HandlerFactory, // handle the "urn:ietf:params:oauth:grant-type:token-exchange" grant type
) )
return oAuth2Provider return oAuth2Provider

View File

@ -1,8 +1,11 @@
// Copyright 2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package resolvedprovider package resolvedprovider
import ( import (
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/idtransform" "go.pinniped.dev/internal/idtransform"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
) )

View File

@ -1,7 +1,7 @@
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package oidc package storage
import ( import (
"context" "context"

View File

@ -1,7 +1,7 @@
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package oidc package storage
import ( import (
"context" "context"
@ -14,13 +14,14 @@ import (
corev1client "k8s.io/client-go/kubernetes/typed/core/v1" corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
"go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1" "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1"
"go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/federationdomain/timeouts"
"go.pinniped.dev/internal/fositestorage/accesstoken" "go.pinniped.dev/internal/fositestorage/accesstoken"
"go.pinniped.dev/internal/fositestorage/authorizationcode" "go.pinniped.dev/internal/fositestorage/authorizationcode"
"go.pinniped.dev/internal/fositestorage/openidconnect" "go.pinniped.dev/internal/fositestorage/openidconnect"
"go.pinniped.dev/internal/fositestorage/pkce" "go.pinniped.dev/internal/fositestorage/pkce"
"go.pinniped.dev/internal/fositestorage/refreshtoken" "go.pinniped.dev/internal/fositestorage/refreshtoken"
"go.pinniped.dev/internal/fositestoragei" "go.pinniped.dev/internal/fositestoragei"
"go.pinniped.dev/internal/oidc/clientregistry"
"go.pinniped.dev/internal/oidcclientsecretstorage" "go.pinniped.dev/internal/oidcclientsecretstorage"
) )
@ -38,7 +39,7 @@ var _ fositestoragei.AllFositeStorage = &KubeStorage{}
func NewKubeStorage( func NewKubeStorage(
secrets corev1client.SecretInterface, secrets corev1client.SecretInterface,
oidcClientsClient v1alpha1.OIDCClientInterface, oidcClientsClient v1alpha1.OIDCClientInterface,
timeoutsConfiguration TimeoutsConfiguration, timeoutsConfiguration timeouts.Configuration,
minBcryptCost int, minBcryptCost int,
) *KubeStorage { ) *KubeStorage {
nowFunc := time.Now nowFunc := time.Now

View File

@ -1,7 +1,7 @@
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package oidc package storage
import ( import (
"context" "context"
@ -11,8 +11,8 @@ import (
"go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1" "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/typed/config/v1alpha1"
"go.pinniped.dev/internal/constable" "go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/fositestoragei" "go.pinniped.dev/internal/fositestoragei"
"go.pinniped.dev/internal/oidc/clientregistry"
"go.pinniped.dev/internal/oidcclientsecretstorage" "go.pinniped.dev/internal/oidcclientsecretstorage"
) )

View File

@ -1,7 +1,7 @@
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package oidc package strategy
import ( import (
"context" "context"
@ -11,6 +11,8 @@ import (
"github.com/ory/fosite/compose" "github.com/ory/fosite/compose"
"github.com/ory/fosite/handler/oauth2" "github.com/ory/fosite/handler/oauth2"
errorsx "github.com/pkg/errors" errorsx "github.com/pkg/errors"
"go.pinniped.dev/internal/federationdomain/storage"
) )
const ( const (
@ -24,7 +26,7 @@ const (
oryAuthcodePrefix = "ory_ac_" oryAuthcodePrefix = "ory_ac_"
) )
// dynamicOauth2HMACStrategy is an oauth2.CoreStrategy that can dynamically load an HMAC key to sign // DynamicOauth2HMACStrategy is an oauth2.CoreStrategy that can dynamically load an HMAC key to sign
// stuff (access tokens, refresh tokens, and auth codes). We want this dynamic capability since our // stuff (access tokens, refresh tokens, and auth codes). We want this dynamic capability since our
// controllers for loading FederationDomain's and signing keys run in parallel, and thus the signing key // controllers for loading FederationDomain's and signing keys run in parallel, and thus the signing key
// might not be ready when an FederationDomain is otherwise ready. // might not be ready when an FederationDomain is otherwise ready.
@ -37,18 +39,18 @@ const (
// out of context, such as when accidentally committed to a GitHub repo. After we implemented the // out of context, such as when accidentally committed to a GitHub repo. After we implemented the
// custom prefix feature, fosite later added the same feature, but did not make the prefix customizable. // custom prefix feature, fosite later added the same feature, but did not make the prefix customizable.
// Therefore, this code has been updated to replace the fosite prefix with our custom prefix. // Therefore, this code has been updated to replace the fosite prefix with our custom prefix.
type dynamicOauth2HMACStrategy struct { type DynamicOauth2HMACStrategy struct {
fositeConfig *fosite.Config fositeConfig *fosite.Config
keyFunc func() []byte keyFunc func() []byte
} }
var _ oauth2.CoreStrategy = &dynamicOauth2HMACStrategy{} var _ oauth2.CoreStrategy = &DynamicOauth2HMACStrategy{}
func newDynamicOauth2HMACStrategy( func NewDynamicOauth2HMACStrategy(
fositeConfig *fosite.Config, fositeConfig *fosite.Config,
keyFunc func() []byte, keyFunc func() []byte,
) *dynamicOauth2HMACStrategy { ) *DynamicOauth2HMACStrategy {
return &dynamicOauth2HMACStrategy{ return &DynamicOauth2HMACStrategy{
fositeConfig: fositeConfig, fositeConfig: fositeConfig,
keyFunc: keyFunc, keyFunc: keyFunc,
} }
@ -58,11 +60,11 @@ func replacePrefix(s, prefixToReplace, newPrefix string) string {
return newPrefix + strings.TrimPrefix(s, prefixToReplace) return newPrefix + strings.TrimPrefix(s, prefixToReplace)
} }
func (s *dynamicOauth2HMACStrategy) AccessTokenSignature(ctx context.Context, token string) string { func (s *DynamicOauth2HMACStrategy) AccessTokenSignature(ctx context.Context, token string) string {
return s.delegate().AccessTokenSignature(ctx, token) return s.delegate().AccessTokenSignature(ctx, token)
} }
func (s *dynamicOauth2HMACStrategy) GenerateAccessToken( func (s *DynamicOauth2HMACStrategy) GenerateAccessToken(
ctx context.Context, ctx context.Context,
requester fosite.Requester, requester fosite.Requester,
) (string, string, error) { ) (string, string, error) {
@ -78,7 +80,7 @@ func (s *dynamicOauth2HMACStrategy) GenerateAccessToken(
return token, sig, err return token, sig, err
} }
func (s *dynamicOauth2HMACStrategy) ValidateAccessToken( func (s *DynamicOauth2HMACStrategy) ValidateAccessToken(
ctx context.Context, ctx context.Context,
requester fosite.Requester, requester fosite.Requester,
token string, token string,
@ -90,11 +92,11 @@ func (s *dynamicOauth2HMACStrategy) ValidateAccessToken(
return s.delegate().ValidateAccessToken(ctx, requester, replacePrefix(token, pinAccessTokenPrefix, oryAccessTokenPrefix)) return s.delegate().ValidateAccessToken(ctx, requester, replacePrefix(token, pinAccessTokenPrefix, oryAccessTokenPrefix))
} }
func (s *dynamicOauth2HMACStrategy) RefreshTokenSignature(ctx context.Context, token string) string { func (s *DynamicOauth2HMACStrategy) RefreshTokenSignature(ctx context.Context, token string) string {
return s.delegate().RefreshTokenSignature(ctx, token) return s.delegate().RefreshTokenSignature(ctx, token)
} }
func (s *dynamicOauth2HMACStrategy) GenerateRefreshToken( func (s *DynamicOauth2HMACStrategy) GenerateRefreshToken(
ctx context.Context, ctx context.Context,
requester fosite.Requester, requester fosite.Requester,
) (string, string, error) { ) (string, string, error) {
@ -110,7 +112,7 @@ func (s *dynamicOauth2HMACStrategy) GenerateRefreshToken(
return token, sig, err return token, sig, err
} }
func (s *dynamicOauth2HMACStrategy) ValidateRefreshToken( func (s *DynamicOauth2HMACStrategy) ValidateRefreshToken(
ctx context.Context, ctx context.Context,
requester fosite.Requester, requester fosite.Requester,
token string, token string,
@ -122,11 +124,11 @@ func (s *dynamicOauth2HMACStrategy) ValidateRefreshToken(
return s.delegate().ValidateRefreshToken(ctx, requester, replacePrefix(token, pinRefreshTokenPrefix, oryRefreshTokenPrefix)) return s.delegate().ValidateRefreshToken(ctx, requester, replacePrefix(token, pinRefreshTokenPrefix, oryRefreshTokenPrefix))
} }
func (s *dynamicOauth2HMACStrategy) AuthorizeCodeSignature(ctx context.Context, token string) string { func (s *DynamicOauth2HMACStrategy) AuthorizeCodeSignature(ctx context.Context, token string) string {
return s.delegate().AuthorizeCodeSignature(ctx, token) return s.delegate().AuthorizeCodeSignature(ctx, token)
} }
func (s *dynamicOauth2HMACStrategy) GenerateAuthorizeCode( func (s *DynamicOauth2HMACStrategy) GenerateAuthorizeCode(
ctx context.Context, ctx context.Context,
requester fosite.Requester, requester fosite.Requester,
) (string, string, error) { ) (string, string, error) {
@ -142,7 +144,7 @@ func (s *dynamicOauth2HMACStrategy) GenerateAuthorizeCode(
return authcode, sig, err return authcode, sig, err
} }
func (s *dynamicOauth2HMACStrategy) ValidateAuthorizeCode( func (s *DynamicOauth2HMACStrategy) ValidateAuthorizeCode(
ctx context.Context, ctx context.Context,
requester fosite.Requester, requester fosite.Requester,
token string, token string,
@ -154,6 +156,6 @@ func (s *dynamicOauth2HMACStrategy) ValidateAuthorizeCode(
return s.delegate().ValidateAuthorizeCode(ctx, requester, replacePrefix(token, pinAuthcodePrefix, oryAuthcodePrefix)) return s.delegate().ValidateAuthorizeCode(ctx, requester, replacePrefix(token, pinAuthcodePrefix, oryAuthcodePrefix))
} }
func (s *dynamicOauth2HMACStrategy) delegate() *oauth2.HMACSHAStrategy { func (s *DynamicOauth2HMACStrategy) delegate() *oauth2.HMACSHAStrategy {
return compose.NewOAuth2HMACStrategy(NewDynamicGlobalSecretConfig(s.fositeConfig, s.keyFunc)) return compose.NewOAuth2HMACStrategy(storage.NewDynamicGlobalSecretConfig(s.fositeConfig, s.keyFunc))
} }

View File

@ -1,7 +1,7 @@
// Copyright 2022 the Pinniped contributors. All Rights Reserved. // Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package oidc package strategy
import ( import (
"context" "context"
@ -15,7 +15,7 @@ import (
) )
func TestDynamicOauth2HMACStrategy_Signatures(t *testing.T) { func TestDynamicOauth2HMACStrategy_Signatures(t *testing.T) {
s := newDynamicOauth2HMACStrategy( s := NewDynamicOauth2HMACStrategy(
&fosite.Config{}, // defaults are good enough for this unit test &fosite.Config{}, // defaults are good enough for this unit test
func() []byte { return []byte("12345678901234567890123456789012") }, // 32 character secret key func() []byte { return []byte("12345678901234567890123456789012") }, // 32 character secret key
) )
@ -57,12 +57,12 @@ func TestDynamicOauth2HMACStrategy_Signatures(t *testing.T) {
} }
func TestDynamicOauth2HMACStrategy_Generate(t *testing.T) { func TestDynamicOauth2HMACStrategy_Generate(t *testing.T) {
s := newDynamicOauth2HMACStrategy( s := NewDynamicOauth2HMACStrategy(
&fosite.Config{}, // defaults are good enough for this unit test &fosite.Config{}, // defaults are good enough for this unit test
func() []byte { return []byte("12345678901234567890123456789012") }, // 32 character secret key func() []byte { return []byte("12345678901234567890123456789012") }, // 32 character secret key
) )
generateTokenErrorCausingStrategy := newDynamicOauth2HMACStrategy( generateTokenErrorCausingStrategy := NewDynamicOauth2HMACStrategy(
&fosite.Config{}, &fosite.Config{},
func() []byte { return []byte("too_short_causes_error") }, // secret key is below required 32 characters func() []byte { return []byte("too_short_causes_error") }, // secret key is below required 32 characters
) )
@ -134,7 +134,7 @@ func TestDynamicOauth2HMACStrategy_Generate(t *testing.T) {
} }
func TestDynamicOauth2HMACStrategy_Validate(t *testing.T) { func TestDynamicOauth2HMACStrategy_Validate(t *testing.T) {
s := newDynamicOauth2HMACStrategy( s := NewDynamicOauth2HMACStrategy(
&fosite.Config{}, // defaults are good enough for this unit test &fosite.Config{}, // defaults are good enough for this unit test
func() []byte { return []byte("12345678901234567890123456789012") }, // 32 character secret key func() []byte { return []byte("12345678901234567890123456789012") }, // 32 character secret key
) )

View File

@ -1,7 +1,7 @@
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package oidc package strategy
import ( import (
"context" "context"
@ -14,11 +14,11 @@ import (
"github.com/ory/fosite/handler/openid" "github.com/ory/fosite/handler/openid"
"go.pinniped.dev/internal/constable" "go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/oidc/jwks" "go.pinniped.dev/internal/federationdomain/endpoints/jwks"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
) )
// dynamicOpenIDConnectECDSAStrategy is an openid.OpenIDConnectTokenStrategy that can dynamically // DynamicOpenIDConnectECDSAStrategy is an openid.OpenIDConnectTokenStrategy that can dynamically
// load a signing key to issue ID tokens. We want this dynamic capability since our controllers for // load a signing key to issue ID tokens. We want this dynamic capability since our controllers for
// loading FederationDomain's and signing keys run in parallel, and thus the signing key might not be // loading FederationDomain's and signing keys run in parallel, and thus the signing key might not be
// ready when an FederationDomain is otherwise ready. // ready when an FederationDomain is otherwise ready.
@ -26,24 +26,24 @@ import (
// If we ever update FederationDomain's to hold their signing key, we might not need this type, since we // If we ever update FederationDomain's to hold their signing key, we might not need this type, since we
// could have an invariant that routes to an FederationDomain's endpoints are only wired up if an // could have an invariant that routes to an FederationDomain's endpoints are only wired up if an
// FederationDomain has a valid signing key. // FederationDomain has a valid signing key.
type dynamicOpenIDConnectECDSAStrategy struct { type DynamicOpenIDConnectECDSAStrategy struct {
fositeConfig *fosite.Config fositeConfig *fosite.Config
jwksProvider jwks.DynamicJWKSProvider jwksProvider jwks.DynamicJWKSProvider
} }
var _ openid.OpenIDConnectTokenStrategy = &dynamicOpenIDConnectECDSAStrategy{} var _ openid.OpenIDConnectTokenStrategy = &DynamicOpenIDConnectECDSAStrategy{}
func newDynamicOpenIDConnectECDSAStrategy( func NewDynamicOpenIDConnectECDSAStrategy(
fositeConfig *fosite.Config, fositeConfig *fosite.Config,
jwksProvider jwks.DynamicJWKSProvider, jwksProvider jwks.DynamicJWKSProvider,
) *dynamicOpenIDConnectECDSAStrategy { ) *DynamicOpenIDConnectECDSAStrategy {
return &dynamicOpenIDConnectECDSAStrategy{ return &DynamicOpenIDConnectECDSAStrategy{
fositeConfig: fositeConfig, fositeConfig: fositeConfig,
jwksProvider: jwksProvider, jwksProvider: jwksProvider,
} }
} }
func (s *dynamicOpenIDConnectECDSAStrategy) GenerateIDToken( func (s *DynamicOpenIDConnectECDSAStrategy) GenerateIDToken(
ctx context.Context, ctx context.Context,
lifespan time.Duration, lifespan time.Duration,
requester fosite.Requester, requester fosite.Requester,

View File

@ -1,7 +1,7 @@
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package oidc package strategy
import ( import (
"context" "context"
@ -20,7 +20,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gopkg.in/square/go-jose.v2" "gopkg.in/square/go-jose.v2"
"go.pinniped.dev/internal/oidc/jwks" "go.pinniped.dev/internal/federationdomain/endpoints/jwks"
"go.pinniped.dev/internal/testutil/oidctestutil" "go.pinniped.dev/internal/testutil/oidctestutil"
) )
@ -94,7 +94,7 @@ func TestDynamicOpenIDConnectECDSAStrategy(t *testing.T) {
if test.jwksProvider != nil { if test.jwksProvider != nil {
test.jwksProvider(jwksProvider) test.jwksProvider(jwksProvider)
} }
s := newDynamicOpenIDConnectECDSAStrategy( s := NewDynamicOpenIDConnectECDSAStrategy(
&fosite.Config{IDTokenIssuer: test.issuer}, &fosite.Config{IDTokenIssuer: test.issuer},
jwksProvider, jwksProvider,
) )

View File

@ -0,0 +1,74 @@
// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package timeouts
import "time"
type Configuration struct {
// The length of time that our state param that we encrypt and pass to the upstream OIDC IDP should be considered
// valid. If a state param generated by the authorize endpoint is sent to the callback endpoint after this much
// time has passed, then the callback endpoint should reject it. This allows us to set a limit on how long
// the end user has to finish their login with the upstream IDP, including the time that it takes to fumble
// with password manager and two-factor authenticator apps, and also accounting for taking a coffee break while
// the browser is sitting at the upstream IDP's login page.
UpstreamStateParamLifespan time.Duration
// How long an authcode issued by the callback endpoint is valid. This determines how much time the end user
// has to come back to exchange the authcode for tokens at the token endpoint.
AuthorizeCodeLifespan time.Duration
// The lifetime of an downstream access token issued by the token endpoint. Access tokens should generally
// be fairly short-lived.
AccessTokenLifespan time.Duration
// The lifetime of an downstream ID token issued by the token endpoint. This should generally be the same
// as the AccessTokenLifespan, or longer if it would be useful for the user's proof of identity to be valid
// for longer than their proof of authorization.
IDTokenLifespan time.Duration
// The lifetime of an downstream refresh token issued by the token endpoint. This should generally be
// significantly longer than the access token lifetime, so it can be used to refresh the access token
// multiple times. Once the refresh token expires, the user's session is over and they will need
// to start a new authorization request, which will require them to log in again with the upstream IDP
// in their web browser.
RefreshTokenLifespan time.Duration
// AuthorizationCodeSessionStorageLifetime is the length of time after which an authcode is allowed to be garbage
// collected from storage. Authcodes are kept in storage after they are redeemed to allow the system to mark the
// authcode as already used, so it can reject any future uses of the same authcode with special case handling which
// include revoking the access and refresh tokens associated with the session. Therefore, this should be
// significantly longer than the AuthorizeCodeLifespan, and there is probably no reason to make it longer than
// the sum of the AuthorizeCodeLifespan and the RefreshTokenLifespan.
AuthorizationCodeSessionStorageLifetime time.Duration
// PKCESessionStorageLifetime is the length of time after which PKCE data is allowed to be garbage collected from
// storage. PKCE sessions are closely related to authorization code sessions. After the authcode is successfully
// redeemed, the PKCE session is explicitly deleted. After the authcode expires, the PKCE session is no longer needed,
// but it is not explicitly deleted. Therefore, this can be just slightly longer than the AuthorizeCodeLifespan. We'll
// avoid making it exactly the same as AuthorizeCodeLifespan to avoid any chance of the garbage collector deleting it
// while it is being used.
PKCESessionStorageLifetime time.Duration
// OIDCSessionStorageLifetime is the length of time after which the OIDC session data related to an authcode
// is allowed to be garbage collected from storage. Due to a bug in an underlying library, these are not explicitly
// deleted. Similar to the PKCE session, they are not needed anymore after the corresponding authcode has expired.
// Therefore, this can be just slightly longer than the AuthorizeCodeLifespan. We'll avoid making it exactly the same
// as AuthorizeCodeLifespan to avoid any chance of the garbage collector deleting it while it is being used.
OIDCSessionStorageLifetime time.Duration
// AccessTokenSessionStorageLifetime is the length of time after which an access token's session data is allowed
// to be garbage collected from storage. These must exist in storage for as long as the refresh token is valid
// or else the refresh flow will not work properly. So this must be longer than RefreshTokenLifespan.
AccessTokenSessionStorageLifetime time.Duration
// RefreshTokenSessionStorageLifetime is the length of time after which a refresh token's session data is allowed
// to be garbage collected from storage. These must exist in storage for as long as the refresh token is valid.
// Therefore, this can be just slightly longer than the RefreshTokenLifespan. We'll avoid making it exactly the same
// as RefreshTokenLifespan to avoid any chance of the garbage collector deleting it while it is being used.
// If an expired token is still stored when the user tries to refresh it, then they will get a more specific
// error message telling them that the token is expired, rather than a more generic error that is returned
// when the token does not exist. If this is desirable, then the RefreshTokenSessionStorageLifetime can be made
// to be significantly larger than RefreshTokenLifespan, at the cost of slower cleanup.
RefreshTokenSessionStorageLifetime time.Duration
}

View File

@ -16,8 +16,8 @@ import (
"go.pinniped.dev/internal/constable" "go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/crud" "go.pinniped.dev/internal/crud"
"go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/fositestorage" "go.pinniped.dev/internal/fositestorage"
"go.pinniped.dev/internal/oidc/clientregistry"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
) )

View File

@ -22,7 +22,7 @@ import (
coretesting "k8s.io/client-go/testing" coretesting "k8s.io/client-go/testing"
clocktesting "k8s.io/utils/clock/testing" clocktesting "k8s.io/utils/clock/testing"
"go.pinniped.dev/internal/oidc/clientregistry" "go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
) )

View File

@ -17,8 +17,8 @@ import (
"go.pinniped.dev/internal/constable" "go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/crud" "go.pinniped.dev/internal/crud"
"go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/fositestorage" "go.pinniped.dev/internal/fositestorage"
"go.pinniped.dev/internal/oidc/clientregistry"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
) )

View File

@ -34,8 +34,8 @@ import (
kubetesting "k8s.io/client-go/testing" kubetesting "k8s.io/client-go/testing"
clocktesting "k8s.io/utils/clock/testing" clocktesting "k8s.io/utils/clock/testing"
"go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/fositestorage" "go.pinniped.dev/internal/fositestorage"
"go.pinniped.dev/internal/oidc/clientregistry"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
) )

View File

@ -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 // SPDX-License-Identifier: Apache-2.0
package fositestorage package fositestorage
@ -7,7 +7,7 @@ import (
"github.com/ory/fosite" "github.com/ory/fosite"
"go.pinniped.dev/internal/constable" "go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/oidc/clientregistry" "go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
) )

View File

@ -16,8 +16,8 @@ import (
"go.pinniped.dev/internal/constable" "go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/crud" "go.pinniped.dev/internal/crud"
"go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/fositestorage" "go.pinniped.dev/internal/fositestorage"
"go.pinniped.dev/internal/oidc/clientregistry"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
) )

View File

@ -21,7 +21,7 @@ import (
coretesting "k8s.io/client-go/testing" coretesting "k8s.io/client-go/testing"
clocktesting "k8s.io/utils/clock/testing" clocktesting "k8s.io/utils/clock/testing"
"go.pinniped.dev/internal/oidc/clientregistry" "go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
) )

View File

@ -15,8 +15,8 @@ import (
"go.pinniped.dev/internal/constable" "go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/crud" "go.pinniped.dev/internal/crud"
"go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/fositestorage" "go.pinniped.dev/internal/fositestorage"
"go.pinniped.dev/internal/oidc/clientregistry"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
) )

View File

@ -21,7 +21,7 @@ import (
coretesting "k8s.io/client-go/testing" coretesting "k8s.io/client-go/testing"
clocktesting "k8s.io/utils/clock/testing" clocktesting "k8s.io/utils/clock/testing"
"go.pinniped.dev/internal/oidc/clientregistry" "go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
) )

View File

@ -16,8 +16,8 @@ import (
"go.pinniped.dev/internal/constable" "go.pinniped.dev/internal/constable"
"go.pinniped.dev/internal/crud" "go.pinniped.dev/internal/crud"
"go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/fositestorage" "go.pinniped.dev/internal/fositestorage"
"go.pinniped.dev/internal/oidc/clientregistry"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
) )

View File

@ -22,7 +22,7 @@ import (
coretesting "k8s.io/client-go/testing" coretesting "k8s.io/client-go/testing"
clocktesting "k8s.io/utils/clock/testing" clocktesting "k8s.io/utils/clock/testing"
"go.pinniped.dev/internal/oidc/clientregistry" "go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
) )

View File

@ -1,6 +1,6 @@
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. // Copyright 2020-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package issuermocks package issuermocks
//go:generate go run -v github.com/golang/mock/mockgen -destination=issuermocks.go -package=issuermocks -copyright_file=../../../hack/header.txt go.pinniped.dev/internal/issuer ClientCertIssuer //go:generate go run -v github.com/golang/mock/mockgen -destination=issuermocks.go -package=issuermocks -copyright_file=../../../hack/header.txt go.pinniped.dev/internal/clientcertissuer ClientCertIssuer

View File

@ -3,7 +3,7 @@
// //
// Code generated by MockGen. DO NOT EDIT. // Code generated by MockGen. DO NOT EDIT.
// Source: go.pinniped.dev/internal/issuer (interfaces: ClientCertIssuer) // Source: go.pinniped.dev/internal/clientcertissuer (interfaces: ClientCertIssuer)
// Package issuermocks is a generated GoMock package. // Package issuermocks is a generated GoMock package.
package issuermocks package issuermocks

View File

@ -3,4 +3,4 @@
package mockupstreamoidcidentityprovider package mockupstreamoidcidentityprovider
//go:generate go run -v github.com/golang/mock/mockgen -destination=mockupstreamoidcidentityprovider.go -package=mockupstreamoidcidentityprovider -copyright_file=../../../hack/header.txt go.pinniped.dev/internal/oidc/provider/upstreamprovider UpstreamOIDCIdentityProviderI //go:generate go run -v github.com/golang/mock/mockgen -destination=mockupstreamoidcidentityprovider.go -package=mockupstreamoidcidentityprovider -copyright_file=../../../hack/header.txt go.pinniped.dev/internal/federationdomain/upstreamprovider UpstreamOIDCIdentityProviderI

View File

@ -3,7 +3,7 @@
// //
// Code generated by MockGen. DO NOT EDIT. // Code generated by MockGen. DO NOT EDIT.
// Source: go.pinniped.dev/internal/oidc/provider/upstreamprovider (interfaces: UpstreamOIDCIdentityProviderI) // Source: go.pinniped.dev/internal/federationdomain/upstreamprovider (interfaces: UpstreamOIDCIdentityProviderI)
// Package mockupstreamoidcidentityprovider is a generated GoMock package. // Package mockupstreamoidcidentityprovider is a generated GoMock package.
package mockupstreamoidcidentityprovider package mockupstreamoidcidentityprovider
@ -14,7 +14,7 @@ import (
reflect "reflect" reflect "reflect"
gomock "github.com/golang/mock/gomock" gomock "github.com/golang/mock/gomock"
upstreamprovider "go.pinniped.dev/internal/oidc/provider/upstreamprovider" upstreamprovider "go.pinniped.dev/internal/federationdomain/upstreamprovider"
nonce "go.pinniped.dev/pkg/oidcclient/nonce" nonce "go.pinniped.dev/pkg/oidcclient/nonce"
oidctypes "go.pinniped.dev/pkg/oidcclient/oidctypes" oidctypes "go.pinniped.dev/pkg/oidcclient/oidctypes"
pkce "go.pinniped.dev/pkg/oidcclient/pkce" pkce "go.pinniped.dev/pkg/oidcclient/pkce"

View File

@ -58,12 +58,13 @@ import (
"go.pinniped.dev/internal/deploymentref" "go.pinniped.dev/internal/deploymentref"
"go.pinniped.dev/internal/downward" "go.pinniped.dev/internal/downward"
"go.pinniped.dev/internal/dynamiccert" "go.pinniped.dev/internal/dynamiccert"
"go.pinniped.dev/internal/federationdomain/dynamictlscertprovider"
"go.pinniped.dev/internal/federationdomain/dynamicupstreamprovider"
"go.pinniped.dev/internal/federationdomain/endpoints/jwks"
"go.pinniped.dev/internal/federationdomain/endpointsmanager"
"go.pinniped.dev/internal/groupsuffix" "go.pinniped.dev/internal/groupsuffix"
"go.pinniped.dev/internal/kubeclient" "go.pinniped.dev/internal/kubeclient"
"go.pinniped.dev/internal/leaderelection" "go.pinniped.dev/internal/leaderelection"
"go.pinniped.dev/internal/oidc/jwks"
"go.pinniped.dev/internal/oidc/provider"
"go.pinniped.dev/internal/oidc/provider/manager"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/pversion" "go.pinniped.dev/internal/pversion"
"go.pinniped.dev/internal/secret" "go.pinniped.dev/internal/secret"
@ -129,10 +130,10 @@ func signalCtx() context.Context {
//nolint:funlen //nolint:funlen
func prepareControllers( func prepareControllers(
cfg *supervisor.Config, cfg *supervisor.Config,
issuerManager *manager.Manager, issuerManager *endpointsmanager.Manager,
dynamicJWKSProvider jwks.DynamicJWKSProvider, dynamicJWKSProvider jwks.DynamicJWKSProvider,
dynamicTLSCertProvider provider.DynamicTLSCertProvider, dynamicTLSCertProvider dynamictlscertprovider.DynamicTLSCertProvider,
dynamicUpstreamIDPProvider provider.DynamicUpstreamIDPProvider, dynamicUpstreamIDPProvider dynamicupstreamprovider.DynamicUpstreamIDPProvider,
dynamicServingCertProvider dynamiccert.Private, dynamicServingCertProvider dynamiccert.Private,
secretCache *secret.Cache, secretCache *secret.Cache,
supervisorDeployment *appsv1.Deployment, supervisorDeployment *appsv1.Deployment,
@ -436,12 +437,12 @@ func runSupervisor(ctx context.Context, podInfo *downward.PodInfo, cfg *supervis
dynamicServingCertProvider := dynamiccert.NewServingCert("supervisor-serving-cert") dynamicServingCertProvider := dynamiccert.NewServingCert("supervisor-serving-cert")
dynamicJWKSProvider := jwks.NewDynamicJWKSProvider() dynamicJWKSProvider := jwks.NewDynamicJWKSProvider()
dynamicTLSCertProvider := provider.NewDynamicTLSCertProvider() dynamicTLSCertProvider := dynamictlscertprovider.NewDynamicTLSCertProvider()
dynamicUpstreamIDPProvider := provider.NewDynamicUpstreamIDPProvider() dynamicUpstreamIDPProvider := dynamicupstreamprovider.NewDynamicUpstreamIDPProvider()
secretCache := secret.Cache{} secretCache := secret.Cache{}
// OIDC endpoints will be served by the oidProvidersManager, and any non-OIDC paths will fallback to the healthMux. // OIDC endpoints will be served by the oidProvidersManager, and any non-OIDC paths will fallback to the healthMux.
oidProvidersManager := manager.NewManager( oidProvidersManager := endpointsmanager.NewManager(
healthMux, healthMux,
dynamicJWKSProvider, dynamicJWKSProvider,
dynamicUpstreamIDPProvider, dynamicUpstreamIDPProvider,

View File

@ -1,4 +1,4 @@
// Copyright 2022 the Pinniped contributors. All Rights Reserved. // Copyright 2022-2023 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
package testutil package testutil
@ -6,10 +6,10 @@ package testutil
import ( import (
"testing" "testing"
"go.pinniped.dev/internal/oidc/oidcclientvalidator"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
) )
func TestBcryptConstants(t *testing.T) { func TestBcryptConstants(t *testing.T) {

View File

@ -30,19 +30,19 @@ import (
"go.pinniped.dev/internal/authenticators" "go.pinniped.dev/internal/authenticators"
"go.pinniped.dev/internal/crud" "go.pinniped.dev/internal/crud"
"go.pinniped.dev/internal/federationdomain/dynamicupstreamprovider"
"go.pinniped.dev/internal/federationdomain/resolvedprovider"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/fositestorage/authorizationcode" "go.pinniped.dev/internal/fositestorage/authorizationcode"
"go.pinniped.dev/internal/fositestorage/openidconnect" "go.pinniped.dev/internal/fositestorage/openidconnect"
pkce2 "go.pinniped.dev/internal/fositestorage/pkce" "go.pinniped.dev/internal/fositestorage/pkce"
"go.pinniped.dev/internal/fositestoragei" "go.pinniped.dev/internal/fositestoragei"
"go.pinniped.dev/internal/idtransform" "go.pinniped.dev/internal/idtransform"
"go.pinniped.dev/internal/oidc/provider"
"go.pinniped.dev/internal/oidc/provider/resolvedprovider"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/pkg/oidcclient/nonce" "go.pinniped.dev/pkg/oidcclient/nonce"
"go.pinniped.dev/pkg/oidcclient/oidctypes" "go.pinniped.dev/pkg/oidcclient/oidctypes"
"go.pinniped.dev/pkg/oidcclient/pkce" oidcpkce "go.pinniped.dev/pkg/oidcclient/pkce"
) )
// Test helpers for the OIDC package. // Test helpers for the OIDC package.
@ -52,7 +52,7 @@ import (
type ExchangeAuthcodeAndValidateTokenArgs struct { type ExchangeAuthcodeAndValidateTokenArgs struct {
Ctx context.Context Ctx context.Context
Authcode string Authcode string
PKCECodeVerifier pkce.Code PKCECodeVerifier oidcpkce.Code
ExpectedIDTokenNonce nonce.Nonce ExpectedIDTokenNonce nonce.Nonce
RedirectURI string RedirectURI string
} }
@ -267,7 +267,7 @@ type TestUpstreamOIDCIdentityProvider struct {
ExchangeAuthcodeAndValidateTokensFunc func( ExchangeAuthcodeAndValidateTokensFunc func(
ctx context.Context, ctx context.Context,
authcode string, authcode string,
pkceCodeVerifier pkce.Code, pkceCodeVerifier oidcpkce.Code,
expectedIDTokenNonce nonce.Nonce, expectedIDTokenNonce nonce.Nonce,
) (*oidctypes.Token, error) ) (*oidctypes.Token, error)
@ -358,7 +358,7 @@ func (u *TestUpstreamOIDCIdentityProvider) PasswordCredentialsGrantAndValidateTo
func (u *TestUpstreamOIDCIdentityProvider) ExchangeAuthcodeAndValidateTokens( func (u *TestUpstreamOIDCIdentityProvider) ExchangeAuthcodeAndValidateTokens(
ctx context.Context, ctx context.Context,
authcode string, authcode string,
pkceCodeVerifier pkce.Code, pkceCodeVerifier oidcpkce.Code,
expectedIDTokenNonce nonce.Nonce, expectedIDTokenNonce nonce.Nonce,
redirectURI string, redirectURI string,
) (*oidctypes.Token, error) { ) (*oidctypes.Token, error) {
@ -595,8 +595,8 @@ func (b *UpstreamIDPListerBuilder) BuildFederationDomainIdentityProvidersListerF
} }
} }
func (b *UpstreamIDPListerBuilder) BuildDynamicUpstreamIDPProvider() provider.DynamicUpstreamIDPProvider { func (b *UpstreamIDPListerBuilder) BuildDynamicUpstreamIDPProvider() dynamicupstreamprovider.DynamicUpstreamIDPProvider {
idpProvider := provider.NewDynamicUpstreamIDPProvider() idpProvider := dynamicupstreamprovider.NewDynamicUpstreamIDPProvider()
oidcUpstreams := make([]upstreamprovider.UpstreamOIDCIdentityProviderI, len(b.upstreamOIDCIdentityProviders)) oidcUpstreams := make([]upstreamprovider.UpstreamOIDCIdentityProviderI, len(b.upstreamOIDCIdentityProviders))
for i := range b.upstreamOIDCIdentityProviders { for i := range b.upstreamOIDCIdentityProviders {
@ -1038,7 +1038,7 @@ func (u *TestUpstreamOIDCIdentityProviderBuilder) Build() *TestUpstreamOIDCIdent
AdditionalClaimMappings: u.additionalClaimMappings, AdditionalClaimMappings: u.additionalClaimMappings,
DisplayNameForFederationDomain: u.displayNameForFederationDomain, DisplayNameForFederationDomain: u.displayNameForFederationDomain,
TransformsForFederationDomain: u.transformsForFederationDomain, TransformsForFederationDomain: u.transformsForFederationDomain,
ExchangeAuthcodeAndValidateTokensFunc: func(ctx context.Context, authcode string, pkceCodeVerifier pkce.Code, expectedIDTokenNonce nonce.Nonce) (*oidctypes.Token, error) { ExchangeAuthcodeAndValidateTokensFunc: func(ctx context.Context, authcode string, pkceCodeVerifier oidcpkce.Code, expectedIDTokenNonce nonce.Nonce) (*oidctypes.Token, error) {
if u.authcodeExchangeErr != nil { if u.authcodeExchangeErr != nil {
return nil, u.authcodeExchangeErr return nil, u.authcodeExchangeErr
} }
@ -1223,7 +1223,7 @@ func RequireAuthCodeRegexpMatch(
) )
// One PKCE should have been stored. // One PKCE should have been stored.
testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secretsClient, labels.Set{crud.SecretLabelKey: pkce2.TypeLabelValue}, 1) testutil.RequireNumberOfSecretsMatchingLabelSelector(t, secretsClient, labels.Set{crud.SecretLabelKey: pkce.TypeLabelValue}, 1)
validatePKCEStorage( validatePKCEStorage(
t, t,

View File

@ -27,8 +27,8 @@ import (
"go.pinniped.dev/internal/authenticators" "go.pinniped.dev/internal/authenticators"
"go.pinniped.dev/internal/crypto/ptls" "go.pinniped.dev/internal/crypto/ptls"
"go.pinniped.dev/internal/endpointaddr" "go.pinniped.dev/internal/endpointaddr"
"go.pinniped.dev/internal/oidc/downstreamsession" "go.pinniped.dev/internal/federationdomain/downstreamsession"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider" "go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
) )

View File

@ -25,8 +25,8 @@ import (
"go.pinniped.dev/internal/certauthority" "go.pinniped.dev/internal/certauthority"
"go.pinniped.dev/internal/crypto/ptls" "go.pinniped.dev/internal/crypto/ptls"
"go.pinniped.dev/internal/endpointaddr" "go.pinniped.dev/internal/endpointaddr"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/mocks/mockldapconn" "go.pinniped.dev/internal/mocks/mockldapconn"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/internal/testutil/tlsassertions" "go.pinniped.dev/internal/testutil/tlsassertions"
"go.pinniped.dev/internal/testutil/tlsserver" "go.pinniped.dev/internal/testutil/tlsserver"

View File

@ -21,9 +21,9 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc" oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/federationdomain/dynamicupstreamprovider"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/httputil/httperr" "go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/oidc/provider"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/pkg/oidcclient/nonce" "go.pinniped.dev/pkg/oidcclient/nonce"
"go.pinniped.dev/pkg/oidcclient/oidctypes" "go.pinniped.dev/pkg/oidcclient/oidctypes"
@ -221,7 +221,7 @@ func (p *ProviderConfig) tryRevokeToken(
if err != nil { if err != nil {
// Couldn't connect to the server or some similar error. // Couldn't connect to the server or some similar error.
// Could be a temporary network problem, so it might be worth retrying. // Could be a temporary network problem, so it might be worth retrying.
return false, provider.NewRetryableRevocationError(err) return false, dynamicupstreamprovider.NewRetryableRevocationError(err)
} }
defer resp.Body.Close() defer resp.Body.Close()
@ -271,7 +271,7 @@ func (p *ProviderConfig) tryRevokeToken(
// be caused by an underlying problem which could potentially become resolved in the near future. We'll be // be caused by an underlying problem which could potentially become resolved in the near future. We'll be
// optimistic and call all 5xx errors retryable. // optimistic and call all 5xx errors retryable.
plog.Trace("RevokeToken() got unexpected error response from provider's revocation endpoint", "providerName", p.Name, "usedBasicAuth", useBasicAuth, "statusCode", status) plog.Trace("RevokeToken() got unexpected error response from provider's revocation endpoint", "providerName", p.Name, "usedBasicAuth", useBasicAuth, "statusCode", status)
return false, provider.NewRetryableRevocationError(fmt.Errorf("server responded with status %d", status)) return false, dynamicupstreamprovider.NewRetryableRevocationError(fmt.Errorf("server responded with status %d", status))
default: default:
// Any other error is probably not due to failed client auth, and is probably not worth retrying later. // Any other error is probably not due to failed client auth, and is probably not worth retrying later.
plog.Trace("RevokeToken() got unexpected error response from provider's revocation endpoint", "providerName", p.Name, "usedBasicAuth", useBasicAuth, "statusCode", status) plog.Trace("RevokeToken() got unexpected error response from provider's revocation endpoint", "providerName", p.Name, "usedBasicAuth", useBasicAuth, "statusCode", status)

View File

@ -23,9 +23,9 @@ import (
"gopkg.in/square/go-jose.v2" "gopkg.in/square/go-jose.v2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"go.pinniped.dev/internal/federationdomain/dynamicupstreamprovider"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/mocks/mockkeyset" "go.pinniped.dev/internal/mocks/mockkeyset"
"go.pinniped.dev/internal/oidc/provider"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/pkg/oidcclient/nonce" "go.pinniped.dev/pkg/oidcclient/nonce"
"go.pinniped.dev/pkg/oidcclient/oidctypes" "go.pinniped.dev/pkg/oidcclient/oidctypes"
@ -715,8 +715,8 @@ func TestProviderConfig(t *testing.T) {
testutil.RequireErrorStringFromErr(t, err, tt.wantErr) testutil.RequireErrorStringFromErr(t, err, tt.wantErr)
if tt.wantRetryableErrType { if tt.wantRetryableErrType {
require.ErrorAs(t, err, &provider.RetryableRevocationError{}) require.ErrorAs(t, err, &dynamicupstreamprovider.RetryableRevocationError{})
} else if errors.As(err, &provider.RetryableRevocationError{}) { } else if errors.As(err, &dynamicupstreamprovider.RetryableRevocationError{}) {
// There is no NotErrorAs() assertion available in the current version of testify, so do the equivalent. // There is no NotErrorAs() assertion available in the current version of testify, so do the equivalent.
require.Fail(t, "error should not be As RetryableRevocationError") require.Fail(t, "error should not be As RetryableRevocationError")
} }

View File

@ -30,10 +30,10 @@ import (
"k8s.io/utils/strings/slices" "k8s.io/utils/strings/slices"
oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc" oidcapi "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/httputil/httperr" "go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/httputil/securityheader" "go.pinniped.dev/internal/httputil/securityheader"
"go.pinniped.dev/internal/net/phttp" "go.pinniped.dev/internal/net/phttp"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/upstreamoidc" "go.pinniped.dev/internal/upstreamoidc"
"go.pinniped.dev/pkg/oidcclient/nonce" "go.pinniped.dev/pkg/oidcclient/nonce"

View File

@ -28,11 +28,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"go.pinniped.dev/internal/federationdomain/upstreamprovider"
"go.pinniped.dev/internal/httputil/httperr" "go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/httputil/roundtripper" "go.pinniped.dev/internal/httputil/roundtripper"
"go.pinniped.dev/internal/mocks/mockupstreamoidcidentityprovider" "go.pinniped.dev/internal/mocks/mockupstreamoidcidentityprovider"
"go.pinniped.dev/internal/net/phttp" "go.pinniped.dev/internal/net/phttp"
"go.pinniped.dev/internal/oidc/provider/upstreamprovider"
"go.pinniped.dev/internal/plog" "go.pinniped.dev/internal/plog"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/internal/testutil/testlogger" "go.pinniped.dev/internal/testutil/testlogger"

View File

@ -160,7 +160,7 @@ Once dynamic clients are implemented:
#### New Dependencies #### New Dependencies
This should be kept to a very simple HTML page with minimal, clean CSS styling. This should be kept to a very simple HTML page with minimal, clean CSS styling.
Javascript should be avoided. Javascript should be avoided.
The styling should match the [form post html page](https://github.com/vmware-tanzu/pinniped/tree/main/internal/oidc/provider/formposthtml) The styling should match the [form post html page](https://github.com/vmware-tanzu/pinniped/tree/main/internal/federationdomain/formposthtml)
as much as possible, we should reuse some of the existing css and add to it to keep the style consistent. as much as possible, we should reuse some of the existing css and add to it to keep the style consistent.
#### Observability Considerations #### Observability Considerations

View File

@ -192,28 +192,28 @@ The Supervisor's endpoints are:
Each FederationDomain's endpoints are mounted under the path of the FederationDomain's `spec.issuer`, Each FederationDomain's endpoints are mounted under the path of the FederationDomain's `spec.issuer`,
if the `spec.issuer` URL has a path component specified. If the issuer has no path, then they are mounted under `/`. if the `spec.issuer` URL has a path component specified. If the issuer has no path, then they are mounted under `/`.
These per-FederationDomain endpoint are all mounted by the code in These per-FederationDomain endpoint are all mounted by the code in
[internal/oidc/provider/manager/manager.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/oidc/provider/manager/manager.go). [internal/federationdomain/endpointsmanager/manager.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/federationdomain/endpointsmanager/manager.go).
The per-FederationDomain endpoints are: The per-FederationDomain endpoints are:
- `<issuer_path>/.well-known/openid-configuration` is the standard OIDC discovery endpoint, which can be used to discover all the other endpoints listed here. - `<issuer_path>/.well-known/openid-configuration` is the standard OIDC discovery endpoint, which can be used to discover all the other endpoints listed here.
See [internal/oidc/discovery/discovery_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/oidc/discovery/discovery_handler.go). See [internal/federationdomain/endpoints/discovery/discovery_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/federationdomain/endpoints/discovery/discovery_handler.go).
- `<issuer_path>/jwks.json` is the standard OIDC JWKS discovery endpoint. - `<issuer_path>/jwks.json` is the standard OIDC JWKS discovery endpoint.
See [internal/oidc/jwks/jwks_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/oidc/jwks/jwks_handler.go). See [internal/federationdomain/endpoints/jwks/jwks_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/federationdomain/endpoints/jwks/jwks_handler.go).
- `<issuer_path>/oauth2/authorize` is the standard OIDC authorize endpoint. - `<issuer_path>/oauth2/authorize` is the standard OIDC authorize endpoint.
See [internal/oidc/auth/auth_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/oidc/auth/auth_handler.go). See [internal/federationdomain/endpoints/auth/auth_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/federationdomain/endpoints/auth/auth_handler.go).
- `<issuer_path>/oauth2/token` is the standard OIDC token endpoint. - `<issuer_path>/oauth2/token` is the standard OIDC token endpoint.
See [internal/oidc/token/token_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/oidc/token/token_handler.go). See [internal/federationdomain/endpoints/token/token_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/federationdomain/endpoints/token/token_handler.go).
The token endpoint can handle the standard OIDC `authorization_code` and `refresh_token` grant types, and has also been The token endpoint can handle the standard OIDC `authorization_code` and `refresh_token` grant types, and has also been
extended in [internal/oidc/token_exchange.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/oidc/token_exchange.go) extended in [internal/federationdomain/endpoints/tokenexchange/token_exchange.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/federationdomain/endpoints/tokenexchange/token_exchange.go)
to handle an additional grant type for [RFC 8693](https://datatracker.ietf.org/doc/html/rfc8693) token exchanges to to handle an additional grant type for [RFC 8693](https://datatracker.ietf.org/doc/html/rfc8693) token exchanges to
reduce the applicable scope (technically, the `aud` claim) of ID tokens. reduce the applicable scope (technically, the `aud` claim) of ID tokens.
- `<issuer_path>/callback` is a special endpoint that is used as the redirect URL when performing an OIDC authcode flow against an upstream OIDC identity provider as configured by an OIDCIdentityProvider custom resource. - `<issuer_path>/callback` is a special endpoint that is used as the redirect URL when performing an OIDC authcode flow against an upstream OIDC identity provider as configured by an OIDCIdentityProvider custom resource.
See [internal/oidc/callback/callback_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/oidc/callback/callback_handler.go). See [internal/federationdomain/endpoints/callback/callback_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/federationdomain/endpoints/callback/callback_handler.go).
- `<issuer_path>/v1alpha1/pinniped_identity_providers` is a custom discovery endpoint for clients to learn about available upstream identity providers. - `<issuer_path>/v1alpha1/pinniped_identity_providers` is a custom discovery endpoint for clients to learn about available upstream identity providers.
See [internal/oidc/idpdiscovery/idp_discovery_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/oidc/idpdiscovery/idp_discovery_handler.go). See [internal/federationdomain/endpoints/idpdiscovery/idp_discovery_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/federationdomain/endpoints/idpdiscovery/idp_discovery_handler.go).
- `<issuer_path>/login` is a login UI page to support the optional browser-based login flow for LDAP and Active Directory identity providers. - `<issuer_path>/login` is a login UI page to support the optional browser-based login flow for LDAP and Active Directory identity providers.
See [internal/oidc/login/login_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/oidc/login/login_handler.go). See [internal/federationdomain/endpoints/login/login_handler.go](https://github.com/vmware-tanzu/pinniped/blob/main/internal/federationdomain/endpoints/login/login_handler.go).
The OIDC specifications implemented by the Supervisor can be found at [openid.net](https://openid.net/connect). The OIDC specifications implemented by the Supervisor can be found at [openid.net](https://openid.net/connect).

View File

@ -19,8 +19,8 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.pinniped.dev/internal/federationdomain/formposthtml"
"go.pinniped.dev/internal/httputil/securityheader" "go.pinniped.dev/internal/httputil/securityheader"
"go.pinniped.dev/internal/oidc/provider/formposthtml"
"go.pinniped.dev/test/testlib" "go.pinniped.dev/test/testlib"
"go.pinniped.dev/test/testlib/browsertest" "go.pinniped.dev/test/testlib/browsertest"
) )

View File

@ -31,8 +31,9 @@ import (
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1" configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1" idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
"go.pinniped.dev/internal/certauthority" "go.pinniped.dev/internal/certauthority"
"go.pinniped.dev/internal/oidc" "go.pinniped.dev/internal/federationdomain/oidc"
"go.pinniped.dev/internal/oidc/oidcclientvalidator" "go.pinniped.dev/internal/federationdomain/oidcclientvalidator"
"go.pinniped.dev/internal/federationdomain/storage"
"go.pinniped.dev/internal/psession" "go.pinniped.dev/internal/psession"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/pkg/oidcclient/nonce" "go.pinniped.dev/pkg/oidcclient/nonce"
@ -2240,7 +2241,7 @@ func testSupervisorLogin(
// First use the latest downstream refresh token to look up the corresponding session in the Supervisor's storage. // First use the latest downstream refresh token to look up the corresponding session in the Supervisor's storage.
supervisorSecretsClient := testlib.NewKubernetesClientset(t).CoreV1().Secrets(env.SupervisorNamespace) supervisorSecretsClient := testlib.NewKubernetesClientset(t).CoreV1().Secrets(env.SupervisorNamespace)
supervisorOIDCClientsClient := testlib.NewSupervisorClientset(t).ConfigV1alpha1().OIDCClients(env.SupervisorNamespace) supervisorOIDCClientsClient := testlib.NewSupervisorClientset(t).ConfigV1alpha1().OIDCClients(env.SupervisorNamespace)
oauthStore := oidc.NewKubeStorage(supervisorSecretsClient, supervisorOIDCClientsClient, oidc.DefaultOIDCTimeoutsConfiguration(), oidcclientvalidator.DefaultMinBcryptCost) oauthStore := storage.NewKubeStorage(supervisorSecretsClient, supervisorOIDCClientsClient, oidc.DefaultOIDCTimeoutsConfiguration(), oidcclientvalidator.DefaultMinBcryptCost)
storedRefreshSession, err := oauthStore.GetRefreshTokenSession(ctx, signatureOfLatestRefreshToken, nil) storedRefreshSession, err := oauthStore.GetRefreshTokenSession(ctx, signatureOfLatestRefreshToken, nil)
require.NoError(t, err) require.NoError(t, err)
@ -2302,7 +2303,7 @@ func testSupervisorLogin(
// First use the latest downstream refresh token to look up the corresponding session in the Supervisor's storage. // First use the latest downstream refresh token to look up the corresponding session in the Supervisor's storage.
supervisorSecretsClient := testlib.NewKubernetesClientset(t).CoreV1().Secrets(env.SupervisorNamespace) supervisorSecretsClient := testlib.NewKubernetesClientset(t).CoreV1().Secrets(env.SupervisorNamespace)
supervisorOIDCClientsClient := testlib.NewSupervisorClientset(t).ConfigV1alpha1().OIDCClients(env.SupervisorNamespace) supervisorOIDCClientsClient := testlib.NewSupervisorClientset(t).ConfigV1alpha1().OIDCClients(env.SupervisorNamespace)
oauthStore := oidc.NewKubeStorage(supervisorSecretsClient, supervisorOIDCClientsClient, oidc.DefaultOIDCTimeoutsConfiguration(), oidcclientvalidator.DefaultMinBcryptCost) oauthStore := storage.NewKubeStorage(supervisorSecretsClient, supervisorOIDCClientsClient, oidc.DefaultOIDCTimeoutsConfiguration(), oidcclientvalidator.DefaultMinBcryptCost)
storedRefreshSession, err := oauthStore.GetRefreshTokenSession(ctx, signatureOfLatestRefreshToken, nil) storedRefreshSession, err := oauthStore.GetRefreshTokenSession(ctx, signatureOfLatestRefreshToken, nil)
require.NoError(t, err) require.NoError(t, err)

View File

@ -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 // SPDX-License-Identifier: Apache-2.0
package integration package integration
@ -17,8 +17,8 @@ import (
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"go.pinniped.dev/internal/federationdomain/clientregistry"
"go.pinniped.dev/internal/fositestorage/authorizationcode" "go.pinniped.dev/internal/fositestorage/authorizationcode"
"go.pinniped.dev/internal/oidc/clientregistry"
"go.pinniped.dev/internal/testutil" "go.pinniped.dev/internal/testutil"
"go.pinniped.dev/test/testlib" "go.pinniped.dev/test/testlib"
) )

Some files were not shown because too many files have changed in this diff Show More