diff --git a/internal/oidc/auth/auth_handler_test.go b/internal/oidc/auth/auth_handler_test.go index b6d71f9e..e7658e83 100644 --- a/internal/oidc/auth/auth_handler_test.go +++ b/internal/oidc/auth/auth_handler_test.go @@ -14,8 +14,6 @@ import ( "testing" "github.com/gorilla/securecookie" - "github.com/ory/fosite" - "github.com/ory/fosite/storage" "github.com/stretchr/testify/require" "go.pinniped.dev/internal/here" @@ -123,12 +121,7 @@ func TestAuthorizationEndpoint(t *testing.T) { issuer := "https://my-issuer.com/some-path" // Configure fosite the same way that the production code would, except use in-memory storage. - oauthStore := &storage.MemoryStore{ - Clients: map[string]fosite.Client{oidc.PinnipedCLIOIDCClient().ID: oidc.PinnipedCLIOIDCClient()}, - AuthorizeCodes: map[string]storage.StoreAuthorizeCode{}, - PKCES: map[string]fosite.Requester{}, - IDSessions: map[string]fosite.Requester{}, - } + oauthStore := oidc.NullStorage{} hmacSecret := []byte("some secret - must have at least 32 bytes") require.GreaterOrEqual(t, len(hmacSecret), 32, "fosite requires that hmac secrets have at least 32 bytes") oauthHelper := oidc.FositeOauth2Helper(oauthStore, hmacSecret) diff --git a/internal/oidc/nullstorage.go b/internal/oidc/nullstorage.go new file mode 100644 index 00000000..3767f889 --- /dev/null +++ b/internal/oidc/nullstorage.go @@ -0,0 +1,101 @@ +// Copyright 2020 the Pinniped contributors. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package oidc + +import ( + "context" + "time" + + "github.com/ory/fosite" + + "go.pinniped.dev/internal/constable" +) + +const errNotImplemented = constable.Error("NullStorage does not implement this method. It should not have been called.") + +type NullStorage struct{} + +func (NullStorage) RevokeRefreshToken(_ context.Context, _ string) error { + return errNotImplemented +} + +func (NullStorage) RevokeAccessToken(_ context.Context, _ string) error { + return errNotImplemented +} + +func (NullStorage) CreateRefreshTokenSession(_ context.Context, _ string, _ fosite.Requester) (err error) { + return nil +} + +func (NullStorage) GetRefreshTokenSession(_ context.Context, _ string, _ fosite.Session) (request fosite.Requester, err error) { + return nil, errNotImplemented +} + +func (NullStorage) DeleteRefreshTokenSession(_ context.Context, _ string) (err error) { + return errNotImplemented +} + +func (NullStorage) CreateAccessTokenSession(_ context.Context, _ string, _ fosite.Requester) (err error) { + return nil +} + +func (NullStorage) GetAccessTokenSession(_ context.Context, _ string, _ fosite.Session) (request fosite.Requester, err error) { + return nil, errNotImplemented +} + +func (NullStorage) DeleteAccessTokenSession(_ context.Context, _ string) (err error) { + return errNotImplemented +} + +func (NullStorage) CreateOpenIDConnectSession(_ context.Context, _ string, _ fosite.Requester) error { + return nil +} + +func (NullStorage) GetOpenIDConnectSession(_ context.Context, _ string, _ fosite.Requester) (fosite.Requester, error) { + return nil, errNotImplemented +} + +func (NullStorage) DeleteOpenIDConnectSession(_ context.Context, _ string) error { + return errNotImplemented +} + +func (NullStorage) GetPKCERequestSession(_ context.Context, _ string, _ fosite.Session) (fosite.Requester, error) { + return nil, errNotImplemented +} + +func (NullStorage) CreatePKCERequestSession(_ context.Context, _ string, _ fosite.Requester) error { + return nil +} + +func (NullStorage) DeletePKCERequestSession(_ context.Context, _ string) error { + return errNotImplemented +} + +func (NullStorage) CreateAuthorizeCodeSession(_ context.Context, _ string, _ fosite.Requester) (err error) { + return nil +} + +func (NullStorage) GetAuthorizeCodeSession(_ context.Context, _ string, _ fosite.Session) (request fosite.Requester, err error) { + return nil, errNotImplemented +} + +func (NullStorage) InvalidateAuthorizeCodeSession(_ context.Context, _ string) (err error) { + return errNotImplemented +} + +func (NullStorage) GetClient(_ context.Context, id string) (fosite.Client, error) { + client := PinnipedCLIOIDCClient() + if client.ID == id { + return client, nil + } + return nil, fosite.ErrNotFound +} + +func (NullStorage) ClientAssertionJWTValid(_ context.Context, _ string) error { + return errNotImplemented +} + +func (NullStorage) SetClientAssertionJWT(_ context.Context, _ string, _ time.Time) error { + return errNotImplemented +} diff --git a/internal/oidc/nullstorage_test.go b/internal/oidc/nullstorage_test.go new file mode 100644 index 00000000..8555c031 --- /dev/null +++ b/internal/oidc/nullstorage_test.go @@ -0,0 +1,36 @@ +// Copyright 2020 the Pinniped contributors. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package oidc + +import ( + "context" + "testing" + + "github.com/ory/fosite" + "github.com/stretchr/testify/require" +) + +func TestNullStorage_GetClient(t *testing.T) { + storage := NullStorage{} + + client, err := storage.GetClient(context.Background(), "some-other-client") + require.Equal(t, fosite.ErrNotFound, err) + require.Zero(t, client) + + client, err = storage.GetClient(context.Background(), "pinniped-cli") + require.NoError(t, err) + require.Equal(t, + &fosite.DefaultOpenIDConnectClient{ + DefaultClient: &fosite.DefaultClient{ + ID: "pinniped-cli", + Public: true, + RedirectURIs: []string{"http://127.0.0.1/callback"}, + ResponseTypes: []string{"code"}, + GrantTypes: []string{"authorization_code"}, + Scopes: []string{"openid", "profile", "email"}, + }, + }, + client, + ) +} diff --git a/internal/oidc/provider/manager/manager.go b/internal/oidc/provider/manager/manager.go index 1cb37fc8..6badff09 100644 --- a/internal/oidc/provider/manager/manager.go +++ b/internal/oidc/provider/manager/manager.go @@ -9,8 +9,6 @@ import ( "sync" "github.com/gorilla/securecookie" - "github.com/ory/fosite" - "github.com/ory/fosite/storage" "go.pinniped.dev/internal/oidc" "go.pinniped.dev/internal/oidc/auth" @@ -70,17 +68,12 @@ func (m *Manager) SetProviders(oidcProviders ...*provider.OIDCProvider) { jwksURL := strings.ToLower(incomingProvider.IssuerHost()) + "/" + incomingProvider.IssuerPath() + oidc.JWKSEndpointPath m.providerHandlers[jwksURL] = jwks.NewHandler(incomingProvider.Issuer(), m.dynamicJWKSProvider) - // Each OIDC provider gets its own storage. - oauthStore := &storage.MemoryStore{ - Clients: map[string]fosite.Client{oidc.PinnipedCLIOIDCClient().ID: oidc.PinnipedCLIOIDCClient()}, - AuthorizeCodes: map[string]storage.StoreAuthorizeCode{}, - PKCES: map[string]fosite.Requester{}, - IDSessions: map[string]fosite.Requester{}, - } - oauthHelper := oidc.FositeOauth2Helper(oauthStore, []byte("some secret - must have at least 32 bytes")) // TODO replace this secret + // Use NullStorage for the authorize endpoint because we do not actually want to store anything until + // the upstream callback endpoint is called later. + oauthHelper := oidc.FositeOauth2Helper(oidc.NullStorage{}, []byte("some secret - must have at least 32 bytes")) // TODO replace this secret - var encoderHashKey = []byte("fake-hash-secret") // TODO fix this - var encoderBlockKey = []byte("16-bytes-aaaaaaa") // TODO fix this + var encoderHashKey = []byte("fake-hash-secret") // TODO replace this secret + var encoderBlockKey = []byte("16-bytes-aaaaaaa") // TODO replace this secret var encoder = securecookie.New(encoderHashKey, encoderBlockKey) encoder.SetSerializer(securecookie.JSONEncoder{})