From db6fc234b78101b7111263f5de7db6b553535daa Mon Sep 17 00:00:00 2001 From: Monis Khan Date: Wed, 11 Nov 2020 14:49:24 -0800 Subject: [PATCH] Add NullStorage for the authorize endpoint to use We want to run all of the fosite validations in the authorize endpoint, but we don't need to store anything yet because we are storing what we need for later in the upstream state parameter. Signed-off-by: Ryan Richard --- internal/oidc/auth/auth_handler_test.go | 9 +- internal/oidc/nullstorage.go | 101 ++++++++++++++++++++++ internal/oidc/nullstorage_test.go | 36 ++++++++ internal/oidc/provider/manager/manager.go | 17 ++-- 4 files changed, 143 insertions(+), 20 deletions(-) create mode 100644 internal/oidc/nullstorage.go create mode 100644 internal/oidc/nullstorage_test.go 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{})