reorganize federation domain packages to be more intuitive
Co-authored-by: Benjamin A. Petersen <ben@benjaminapetersen.me>
This commit is contained in:
parent
3160b5bad1
commit
86c791b8a6
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -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"}),
|
||||||
})
|
})
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -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"}),
|
||||||
})
|
})
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -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 {
|
||||||
|
@ -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"},
|
||||||
})
|
})
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -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
|
||||||
|
@ -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())
|
||||||
|
@ -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"
|
||||||
)
|
)
|
@ -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"
|
||||||
)
|
)
|
@ -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.
|
@ -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
|
@ -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
|
@ -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
|
@ -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"
|
@ -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{}
|
@ -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
|
@ -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"
|
@ -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 {
|
@ -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"
|
@ -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)
|
||||||
}
|
}
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
@ -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()
|
@ -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
|
@ -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) {
|
@ -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.
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
@ -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
|
@ -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.
|
@ -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
|
@ -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 (
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
@ -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"
|
||||||
)
|
)
|
@ -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 {
|
@ -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:
|
@ -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.
|
@ -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 (
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
@ -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()
|
@ -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"
|
||||||
)
|
)
|
@ -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()
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
@ -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,
|
@ -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"
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
@ -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 {
|
@ -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">
|
@ -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 = () => {
|
@ -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.
|
@ -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
|
@ -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 {
|
@ -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
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
@ -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"
|
@ -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
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
@ -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
|
||||||
)
|
)
|
@ -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,
|
@ -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,
|
||||||
)
|
)
|
74
internal/federationdomain/timeouts/timeouts_configuration.go
Normal file
74
internal/federationdomain/timeouts/timeouts_configuration.go
Normal 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
|
||||||
|
}
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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,
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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)
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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).
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
Loading…
Reference in New Issue
Block a user