Merge pull request #673 from mattmoyer/refactor-static-client-struct-second-attempt
Use a custom type for our static CLI client.
This commit is contained in:
commit
3f41261580
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package accesstoken
|
package accesstoken
|
||||||
@ -17,6 +17,7 @@ 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/fositestorage"
|
"go.pinniped.dev/internal/fositestorage"
|
||||||
|
"go.pinniped.dev/internal/oidc/clientregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -108,7 +109,7 @@ func (a *accessTokenStorage) getSession(ctx context.Context, signature string) (
|
|||||||
func newValidEmptyAccessTokenSession() *session {
|
func newValidEmptyAccessTokenSession() *session {
|
||||||
return &session{
|
return &session{
|
||||||
Request: &fosite.Request{
|
Request: &fosite.Request{
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
Session: &openid.DefaultSession{},
|
Session: &openid.DefaultSession{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package accesstoken
|
package accesstoken
|
||||||
@ -20,6 +20,8 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
coretesting "k8s.io/client-go/testing"
|
coretesting "k8s.io/client-go/testing"
|
||||||
|
|
||||||
|
"go.pinniped.dev/internal/oidc/clientregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const namespace = "test-ns"
|
const namespace = "test-ns"
|
||||||
@ -63,24 +65,25 @@ func TestAccessTokenStorage(t *testing.T) {
|
|||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
ID: "abcd-1",
|
ID: "abcd-1",
|
||||||
RequestedAt: time.Time{},
|
RequestedAt: time.Time{},
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{
|
Client: &clientregistry.Client{
|
||||||
DefaultClient: &fosite.DefaultClient{
|
DefaultOpenIDConnectClient: fosite.DefaultOpenIDConnectClient{
|
||||||
ID: "pinny",
|
DefaultClient: &fosite.DefaultClient{
|
||||||
Secret: nil,
|
ID: "pinny",
|
||||||
RedirectURIs: nil,
|
Secret: nil,
|
||||||
GrantTypes: nil,
|
RedirectURIs: nil,
|
||||||
ResponseTypes: nil,
|
GrantTypes: nil,
|
||||||
Scopes: nil,
|
ResponseTypes: nil,
|
||||||
Audience: nil,
|
Scopes: nil,
|
||||||
Public: true,
|
Audience: nil,
|
||||||
},
|
Public: true,
|
||||||
JSONWebKeysURI: "where",
|
},
|
||||||
JSONWebKeys: nil,
|
JSONWebKeysURI: "where",
|
||||||
TokenEndpointAuthMethod: "something",
|
JSONWebKeys: nil,
|
||||||
RequestURIs: nil,
|
TokenEndpointAuthMethod: "something",
|
||||||
RequestObjectSigningAlgorithm: "",
|
RequestURIs: nil,
|
||||||
TokenEndpointAuthSigningAlgorithm: "",
|
RequestObjectSigningAlgorithm: "",
|
||||||
},
|
TokenEndpointAuthSigningAlgorithm: "",
|
||||||
|
}},
|
||||||
RequestedScope: nil,
|
RequestedScope: nil,
|
||||||
GrantedScope: nil,
|
GrantedScope: nil,
|
||||||
Form: url.Values{"key": []string{"val"}},
|
Form: url.Values{"key": []string{"val"}},
|
||||||
@ -138,13 +141,15 @@ func TestAccessTokenStorageRevocation(t *testing.T) {
|
|||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
ID: "abcd-1",
|
ID: "abcd-1",
|
||||||
RequestedAt: time.Time{},
|
RequestedAt: time.Time{},
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{
|
Client: &clientregistry.Client{
|
||||||
DefaultClient: &fosite.DefaultClient{
|
DefaultOpenIDConnectClient: fosite.DefaultOpenIDConnectClient{
|
||||||
ID: "pinny",
|
DefaultClient: &fosite.DefaultClient{
|
||||||
Public: true,
|
ID: "pinny",
|
||||||
|
Public: true,
|
||||||
|
},
|
||||||
|
JSONWebKeysURI: "where",
|
||||||
|
TokenEndpointAuthMethod: "something",
|
||||||
},
|
},
|
||||||
JSONWebKeysURI: "where",
|
|
||||||
TokenEndpointAuthMethod: "something",
|
|
||||||
},
|
},
|
||||||
Form: url.Values{"key": []string{"val"}},
|
Form: url.Values{"key": []string{"val"}},
|
||||||
Session: &openid.DefaultSession{
|
Session: &openid.DefaultSession{
|
||||||
@ -238,7 +243,7 @@ func TestCreateWithWrongRequesterDataTypes(t *testing.T) {
|
|||||||
|
|
||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
Session: nil,
|
Session: nil,
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
}
|
}
|
||||||
err := storage.CreateAccessTokenSession(ctx, "signature-doesnt-matter", request)
|
err := storage.CreateAccessTokenSession(ctx, "signature-doesnt-matter", request)
|
||||||
require.EqualError(t, err, "requester's session must be of type openid.DefaultSession")
|
require.EqualError(t, err, "requester's session must be of type openid.DefaultSession")
|
||||||
@ -248,7 +253,7 @@ func TestCreateWithWrongRequesterDataTypes(t *testing.T) {
|
|||||||
Client: nil,
|
Client: nil,
|
||||||
}
|
}
|
||||||
err = storage.CreateAccessTokenSession(ctx, "signature-doesnt-matter", request)
|
err = storage.CreateAccessTokenSession(ctx, "signature-doesnt-matter", request)
|
||||||
require.EqualError(t, err, "requester's client must be of type fosite.DefaultOpenIDConnectClient")
|
require.EqualError(t, err, "requester's client must be of type clientregistry.Client")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateWithoutRequesterID(t *testing.T) {
|
func TestCreateWithoutRequesterID(t *testing.T) {
|
||||||
@ -257,7 +262,7 @@ func TestCreateWithoutRequesterID(t *testing.T) {
|
|||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
ID: "", // empty ID
|
ID: "", // empty ID
|
||||||
Session: &openid.DefaultSession{},
|
Session: &openid.DefaultSession{},
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
}
|
}
|
||||||
err := storage.CreateAccessTokenSession(ctx, "signature-doesnt-matter", request)
|
err := storage.CreateAccessTokenSession(ctx, "signature-doesnt-matter", request)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package authorizationcode
|
package authorizationcode
|
||||||
@ -18,6 +18,7 @@ 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/fositestorage"
|
"go.pinniped.dev/internal/fositestorage"
|
||||||
|
"go.pinniped.dev/internal/oidc/clientregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -137,7 +138,7 @@ func (a *authorizeCodeStorage) getSession(ctx context.Context, signature string)
|
|||||||
func NewValidEmptyAuthorizeCodeSession() *AuthorizeCodeSession {
|
func NewValidEmptyAuthorizeCodeSession() *AuthorizeCodeSession {
|
||||||
return &AuthorizeCodeSession{
|
return &AuthorizeCodeSession{
|
||||||
Request: &fosite.Request{
|
Request: &fosite.Request{
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
Session: &openid.DefaultSession{},
|
Session: &openid.DefaultSession{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package authorizationcode
|
package authorizationcode
|
||||||
@ -33,6 +33,7 @@ import (
|
|||||||
kubetesting "k8s.io/client-go/testing"
|
kubetesting "k8s.io/client-go/testing"
|
||||||
|
|
||||||
"go.pinniped.dev/internal/fositestorage"
|
"go.pinniped.dev/internal/fositestorage"
|
||||||
|
"go.pinniped.dev/internal/oidc/clientregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const namespace = "test-ns"
|
const namespace = "test-ns"
|
||||||
@ -92,23 +93,25 @@ func TestAuthorizationCodeStorage(t *testing.T) {
|
|||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
ID: "abcd-1",
|
ID: "abcd-1",
|
||||||
RequestedAt: time.Time{},
|
RequestedAt: time.Time{},
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{
|
Client: &clientregistry.Client{
|
||||||
DefaultClient: &fosite.DefaultClient{
|
DefaultOpenIDConnectClient: fosite.DefaultOpenIDConnectClient{
|
||||||
ID: "pinny",
|
DefaultClient: &fosite.DefaultClient{
|
||||||
Secret: nil,
|
ID: "pinny",
|
||||||
RedirectURIs: nil,
|
Secret: nil,
|
||||||
GrantTypes: nil,
|
RedirectURIs: nil,
|
||||||
ResponseTypes: nil,
|
GrantTypes: nil,
|
||||||
Scopes: nil,
|
ResponseTypes: nil,
|
||||||
Audience: nil,
|
Scopes: nil,
|
||||||
Public: true,
|
Audience: nil,
|
||||||
|
Public: true,
|
||||||
|
},
|
||||||
|
JSONWebKeysURI: "where",
|
||||||
|
JSONWebKeys: nil,
|
||||||
|
TokenEndpointAuthMethod: "something",
|
||||||
|
RequestURIs: nil,
|
||||||
|
RequestObjectSigningAlgorithm: "",
|
||||||
|
TokenEndpointAuthSigningAlgorithm: "",
|
||||||
},
|
},
|
||||||
JSONWebKeysURI: "where",
|
|
||||||
JSONWebKeys: nil,
|
|
||||||
TokenEndpointAuthMethod: "something",
|
|
||||||
RequestURIs: nil,
|
|
||||||
RequestObjectSigningAlgorithm: "",
|
|
||||||
TokenEndpointAuthSigningAlgorithm: "",
|
|
||||||
},
|
},
|
||||||
RequestedScope: nil,
|
RequestedScope: nil,
|
||||||
GrantedScope: nil,
|
GrantedScope: nil,
|
||||||
@ -169,7 +172,7 @@ func TestInvalidateWhenConflictOnUpdateHappens(t *testing.T) {
|
|||||||
|
|
||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
ID: "some-request-id",
|
ID: "some-request-id",
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
Session: &openid.DefaultSession{},
|
Session: &openid.DefaultSession{},
|
||||||
}
|
}
|
||||||
err := storage.CreateAuthorizeCodeSession(ctx, "fancy-signature", request)
|
err := storage.CreateAuthorizeCodeSession(ctx, "fancy-signature", request)
|
||||||
@ -240,7 +243,7 @@ func TestCreateWithWrongRequesterDataTypes(t *testing.T) {
|
|||||||
|
|
||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
Session: nil,
|
Session: nil,
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
}
|
}
|
||||||
err := storage.CreateAuthorizeCodeSession(ctx, "signature-doesnt-matter", request)
|
err := storage.CreateAuthorizeCodeSession(ctx, "signature-doesnt-matter", request)
|
||||||
require.EqualError(t, err, "requester's session must be of type openid.DefaultSession")
|
require.EqualError(t, err, "requester's session must be of type openid.DefaultSession")
|
||||||
@ -250,7 +253,7 @@ func TestCreateWithWrongRequesterDataTypes(t *testing.T) {
|
|||||||
Client: nil,
|
Client: nil,
|
||||||
}
|
}
|
||||||
err = storage.CreateAuthorizeCodeSession(ctx, "signature-doesnt-matter", request)
|
err = storage.CreateAuthorizeCodeSession(ctx, "signature-doesnt-matter", request)
|
||||||
require.EqualError(t, err, "requester's client must be of type fosite.DefaultOpenIDConnectClient")
|
require.EqualError(t, err, "requester's client must be of type clientregistry.Client")
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeTestSubject() (context.Context, *fake.Clientset, corev1client.SecretInterface, oauth2.AuthorizeCodeStorage) {
|
func makeTestSubject() (context.Context, *fake.Clientset, corev1client.SecretInterface, oauth2.AuthorizeCodeStorage) {
|
||||||
@ -270,7 +273,7 @@ func TestFuzzAndJSONNewValidEmptyAuthorizeCodeSession(t *testing.T) {
|
|||||||
require.Equal(t, validSession.Request, extractedRequest)
|
require.Equal(t, validSession.Request, extractedRequest)
|
||||||
|
|
||||||
// checked above
|
// checked above
|
||||||
defaultClient := validSession.Request.Client.(*fosite.DefaultOpenIDConnectClient)
|
defaultClient := validSession.Request.Client.(*clientregistry.Client)
|
||||||
defaultSession := validSession.Request.Session.(*openid.DefaultSession)
|
defaultSession := validSession.Request.Session.(*openid.DefaultSession)
|
||||||
|
|
||||||
// makes it easier to use a raw string
|
// makes it easier to use a raw string
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package fositestorage
|
package fositestorage
|
||||||
@ -8,11 +8,12 @@ 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/clientregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ErrInvalidRequestType = constable.Error("requester must be of type fosite.Request")
|
ErrInvalidRequestType = constable.Error("requester must be of type fosite.Request")
|
||||||
ErrInvalidClientType = constable.Error("requester's client must be of type fosite.DefaultOpenIDConnectClient")
|
ErrInvalidClientType = constable.Error("requester's client must be of type clientregistry.Client")
|
||||||
ErrInvalidSessionType = constable.Error("requester's session must be of type openid.DefaultSession")
|
ErrInvalidSessionType = constable.Error("requester's session must be of type openid.DefaultSession")
|
||||||
StorageRequestIDLabelName = "storage.pinniped.dev/request-id" //nolint:gosec // this is not a credential
|
StorageRequestIDLabelName = "storage.pinniped.dev/request-id" //nolint:gosec // this is not a credential
|
||||||
)
|
)
|
||||||
@ -22,7 +23,7 @@ func ValidateAndExtractAuthorizeRequest(requester fosite.Requester) (*fosite.Req
|
|||||||
if !ok1 {
|
if !ok1 {
|
||||||
return nil, ErrInvalidRequestType
|
return nil, ErrInvalidRequestType
|
||||||
}
|
}
|
||||||
_, ok2 := request.Client.(*fosite.DefaultOpenIDConnectClient)
|
_, ok2 := request.Client.(*clientregistry.Client)
|
||||||
if !ok2 {
|
if !ok2 {
|
||||||
return nil, ErrInvalidClientType
|
return nil, ErrInvalidClientType
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package openidconnect
|
package openidconnect
|
||||||
@ -17,6 +17,7 @@ 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/fositestorage"
|
"go.pinniped.dev/internal/fositestorage"
|
||||||
|
"go.pinniped.dev/internal/oidc/clientregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -110,7 +111,7 @@ func (a *openIDConnectRequestStorage) getSession(ctx context.Context, signature
|
|||||||
func newValidEmptyOIDCSession() *session {
|
func newValidEmptyOIDCSession() *session {
|
||||||
return &session{
|
return &session{
|
||||||
Request: &fosite.Request{
|
Request: &fosite.Request{
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
Session: &openid.DefaultSession{},
|
Session: &openid.DefaultSession{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package openidconnect
|
package openidconnect
|
||||||
@ -20,6 +20,8 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
coretesting "k8s.io/client-go/testing"
|
coretesting "k8s.io/client-go/testing"
|
||||||
|
|
||||||
|
"go.pinniped.dev/internal/oidc/clientregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const namespace = "test-ns"
|
const namespace = "test-ns"
|
||||||
@ -62,23 +64,25 @@ func TestOpenIdConnectStorage(t *testing.T) {
|
|||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
ID: "abcd-1",
|
ID: "abcd-1",
|
||||||
RequestedAt: time.Time{},
|
RequestedAt: time.Time{},
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{
|
Client: &clientregistry.Client{
|
||||||
DefaultClient: &fosite.DefaultClient{
|
DefaultOpenIDConnectClient: fosite.DefaultOpenIDConnectClient{
|
||||||
ID: "pinny",
|
DefaultClient: &fosite.DefaultClient{
|
||||||
Secret: nil,
|
ID: "pinny",
|
||||||
RedirectURIs: nil,
|
Secret: nil,
|
||||||
GrantTypes: nil,
|
RedirectURIs: nil,
|
||||||
ResponseTypes: nil,
|
GrantTypes: nil,
|
||||||
Scopes: nil,
|
ResponseTypes: nil,
|
||||||
Audience: nil,
|
Scopes: nil,
|
||||||
Public: true,
|
Audience: nil,
|
||||||
|
Public: true,
|
||||||
|
},
|
||||||
|
JSONWebKeysURI: "where",
|
||||||
|
JSONWebKeys: nil,
|
||||||
|
TokenEndpointAuthMethod: "something",
|
||||||
|
RequestURIs: nil,
|
||||||
|
RequestObjectSigningAlgorithm: "",
|
||||||
|
TokenEndpointAuthSigningAlgorithm: "",
|
||||||
},
|
},
|
||||||
JSONWebKeysURI: "where",
|
|
||||||
JSONWebKeys: nil,
|
|
||||||
TokenEndpointAuthMethod: "something",
|
|
||||||
RequestURIs: nil,
|
|
||||||
RequestObjectSigningAlgorithm: "",
|
|
||||||
TokenEndpointAuthSigningAlgorithm: "",
|
|
||||||
},
|
},
|
||||||
RequestedScope: nil,
|
RequestedScope: nil,
|
||||||
GrantedScope: nil,
|
GrantedScope: nil,
|
||||||
@ -176,7 +180,7 @@ func TestCreateWithWrongRequesterDataTypes(t *testing.T) {
|
|||||||
|
|
||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
Session: nil,
|
Session: nil,
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
}
|
}
|
||||||
err := storage.CreateOpenIDConnectSession(ctx, "authcode.signature-doesnt-matter", request)
|
err := storage.CreateOpenIDConnectSession(ctx, "authcode.signature-doesnt-matter", request)
|
||||||
require.EqualError(t, err, "requester's session must be of type openid.DefaultSession")
|
require.EqualError(t, err, "requester's session must be of type openid.DefaultSession")
|
||||||
@ -186,7 +190,7 @@ func TestCreateWithWrongRequesterDataTypes(t *testing.T) {
|
|||||||
Client: nil,
|
Client: nil,
|
||||||
}
|
}
|
||||||
err = storage.CreateOpenIDConnectSession(ctx, "authcode.signature-doesnt-matter", request)
|
err = storage.CreateOpenIDConnectSession(ctx, "authcode.signature-doesnt-matter", request)
|
||||||
require.EqualError(t, err, "requester's client must be of type fosite.DefaultOpenIDConnectClient")
|
require.EqualError(t, err, "requester's client must be of type clientregistry.Client")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAuthcodeHasNoDot(t *testing.T) {
|
func TestAuthcodeHasNoDot(t *testing.T) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package pkce
|
package pkce
|
||||||
@ -17,6 +17,7 @@ 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/fositestorage"
|
"go.pinniped.dev/internal/fositestorage"
|
||||||
|
"go.pinniped.dev/internal/oidc/clientregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -94,7 +95,7 @@ func (a *pkceStorage) getSession(ctx context.Context, signature string) (*sessio
|
|||||||
func newValidEmptyPKCESession() *session {
|
func newValidEmptyPKCESession() *session {
|
||||||
return &session{
|
return &session{
|
||||||
Request: &fosite.Request{
|
Request: &fosite.Request{
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
Session: &openid.DefaultSession{},
|
Session: &openid.DefaultSession{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package pkce
|
package pkce
|
||||||
@ -21,6 +21,8 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
coretesting "k8s.io/client-go/testing"
|
coretesting "k8s.io/client-go/testing"
|
||||||
|
|
||||||
|
"go.pinniped.dev/internal/oidc/clientregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const namespace = "test-ns"
|
const namespace = "test-ns"
|
||||||
@ -63,23 +65,25 @@ func TestPKCEStorage(t *testing.T) {
|
|||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
ID: "abcd-1",
|
ID: "abcd-1",
|
||||||
RequestedAt: time.Time{},
|
RequestedAt: time.Time{},
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{
|
Client: &clientregistry.Client{
|
||||||
DefaultClient: &fosite.DefaultClient{
|
DefaultOpenIDConnectClient: fosite.DefaultOpenIDConnectClient{
|
||||||
ID: "pinny",
|
DefaultClient: &fosite.DefaultClient{
|
||||||
Secret: nil,
|
ID: "pinny",
|
||||||
RedirectURIs: nil,
|
Secret: nil,
|
||||||
GrantTypes: nil,
|
RedirectURIs: nil,
|
||||||
ResponseTypes: nil,
|
GrantTypes: nil,
|
||||||
Scopes: nil,
|
ResponseTypes: nil,
|
||||||
Audience: nil,
|
Scopes: nil,
|
||||||
Public: true,
|
Audience: nil,
|
||||||
|
Public: true,
|
||||||
|
},
|
||||||
|
JSONWebKeysURI: "where",
|
||||||
|
JSONWebKeys: nil,
|
||||||
|
TokenEndpointAuthMethod: "something",
|
||||||
|
RequestURIs: nil,
|
||||||
|
RequestObjectSigningAlgorithm: "",
|
||||||
|
TokenEndpointAuthSigningAlgorithm: "",
|
||||||
},
|
},
|
||||||
JSONWebKeysURI: "where",
|
|
||||||
JSONWebKeys: nil,
|
|
||||||
TokenEndpointAuthMethod: "something",
|
|
||||||
RequestURIs: nil,
|
|
||||||
RequestObjectSigningAlgorithm: "",
|
|
||||||
TokenEndpointAuthSigningAlgorithm: "",
|
|
||||||
},
|
},
|
||||||
RequestedScope: nil,
|
RequestedScope: nil,
|
||||||
GrantedScope: nil,
|
GrantedScope: nil,
|
||||||
@ -183,7 +187,7 @@ func TestCreateWithWrongRequesterDataTypes(t *testing.T) {
|
|||||||
|
|
||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
Session: nil,
|
Session: nil,
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
}
|
}
|
||||||
err := storage.CreatePKCERequestSession(ctx, "signature-doesnt-matter", request)
|
err := storage.CreatePKCERequestSession(ctx, "signature-doesnt-matter", request)
|
||||||
require.EqualError(t, err, "requester's session must be of type openid.DefaultSession")
|
require.EqualError(t, err, "requester's session must be of type openid.DefaultSession")
|
||||||
@ -193,7 +197,7 @@ func TestCreateWithWrongRequesterDataTypes(t *testing.T) {
|
|||||||
Client: nil,
|
Client: nil,
|
||||||
}
|
}
|
||||||
err = storage.CreatePKCERequestSession(ctx, "signature-doesnt-matter", request)
|
err = storage.CreatePKCERequestSession(ctx, "signature-doesnt-matter", request)
|
||||||
require.EqualError(t, err, "requester's client must be of type fosite.DefaultOpenIDConnectClient")
|
require.EqualError(t, err, "requester's client must be of type clientregistry.Client")
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeTestSubject() (context.Context, *fake.Clientset, corev1client.SecretInterface, pkce.PKCERequestStorage) {
|
func makeTestSubject() (context.Context, *fake.Clientset, corev1client.SecretInterface, pkce.PKCERequestStorage) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package refreshtoken
|
package refreshtoken
|
||||||
@ -17,6 +17,7 @@ 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/fositestorage"
|
"go.pinniped.dev/internal/fositestorage"
|
||||||
|
"go.pinniped.dev/internal/oidc/clientregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -108,7 +109,7 @@ func (a *refreshTokenStorage) getSession(ctx context.Context, signature string)
|
|||||||
func newValidEmptyRefreshTokenSession() *session {
|
func newValidEmptyRefreshTokenSession() *session {
|
||||||
return &session{
|
return &session{
|
||||||
Request: &fosite.Request{
|
Request: &fosite.Request{
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
Session: &openid.DefaultSession{},
|
Session: &openid.DefaultSession{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package refreshtoken
|
package refreshtoken
|
||||||
@ -20,6 +20,8 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
coretesting "k8s.io/client-go/testing"
|
coretesting "k8s.io/client-go/testing"
|
||||||
|
|
||||||
|
"go.pinniped.dev/internal/oidc/clientregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const namespace = "test-ns"
|
const namespace = "test-ns"
|
||||||
@ -62,23 +64,25 @@ func TestRefreshTokenStorage(t *testing.T) {
|
|||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
ID: "abcd-1",
|
ID: "abcd-1",
|
||||||
RequestedAt: time.Time{},
|
RequestedAt: time.Time{},
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{
|
Client: &clientregistry.Client{
|
||||||
DefaultClient: &fosite.DefaultClient{
|
DefaultOpenIDConnectClient: fosite.DefaultOpenIDConnectClient{
|
||||||
ID: "pinny",
|
DefaultClient: &fosite.DefaultClient{
|
||||||
Secret: nil,
|
ID: "pinny",
|
||||||
RedirectURIs: nil,
|
Secret: nil,
|
||||||
GrantTypes: nil,
|
RedirectURIs: nil,
|
||||||
ResponseTypes: nil,
|
GrantTypes: nil,
|
||||||
Scopes: nil,
|
ResponseTypes: nil,
|
||||||
Audience: nil,
|
Scopes: nil,
|
||||||
Public: true,
|
Audience: nil,
|
||||||
|
Public: true,
|
||||||
|
},
|
||||||
|
JSONWebKeysURI: "where",
|
||||||
|
JSONWebKeys: nil,
|
||||||
|
TokenEndpointAuthMethod: "something",
|
||||||
|
RequestURIs: nil,
|
||||||
|
RequestObjectSigningAlgorithm: "",
|
||||||
|
TokenEndpointAuthSigningAlgorithm: "",
|
||||||
},
|
},
|
||||||
JSONWebKeysURI: "where",
|
|
||||||
JSONWebKeys: nil,
|
|
||||||
TokenEndpointAuthMethod: "something",
|
|
||||||
RequestURIs: nil,
|
|
||||||
RequestObjectSigningAlgorithm: "",
|
|
||||||
TokenEndpointAuthSigningAlgorithm: "",
|
|
||||||
},
|
},
|
||||||
RequestedScope: nil,
|
RequestedScope: nil,
|
||||||
GrantedScope: nil,
|
GrantedScope: nil,
|
||||||
@ -137,13 +141,15 @@ func TestRefreshTokenStorageRevocation(t *testing.T) {
|
|||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
ID: "abcd-1",
|
ID: "abcd-1",
|
||||||
RequestedAt: time.Time{},
|
RequestedAt: time.Time{},
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{
|
Client: &clientregistry.Client{
|
||||||
DefaultClient: &fosite.DefaultClient{
|
DefaultOpenIDConnectClient: fosite.DefaultOpenIDConnectClient{
|
||||||
ID: "pinny",
|
DefaultClient: &fosite.DefaultClient{
|
||||||
Public: true,
|
ID: "pinny",
|
||||||
|
Public: true,
|
||||||
|
},
|
||||||
|
JSONWebKeysURI: "where",
|
||||||
|
TokenEndpointAuthMethod: "something",
|
||||||
},
|
},
|
||||||
JSONWebKeysURI: "where",
|
|
||||||
TokenEndpointAuthMethod: "something",
|
|
||||||
},
|
},
|
||||||
Form: url.Values{"key": []string{"val"}},
|
Form: url.Values{"key": []string{"val"}},
|
||||||
Session: &openid.DefaultSession{
|
Session: &openid.DefaultSession{
|
||||||
@ -237,7 +243,7 @@ func TestCreateWithWrongRequesterDataTypes(t *testing.T) {
|
|||||||
|
|
||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
Session: nil,
|
Session: nil,
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
}
|
}
|
||||||
err := storage.CreateRefreshTokenSession(ctx, "signature-doesnt-matter", request)
|
err := storage.CreateRefreshTokenSession(ctx, "signature-doesnt-matter", request)
|
||||||
require.EqualError(t, err, "requester's session must be of type openid.DefaultSession")
|
require.EqualError(t, err, "requester's session must be of type openid.DefaultSession")
|
||||||
@ -247,7 +253,7 @@ func TestCreateWithWrongRequesterDataTypes(t *testing.T) {
|
|||||||
Client: nil,
|
Client: nil,
|
||||||
}
|
}
|
||||||
err = storage.CreateRefreshTokenSession(ctx, "signature-doesnt-matter", request)
|
err = storage.CreateRefreshTokenSession(ctx, "signature-doesnt-matter", request)
|
||||||
require.EqualError(t, err, "requester's client must be of type fosite.DefaultOpenIDConnectClient")
|
require.EqualError(t, err, "requester's client must be of type clientregistry.Client")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateWithoutRequesterID(t *testing.T) {
|
func TestCreateWithoutRequesterID(t *testing.T) {
|
||||||
@ -256,7 +262,7 @@ func TestCreateWithoutRequesterID(t *testing.T) {
|
|||||||
request := &fosite.Request{
|
request := &fosite.Request{
|
||||||
ID: "", // empty ID
|
ID: "", // empty ID
|
||||||
Session: &openid.DefaultSession{},
|
Session: &openid.DefaultSession{},
|
||||||
Client: &fosite.DefaultOpenIDConnectClient{},
|
Client: &clientregistry.Client{},
|
||||||
}
|
}
|
||||||
err := storage.CreateRefreshTokenSession(ctx, "signature-doesnt-matter", request)
|
err := storage.CreateRefreshTokenSession(ctx, "signature-doesnt-matter", request)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
94
internal/oidc/clientregistry/clientregistry.go
Normal file
94
internal/oidc/clientregistry/clientregistry.go
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
// Package clientregistry defines Pinniped's OAuth2/OIDC clients.
|
||||||
|
package clientregistry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/coreos/go-oidc/v3/oidc"
|
||||||
|
"github.com/ory/fosite"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Client represents a Pinniped OAuth/OIDC client.
|
||||||
|
type Client struct {
|
||||||
|
fosite.DefaultOpenIDConnectClient
|
||||||
|
}
|
||||||
|
|
||||||
|
// It implements both the base and OIDC client interfaces of Fosite.
|
||||||
|
var (
|
||||||
|
_ fosite.Client = (*Client)(nil)
|
||||||
|
_ fosite.OpenIDConnectClient = (*Client)(nil)
|
||||||
|
)
|
||||||
|
|
||||||
|
// StaticClientManager is a fosite.ClientManager with statically-defined clients.
|
||||||
|
type StaticClientManager struct{}
|
||||||
|
|
||||||
|
var _ fosite.ClientManager = (*StaticClientManager)(nil)
|
||||||
|
|
||||||
|
// GetClient returns a static client specified by the given ID.
|
||||||
|
//
|
||||||
|
// It returns a fosite.ErrNotFound if an unknown client is specified.
|
||||||
|
func (StaticClientManager) GetClient(_ context.Context, id string) (fosite.Client, error) {
|
||||||
|
switch id {
|
||||||
|
case "pinniped-cli":
|
||||||
|
return PinnipedCLI(), nil
|
||||||
|
default:
|
||||||
|
return nil, fosite.ErrNotFound.WithDescription("no such client")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientAssertionJWTValid returns an error if the JTI is
|
||||||
|
// known or the DB check failed and nil if the JTI is not known.
|
||||||
|
//
|
||||||
|
// This functionality is not supported by the StaticClientManager.
|
||||||
|
func (StaticClientManager) ClientAssertionJWTValid(ctx context.Context, jti string) error {
|
||||||
|
return fmt.Errorf("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetClientAssertionJWT marks a JTI as known for the given
|
||||||
|
// expiry time. Before inserting the new JTI, it will clean
|
||||||
|
// up any existing JTIs that have expired as those tokens can
|
||||||
|
// not be replayed due to the expiry.
|
||||||
|
//
|
||||||
|
// This functionality is not supported by the StaticClientManager.
|
||||||
|
func (StaticClientManager) SetClientAssertionJWT(ctx context.Context, jti string, exp time.Time) error {
|
||||||
|
return fmt.Errorf("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// PinnipedCLI returns the static Client corresponding to the Pinniped CLI.
|
||||||
|
func PinnipedCLI() *Client {
|
||||||
|
return &Client{
|
||||||
|
DefaultOpenIDConnectClient: fosite.DefaultOpenIDConnectClient{
|
||||||
|
DefaultClient: &fosite.DefaultClient{
|
||||||
|
ID: "pinniped-cli",
|
||||||
|
Secret: nil,
|
||||||
|
RedirectURIs: []string{"http://127.0.0.1/callback"},
|
||||||
|
GrantTypes: fosite.Arguments{
|
||||||
|
"authorization_code",
|
||||||
|
"refresh_token",
|
||||||
|
"urn:ietf:params:oauth:grant-type:token-exchange",
|
||||||
|
},
|
||||||
|
ResponseTypes: []string{"code"},
|
||||||
|
Scopes: fosite.Arguments{
|
||||||
|
oidc.ScopeOpenID,
|
||||||
|
oidc.ScopeOfflineAccess,
|
||||||
|
"profile",
|
||||||
|
"email",
|
||||||
|
"pinniped:request-audience",
|
||||||
|
},
|
||||||
|
Audience: nil,
|
||||||
|
Public: true,
|
||||||
|
},
|
||||||
|
RequestURIs: nil,
|
||||||
|
JSONWebKeys: nil,
|
||||||
|
JSONWebKeysURI: "",
|
||||||
|
RequestObjectSigningAlgorithm: "",
|
||||||
|
TokenEndpointAuthSigningAlgorithm: oidc.RS256,
|
||||||
|
TokenEndpointAuthMethod: "none",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
95
internal/oidc/clientregistry/clientregistry_test.go
Normal file
95
internal/oidc/clientregistry/clientregistry_test.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package clientregistry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/coreos/go-oidc/v3/oidc"
|
||||||
|
"github.com/ory/fosite"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStaticRegistry(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
t.Run("unimplemented methods", func(t *testing.T) {
|
||||||
|
registry := StaticClientManager{}
|
||||||
|
require.EqualError(t, registry.ClientAssertionJWTValid(ctx, "some-token-id"), "not implemented")
|
||||||
|
require.EqualError(t, registry.SetClientAssertionJWT(ctx, "some-token-id", time.Now()), "not implemented")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("not found", func(t *testing.T) {
|
||||||
|
registry := StaticClientManager{}
|
||||||
|
got, err := registry.GetClient(ctx, "does-not-exist")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Nil(t, got)
|
||||||
|
rfcErr := fosite.ErrorToRFC6749Error(err)
|
||||||
|
require.NotNil(t, rfcErr)
|
||||||
|
require.Equal(t, rfcErr.CodeField, 404)
|
||||||
|
require.Equal(t, rfcErr.GetDescription(), "no such client")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("pinniped CLI", func(t *testing.T) {
|
||||||
|
registry := StaticClientManager{}
|
||||||
|
got, err := registry.GetClient(ctx, "pinniped-cli")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, got)
|
||||||
|
require.IsType(t, &Client{}, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPinnipedCLI(t *testing.T) {
|
||||||
|
c := PinnipedCLI()
|
||||||
|
require.Equal(t, "pinniped-cli", c.GetID())
|
||||||
|
require.Nil(t, c.GetHashedSecret())
|
||||||
|
require.Equal(t, []string{"http://127.0.0.1/callback"}, c.GetRedirectURIs())
|
||||||
|
require.Equal(t, fosite.Arguments{"authorization_code", "refresh_token", "urn:ietf:params:oauth:grant-type:token-exchange"}, c.GetGrantTypes())
|
||||||
|
require.Equal(t, fosite.Arguments{"code"}, c.GetResponseTypes())
|
||||||
|
require.Equal(t, fosite.Arguments{oidc.ScopeOpenID, oidc.ScopeOfflineAccess, "profile", "email", "pinniped:request-audience"}, c.GetScopes())
|
||||||
|
require.True(t, c.IsPublic())
|
||||||
|
require.Nil(t, c.GetAudience())
|
||||||
|
require.Nil(t, c.GetRequestURIs())
|
||||||
|
require.Nil(t, c.GetJSONWebKeys())
|
||||||
|
require.Equal(t, "", c.GetJSONWebKeysURI())
|
||||||
|
require.Equal(t, "", c.GetRequestObjectSigningAlgorithm())
|
||||||
|
require.Equal(t, "none", c.GetTokenEndpointAuthMethod())
|
||||||
|
require.Equal(t, "RS256", c.GetTokenEndpointAuthSigningAlgorithm())
|
||||||
|
|
||||||
|
marshaled, err := json.Marshal(c)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.JSONEq(t, `
|
||||||
|
{
|
||||||
|
"id": "pinniped-cli",
|
||||||
|
"redirect_uris": [
|
||||||
|
"http://127.0.0.1/callback"
|
||||||
|
],
|
||||||
|
"grant_types": [
|
||||||
|
"authorization_code",
|
||||||
|
"refresh_token",
|
||||||
|
"urn:ietf:params:oauth:grant-type:token-exchange"
|
||||||
|
],
|
||||||
|
"response_types": [
|
||||||
|
"code"
|
||||||
|
],
|
||||||
|
"scopes": [
|
||||||
|
"openid",
|
||||||
|
"offline_access",
|
||||||
|
"profile",
|
||||||
|
"email",
|
||||||
|
"pinniped:request-audience"
|
||||||
|
],
|
||||||
|
"audience": null,
|
||||||
|
"public": true,
|
||||||
|
"jwks_uri": "",
|
||||||
|
"jwks": null,
|
||||||
|
"token_endpoint_auth_method": "none",
|
||||||
|
"request_uris": null,
|
||||||
|
"request_object_signing_alg": "",
|
||||||
|
"token_endpoint_auth_signing_alg": "RS256"
|
||||||
|
}`, string(marshaled))
|
||||||
|
}
|
@ -13,18 +13,17 @@ import (
|
|||||||
fositepkce "github.com/ory/fosite/handler/pkce"
|
fositepkce "github.com/ory/fosite/handler/pkce"
|
||||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
|
|
||||||
"go.pinniped.dev/internal/constable"
|
|
||||||
"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"
|
||||||
)
|
)
|
||||||
|
|
||||||
const errKubeStorageNotImplemented = constable.Error("KubeStorage does not implement this method. It should not have been called.")
|
|
||||||
|
|
||||||
type KubeStorage struct {
|
type KubeStorage struct {
|
||||||
|
clientManager fosite.ClientManager
|
||||||
authorizationCodeStorage oauth2.AuthorizeCodeStorage
|
authorizationCodeStorage oauth2.AuthorizeCodeStorage
|
||||||
pkceStorage fositepkce.PKCERequestStorage
|
pkceStorage fositepkce.PKCERequestStorage
|
||||||
oidcStorage openid.OpenIDConnectRequestStorage
|
oidcStorage openid.OpenIDConnectRequestStorage
|
||||||
@ -37,6 +36,7 @@ var _ fositestoragei.AllFositeStorage = &KubeStorage{}
|
|||||||
func NewKubeStorage(secrets corev1client.SecretInterface, timeoutsConfiguration TimeoutsConfiguration) *KubeStorage {
|
func NewKubeStorage(secrets corev1client.SecretInterface, timeoutsConfiguration TimeoutsConfiguration) *KubeStorage {
|
||||||
nowFunc := time.Now
|
nowFunc := time.Now
|
||||||
return &KubeStorage{
|
return &KubeStorage{
|
||||||
|
clientManager: &clientregistry.StaticClientManager{},
|
||||||
authorizationCodeStorage: authorizationcode.New(secrets, nowFunc, timeoutsConfiguration.AuthorizationCodeSessionStorageLifetime),
|
authorizationCodeStorage: authorizationcode.New(secrets, nowFunc, timeoutsConfiguration.AuthorizationCodeSessionStorageLifetime),
|
||||||
pkceStorage: pkce.New(secrets, nowFunc, timeoutsConfiguration.PKCESessionStorageLifetime),
|
pkceStorage: pkce.New(secrets, nowFunc, timeoutsConfiguration.PKCESessionStorageLifetime),
|
||||||
oidcStorage: openidconnect.New(secrets, nowFunc, timeoutsConfiguration.OIDCSessionStorageLifetime),
|
oidcStorage: openidconnect.New(secrets, nowFunc, timeoutsConfiguration.OIDCSessionStorageLifetime),
|
||||||
@ -183,26 +183,15 @@ func (k KubeStorage) RevokeRefreshToken(ctx context.Context, requestID string) e
|
|||||||
//
|
//
|
||||||
// OAuth client definitions:
|
// OAuth client definitions:
|
||||||
//
|
//
|
||||||
// For the time being, we only allow a single pre-defined client, so we do not need to interact with any underlying
|
|
||||||
// storage mechanism to fetch them.
|
|
||||||
//
|
|
||||||
|
|
||||||
func (KubeStorage) GetClient(_ context.Context, id string) (fosite.Client, error) {
|
func (k KubeStorage) GetClient(ctx context.Context, id string) (fosite.Client, error) {
|
||||||
client := PinnipedCLIOIDCClient()
|
return k.clientManager.GetClient(ctx, id)
|
||||||
if client.ID == id {
|
|
||||||
return client, nil
|
|
||||||
}
|
|
||||||
return nil, fosite.ErrNotFound
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
func (k KubeStorage) ClientAssertionJWTValid(ctx context.Context, jti string) error {
|
||||||
// Unused interface methods.
|
return k.clientManager.ClientAssertionJWTValid(ctx, jti)
|
||||||
//
|
|
||||||
|
|
||||||
func (KubeStorage) ClientAssertionJWTValid(_ context.Context, _ string) error {
|
|
||||||
return errKubeStorageNotImplemented
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (KubeStorage) SetClientAssertionJWT(_ context.Context, _ string, _ time.Time) error {
|
func (k KubeStorage) SetClientAssertionJWT(ctx context.Context, jti string, exp time.Time) error {
|
||||||
return errKubeStorageNotImplemented
|
return k.clientManager.SetClientAssertionJWT(ctx, jti, exp)
|
||||||
}
|
}
|
||||||
|
@ -5,17 +5,19 @@ package oidc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ory/fosite"
|
"github.com/ory/fosite"
|
||||||
|
|
||||||
"go.pinniped.dev/internal/constable"
|
"go.pinniped.dev/internal/constable"
|
||||||
"go.pinniped.dev/internal/fositestoragei"
|
"go.pinniped.dev/internal/fositestoragei"
|
||||||
|
"go.pinniped.dev/internal/oidc/clientregistry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const errNullStorageNotImplemented = constable.Error("NullStorage does not implement this method. It should not have been called.")
|
const errNullStorageNotImplemented = constable.Error("NullStorage does not implement this method. It should not have been called.")
|
||||||
|
|
||||||
type NullStorage struct{}
|
type NullStorage struct {
|
||||||
|
clientregistry.StaticClientManager
|
||||||
|
}
|
||||||
|
|
||||||
var _ fositestoragei.AllFositeStorage = &NullStorage{}
|
var _ fositestoragei.AllFositeStorage = &NullStorage{}
|
||||||
|
|
||||||
@ -86,19 +88,3 @@ func (NullStorage) GetAuthorizeCodeSession(_ context.Context, _ string, _ fosite
|
|||||||
func (NullStorage) InvalidateAuthorizeCodeSession(_ context.Context, _ string) (err error) {
|
func (NullStorage) InvalidateAuthorizeCodeSession(_ context.Context, _ string) (err error) {
|
||||||
return errNullStorageNotImplemented
|
return errNullStorageNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
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 errNullStorageNotImplemented
|
|
||||||
}
|
|
||||||
|
|
||||||
func (NullStorage) SetClientAssertionJWT(_ context.Context, _ string, _ time.Time) error {
|
|
||||||
return errNullStorageNotImplemented
|
|
||||||
}
|
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
// 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", "refresh_token", "urn:ietf:params:oauth:grant-type:token-exchange"},
|
|
||||||
Scopes: []string{"openid", "offline_access", "profile", "email", "pinniped:request-audience"},
|
|
||||||
},
|
|
||||||
TokenEndpointAuthMethod: "none",
|
|
||||||
},
|
|
||||||
client,
|
|
||||||
)
|
|
||||||
}
|
|
@ -98,20 +98,6 @@ type UpstreamStateParamData struct {
|
|||||||
FormatVersion string `json:"v"`
|
FormatVersion string `json:"v"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func PinnipedCLIOIDCClient() *fosite.DefaultOpenIDConnectClient {
|
|
||||||
return &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", "refresh_token", "urn:ietf:params:oauth:grant-type:token-exchange"},
|
|
||||||
Scopes: []string{coreosoidc.ScopeOpenID, coreosoidc.ScopeOfflineAccess, "profile", "email", "pinniped:request-audience"},
|
|
||||||
},
|
|
||||||
TokenEndpointAuthMethod: "none",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type TimeoutsConfiguration struct {
|
type TimeoutsConfiguration struct {
|
||||||
// The length of time that our state param that we encrypt and pass to the upstream OIDC IDP should be considered
|
// 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
|
// valid. If a state param generated by the authorize endpoint is sent to the callback endpoint after this much
|
||||||
|
Loading…
Reference in New Issue
Block a user