Extract Supervisor IDP discovery endpoint types into apis package
This commit is contained in:
parent
964d16110e
commit
96474b3d99
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
// SupervisorOIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
|
||||||
|
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
|
||||||
|
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
|
||||||
|
type SupervisorOIDCDiscoveryResponse struct {
|
||||||
|
SupervisorDiscovery SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorOIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
|
||||||
|
type SupervisorOIDCDiscoveryResponseIDPEndpoint struct {
|
||||||
|
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorIDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
|
||||||
|
type SupervisorIDPDiscoveryResponse struct {
|
||||||
|
PinnipedIDPs []SupervisorPinnipedIDP `json:"pinniped_identity_providers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorPinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
|
||||||
|
// identity provider discovery endpoint.
|
||||||
|
type SupervisorPinnipedIDP struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Flows []string `json:"flows,omitempty"`
|
||||||
|
}
|
@ -32,6 +32,7 @@ import (
|
|||||||
|
|
||||||
conciergev1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
|
conciergev1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1"
|
||||||
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
configv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||||
|
idpdiscoveryv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
|
||||||
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
|
conciergeclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
|
||||||
"go.pinniped.dev/internal/groupsuffix"
|
"go.pinniped.dev/internal/groupsuffix"
|
||||||
)
|
)
|
||||||
@ -98,24 +99,6 @@ type getKubeconfigParams struct {
|
|||||||
credentialCachePathSet bool
|
credentialCachePathSet bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type supervisorOIDCDiscoveryResponseWithV1Alpha1 struct {
|
|
||||||
SupervisorDiscovery SupervisorDiscoveryResponseV1Alpha1 `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SupervisorDiscoveryResponseV1Alpha1 struct {
|
|
||||||
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type supervisorIDPsDiscoveryResponseV1Alpha1 struct {
|
|
||||||
PinnipedIDPs []pinnipedIDPResponse `json:"pinniped_identity_providers"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type pinnipedIDPResponse struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
Flows []string `json:"flows,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
|
func kubeconfigCommand(deps kubeconfigDeps) *cobra.Command {
|
||||||
var (
|
var (
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
@ -818,7 +801,7 @@ func discoverIDPsDiscoveryEndpointURL(ctx context.Context, issuer string, httpCl
|
|||||||
return "", fmt.Errorf("while fetching OIDC discovery data from issuer: %w", err)
|
return "", fmt.Errorf("while fetching OIDC discovery data from issuer: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var body supervisorOIDCDiscoveryResponseWithV1Alpha1
|
var body idpdiscoveryv1alpha1.SupervisorOIDCDiscoveryResponse
|
||||||
err = discoveredProvider.Claims(&body)
|
err = discoveredProvider.Claims(&body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("while fetching OIDC discovery data from issuer: %w", err)
|
return "", fmt.Errorf("while fetching OIDC discovery data from issuer: %w", err)
|
||||||
@ -827,7 +810,7 @@ func discoverIDPsDiscoveryEndpointURL(ctx context.Context, issuer string, httpCl
|
|||||||
return body.SupervisorDiscovery.PinnipedIDPsEndpoint, nil
|
return body.SupervisorDiscovery.PinnipedIDPsEndpoint, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDPsEndpoint string, httpClient *http.Client) ([]pinnipedIDPResponse, error) {
|
func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDPsEndpoint string, httpClient *http.Client) ([]idpdiscoveryv1alpha1.SupervisorPinnipedIDP, error) {
|
||||||
request, err := http.NewRequestWithContext(ctx, http.MethodGet, pinnipedIDPsEndpoint, nil)
|
request, err := http.NewRequestWithContext(ctx, http.MethodGet, pinnipedIDPsEndpoint, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("while forming request to IDP discovery URL: %w", err)
|
return nil, fmt.Errorf("while forming request to IDP discovery URL: %w", err)
|
||||||
@ -849,7 +832,7 @@ func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDP
|
|||||||
return nil, fmt.Errorf("unable to fetch IDP discovery data from issuer: could not read response body: %w", err)
|
return nil, fmt.Errorf("unable to fetch IDP discovery data from issuer: could not read response body: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var body supervisorIDPsDiscoveryResponseV1Alpha1
|
var body idpdiscoveryv1alpha1.SupervisorIDPDiscoveryResponse
|
||||||
err = json.Unmarshal(rawBody, &body)
|
err = json.Unmarshal(rawBody, &body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to fetch IDP discovery data from issuer: could not parse response JSON: %w", err)
|
return nil, fmt.Errorf("unable to fetch IDP discovery data from issuer: could not parse response JSON: %w", err)
|
||||||
@ -858,7 +841,7 @@ func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDP
|
|||||||
return body.PinnipedIDPs, nil
|
return body.PinnipedIDPs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func selectUpstreamIDPNameAndType(pinnipedIDPs []pinnipedIDPResponse, specifiedIDPName, specifiedIDPType string) (string, string, []string, error) {
|
func selectUpstreamIDPNameAndType(pinnipedIDPs []idpdiscoveryv1alpha1.SupervisorPinnipedIDP, specifiedIDPName, specifiedIDPType string) (string, string, []string, error) {
|
||||||
pinnipedIDPsString, _ := json.Marshal(pinnipedIDPs)
|
pinnipedIDPsString, _ := json.Marshal(pinnipedIDPs)
|
||||||
var discoveredFlows []string
|
var discoveredFlows []string
|
||||||
switch {
|
switch {
|
||||||
|
29
generated/1.17/apis/supervisor/idpdiscovery/v1alpha1/types_supervisor_idp_discovery.go
generated
Normal file
29
generated/1.17/apis/supervisor/idpdiscovery/v1alpha1/types_supervisor_idp_discovery.go
generated
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
// SupervisorOIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
|
||||||
|
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
|
||||||
|
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
|
||||||
|
type SupervisorOIDCDiscoveryResponse struct {
|
||||||
|
SupervisorDiscovery SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorOIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
|
||||||
|
type SupervisorOIDCDiscoveryResponseIDPEndpoint struct {
|
||||||
|
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorIDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
|
||||||
|
type SupervisorIDPDiscoveryResponse struct {
|
||||||
|
PinnipedIDPs []SupervisorPinnipedIDP `json:"pinniped_identity_providers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorPinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
|
||||||
|
// identity provider discovery endpoint.
|
||||||
|
type SupervisorPinnipedIDP struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Flows []string `json:"flows,omitempty"`
|
||||||
|
}
|
29
generated/1.18/apis/supervisor/idpdiscovery/v1alpha1/types_supervisor_idp_discovery.go
generated
Normal file
29
generated/1.18/apis/supervisor/idpdiscovery/v1alpha1/types_supervisor_idp_discovery.go
generated
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
// SupervisorOIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
|
||||||
|
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
|
||||||
|
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
|
||||||
|
type SupervisorOIDCDiscoveryResponse struct {
|
||||||
|
SupervisorDiscovery SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorOIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
|
||||||
|
type SupervisorOIDCDiscoveryResponseIDPEndpoint struct {
|
||||||
|
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorIDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
|
||||||
|
type SupervisorIDPDiscoveryResponse struct {
|
||||||
|
PinnipedIDPs []SupervisorPinnipedIDP `json:"pinniped_identity_providers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorPinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
|
||||||
|
// identity provider discovery endpoint.
|
||||||
|
type SupervisorPinnipedIDP struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Flows []string `json:"flows,omitempty"`
|
||||||
|
}
|
29
generated/1.19/apis/supervisor/idpdiscovery/v1alpha1/types_supervisor_idp_discovery.go
generated
Normal file
29
generated/1.19/apis/supervisor/idpdiscovery/v1alpha1/types_supervisor_idp_discovery.go
generated
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
// SupervisorOIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
|
||||||
|
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
|
||||||
|
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
|
||||||
|
type SupervisorOIDCDiscoveryResponse struct {
|
||||||
|
SupervisorDiscovery SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorOIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
|
||||||
|
type SupervisorOIDCDiscoveryResponseIDPEndpoint struct {
|
||||||
|
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorIDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
|
||||||
|
type SupervisorIDPDiscoveryResponse struct {
|
||||||
|
PinnipedIDPs []SupervisorPinnipedIDP `json:"pinniped_identity_providers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorPinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
|
||||||
|
// identity provider discovery endpoint.
|
||||||
|
type SupervisorPinnipedIDP struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Flows []string `json:"flows,omitempty"`
|
||||||
|
}
|
29
generated/1.20/apis/supervisor/idpdiscovery/v1alpha1/types_supervisor_idp_discovery.go
generated
Normal file
29
generated/1.20/apis/supervisor/idpdiscovery/v1alpha1/types_supervisor_idp_discovery.go
generated
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
// SupervisorOIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
|
||||||
|
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
|
||||||
|
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
|
||||||
|
type SupervisorOIDCDiscoveryResponse struct {
|
||||||
|
SupervisorDiscovery SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorOIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
|
||||||
|
type SupervisorOIDCDiscoveryResponseIDPEndpoint struct {
|
||||||
|
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorIDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
|
||||||
|
type SupervisorIDPDiscoveryResponse struct {
|
||||||
|
PinnipedIDPs []SupervisorPinnipedIDP `json:"pinniped_identity_providers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorPinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
|
||||||
|
// identity provider discovery endpoint.
|
||||||
|
type SupervisorPinnipedIDP struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Flows []string `json:"flows,omitempty"`
|
||||||
|
}
|
29
generated/latest/apis/supervisor/idpdiscovery/v1alpha1/types_supervisor_idp_discovery.go
generated
Normal file
29
generated/latest/apis/supervisor/idpdiscovery/v1alpha1/types_supervisor_idp_discovery.go
generated
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
// SupervisorOIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
|
||||||
|
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
|
||||||
|
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
|
||||||
|
type SupervisorOIDCDiscoveryResponse struct {
|
||||||
|
SupervisorDiscovery SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorOIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
|
||||||
|
type SupervisorOIDCDiscoveryResponseIDPEndpoint struct {
|
||||||
|
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorIDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
|
||||||
|
type SupervisorIDPDiscoveryResponse struct {
|
||||||
|
PinnipedIDPs []SupervisorPinnipedIDP `json:"pinniped_identity_providers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SupervisorPinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
|
||||||
|
// identity provider discovery endpoint.
|
||||||
|
type SupervisorPinnipedIDP struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Flows []string `json:"flows,omitempty"`
|
||||||
|
}
|
@ -9,6 +9,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
|
||||||
"go.pinniped.dev/internal/oidc"
|
"go.pinniped.dev/internal/oidc"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,20 +42,11 @@ type Metadata struct {
|
|||||||
|
|
||||||
// vvv Custom vvv
|
// vvv Custom vvv
|
||||||
|
|
||||||
SupervisorDiscovery SupervisorDiscoveryMetadataV1Alpha1 `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
|
SupervisorDiscovery v1alpha1.SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
|
||||||
|
|
||||||
// ^^^ Custom ^^^
|
// ^^^ Custom ^^^
|
||||||
}
|
}
|
||||||
|
|
||||||
type SupervisorDiscoveryMetadataV1Alpha1 struct {
|
|
||||||
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type IdentityProviderMetadata struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewHandler returns an http.Handler that serves an OIDC discovery endpoint.
|
// NewHandler returns an http.Handler that serves an OIDC discovery endpoint.
|
||||||
func NewHandler(issuerURL string) http.Handler {
|
func NewHandler(issuerURL string) http.Handler {
|
||||||
oidcConfig := Metadata{
|
oidcConfig := Metadata{
|
||||||
@ -62,7 +54,7 @@ func NewHandler(issuerURL string) http.Handler {
|
|||||||
AuthorizationEndpoint: issuerURL + oidc.AuthorizationEndpointPath,
|
AuthorizationEndpoint: issuerURL + oidc.AuthorizationEndpointPath,
|
||||||
TokenEndpoint: issuerURL + oidc.TokenEndpointPath,
|
TokenEndpoint: issuerURL + oidc.TokenEndpointPath,
|
||||||
JWKSURI: issuerURL + oidc.JWKSEndpointPath,
|
JWKSURI: issuerURL + oidc.JWKSEndpointPath,
|
||||||
SupervisorDiscovery: SupervisorDiscoveryMetadataV1Alpha1{PinnipedIDPsEndpoint: issuerURL + oidc.PinnipedIDPsPathV1Alpha1},
|
SupervisorDiscovery: v1alpha1.SupervisorOIDCDiscoveryResponseIDPEndpoint{PinnipedIDPsEndpoint: issuerURL + oidc.PinnipedIDPsPathV1Alpha1},
|
||||||
ResponseTypesSupported: []string{"code"},
|
ResponseTypesSupported: []string{"code"},
|
||||||
ResponseModesSupported: []string{"query", "form_post"},
|
ResponseModesSupported: []string{"query", "form_post"},
|
||||||
SubjectTypesSupported: []string{"public"},
|
SubjectTypesSupported: []string{"public"},
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
package discovery
|
package discovery
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"go.pinniped.dev/internal/here"
|
||||||
"go.pinniped.dev/internal/oidc"
|
"go.pinniped.dev/internal/oidc"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ func TestDiscovery(t *testing.T) {
|
|||||||
|
|
||||||
wantStatus int
|
wantStatus int
|
||||||
wantContentType string
|
wantContentType string
|
||||||
wantBodyJSON interface{}
|
wantBodyJSON string
|
||||||
wantBodyString string
|
wantBodyString string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -34,22 +34,24 @@ func TestDiscovery(t *testing.T) {
|
|||||||
path: "/some/path" + oidc.WellKnownEndpointPath,
|
path: "/some/path" + oidc.WellKnownEndpointPath,
|
||||||
wantStatus: http.StatusOK,
|
wantStatus: http.StatusOK,
|
||||||
wantContentType: "application/json",
|
wantContentType: "application/json",
|
||||||
wantBodyJSON: &Metadata{
|
wantBodyJSON: here.Doc(`
|
||||||
Issuer: "https://some-issuer.com/some/path",
|
{
|
||||||
AuthorizationEndpoint: "https://some-issuer.com/some/path/oauth2/authorize",
|
"issuer": "https://some-issuer.com/some/path",
|
||||||
TokenEndpoint: "https://some-issuer.com/some/path/oauth2/token",
|
"authorization_endpoint": "https://some-issuer.com/some/path/oauth2/authorize",
|
||||||
JWKSURI: "https://some-issuer.com/some/path/jwks.json",
|
"token_endpoint": "https://some-issuer.com/some/path/oauth2/token",
|
||||||
SupervisorDiscovery: SupervisorDiscoveryMetadataV1Alpha1{
|
"jwks_uri": "https://some-issuer.com/some/path/jwks.json",
|
||||||
PinnipedIDPsEndpoint: "https://some-issuer.com/some/path/v1alpha1/pinniped_identity_providers",
|
"response_types_supported": ["code"],
|
||||||
},
|
"response_modes_supported": ["query", "form_post"],
|
||||||
ResponseTypesSupported: []string{"code"},
|
"subject_types_supported": ["public"],
|
||||||
ResponseModesSupported: []string{"query", "form_post"},
|
"id_token_signing_alg_values_supported": ["ES256"],
|
||||||
SubjectTypesSupported: []string{"public"},
|
"token_endpoint_auth_methods_supported": ["client_secret_basic"],
|
||||||
IDTokenSigningAlgValuesSupported: []string{"ES256"},
|
"scopes_supported": ["openid", "offline"],
|
||||||
TokenEndpointAuthMethodsSupported: []string{"client_secret_basic"},
|
"claims_supported": ["groups"],
|
||||||
ScopesSupported: []string{"openid", "offline"},
|
"discovery.supervisor.pinniped.dev/v1alpha1": {
|
||||||
ClaimsSupported: []string{"groups"},
|
"pinniped_identity_providers_endpoint": "https://some-issuer.com/some/path/v1alpha1/pinniped_identity_providers"
|
||||||
},
|
}
|
||||||
|
}
|
||||||
|
`),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "bad method",
|
name: "bad method",
|
||||||
@ -73,10 +75,8 @@ func TestDiscovery(t *testing.T) {
|
|||||||
|
|
||||||
require.Equal(t, test.wantContentType, rsp.Header().Get("Content-Type"))
|
require.Equal(t, test.wantContentType, rsp.Header().Get("Content-Type"))
|
||||||
|
|
||||||
if test.wantBodyJSON != nil {
|
if test.wantBodyJSON != "" {
|
||||||
wantJSON, err := json.Marshal(test.wantBodyJSON)
|
require.JSONEq(t, test.wantBodyJSON, rsp.Body.String())
|
||||||
require.NoError(t, err)
|
|
||||||
require.JSONEq(t, string(wantJSON), rsp.Body.String())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.wantBodyString != "" {
|
if test.wantBodyString != "" {
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
|
"go.pinniped.dev/generated/latest/apis/supervisor/idpdiscovery/v1alpha1"
|
||||||
"go.pinniped.dev/internal/oidc"
|
"go.pinniped.dev/internal/oidc"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,16 +22,6 @@ const (
|
|||||||
flowCLIPassword = "cli_password"
|
flowCLIPassword = "cli_password"
|
||||||
)
|
)
|
||||||
|
|
||||||
type response struct {
|
|
||||||
IDPs []identityProviderResponse `json:"pinniped_identity_providers"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type identityProviderResponse struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
Flows []string `json:"flows"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewHandler returns an http.Handler that serves the upstream IDP discovery endpoint.
|
// NewHandler returns an http.Handler that serves the upstream IDP discovery endpoint.
|
||||||
func NewHandler(upstreamIDPs oidc.UpstreamIdentityProvidersLister) http.Handler {
|
func NewHandler(upstreamIDPs oidc.UpstreamIdentityProvidersLister) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -54,13 +45,13 @@ func NewHandler(upstreamIDPs oidc.UpstreamIdentityProvidersLister) http.Handler
|
|||||||
}
|
}
|
||||||
|
|
||||||
func responseAsJSON(upstreamIDPs oidc.UpstreamIdentityProvidersLister) ([]byte, error) {
|
func responseAsJSON(upstreamIDPs oidc.UpstreamIdentityProvidersLister) ([]byte, error) {
|
||||||
r := response{
|
r := v1alpha1.SupervisorIDPDiscoveryResponse{
|
||||||
IDPs: []identityProviderResponse{},
|
PinnipedIDPs: []v1alpha1.SupervisorPinnipedIDP{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// The cache of IDPs could change at any time, so always recalculate the list.
|
// The cache of IDPs could change at any time, so always recalculate the list.
|
||||||
for _, provider := range upstreamIDPs.GetLDAPIdentityProviders() {
|
for _, provider := range upstreamIDPs.GetLDAPIdentityProviders() {
|
||||||
r.IDPs = append(r.IDPs, identityProviderResponse{
|
r.PinnipedIDPs = append(r.PinnipedIDPs, v1alpha1.SupervisorPinnipedIDP{
|
||||||
Name: provider.GetName(),
|
Name: provider.GetName(),
|
||||||
Type: idpDiscoveryTypeLDAP,
|
Type: idpDiscoveryTypeLDAP,
|
||||||
Flows: []string{flowCLIPassword},
|
Flows: []string{flowCLIPassword},
|
||||||
@ -71,7 +62,7 @@ func responseAsJSON(upstreamIDPs oidc.UpstreamIdentityProvidersLister) ([]byte,
|
|||||||
if provider.AllowsPasswordGrant() {
|
if provider.AllowsPasswordGrant() {
|
||||||
flows = append(flows, flowCLIPassword)
|
flows = append(flows, flowCLIPassword)
|
||||||
}
|
}
|
||||||
r.IDPs = append(r.IDPs, identityProviderResponse{
|
r.PinnipedIDPs = append(r.PinnipedIDPs, v1alpha1.SupervisorPinnipedIDP{
|
||||||
Name: provider.GetName(),
|
Name: provider.GetName(),
|
||||||
Type: idpDiscoveryTypeOIDC,
|
Type: idpDiscoveryTypeOIDC,
|
||||||
Flows: flows,
|
Flows: flows,
|
||||||
@ -79,8 +70,8 @@ func responseAsJSON(upstreamIDPs oidc.UpstreamIdentityProvidersLister) ([]byte,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Nobody like an API that changes the results unnecessarily. :)
|
// Nobody like an API that changes the results unnecessarily. :)
|
||||||
sort.SliceStable(r.IDPs, func(i, j int) bool {
|
sort.SliceStable(r.PinnipedIDPs, func(i, j int) bool {
|
||||||
return r.IDPs[i].Name < r.IDPs[j].Name
|
return r.PinnipedIDPs[i].Name < r.PinnipedIDPs[j].Name
|
||||||
})
|
})
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
package idpdiscovery
|
package idpdiscovery
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"go.pinniped.dev/internal/here"
|
||||||
"go.pinniped.dev/internal/oidc"
|
"go.pinniped.dev/internal/oidc"
|
||||||
"go.pinniped.dev/internal/oidc/provider"
|
"go.pinniped.dev/internal/oidc/provider"
|
||||||
"go.pinniped.dev/internal/testutil/oidctestutil"
|
"go.pinniped.dev/internal/testutil/oidctestutil"
|
||||||
@ -25,8 +25,8 @@ func TestIDPDiscovery(t *testing.T) {
|
|||||||
|
|
||||||
wantStatus int
|
wantStatus int
|
||||||
wantContentType string
|
wantContentType string
|
||||||
wantFirstResponseBodyJSON interface{}
|
wantFirstResponseBodyJSON string
|
||||||
wantSecondResponseBodyJSON interface{}
|
wantSecondResponseBodyJSON string
|
||||||
wantBodyString string
|
wantBodyString string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -35,24 +35,24 @@ func TestIDPDiscovery(t *testing.T) {
|
|||||||
path: "/some/path" + oidc.WellKnownEndpointPath,
|
path: "/some/path" + oidc.WellKnownEndpointPath,
|
||||||
wantStatus: http.StatusOK,
|
wantStatus: http.StatusOK,
|
||||||
wantContentType: "application/json",
|
wantContentType: "application/json",
|
||||||
wantFirstResponseBodyJSON: &response{
|
wantFirstResponseBodyJSON: here.Doc(`{
|
||||||
IDPs: []identityProviderResponse{
|
"pinniped_identity_providers": [
|
||||||
{Name: "a-some-ldap-idp", Type: "ldap", Flows: []string{"cli_password"}},
|
{"name": "a-some-ldap-idp", "type": "ldap", "flows": ["cli_password"]},
|
||||||
{Name: "a-some-oidc-idp", Type: "oidc", Flows: []string{"browser_authcode"}},
|
{"name": "a-some-oidc-idp", "type": "oidc", "flows": ["browser_authcode"]},
|
||||||
{Name: "x-some-idp", Type: "ldap", Flows: []string{"cli_password"}},
|
{"name": "x-some-idp", "type": "ldap", "flows": ["cli_password"]},
|
||||||
{Name: "x-some-idp", Type: "oidc", Flows: []string{"browser_authcode"}},
|
{"name": "x-some-idp", "type": "oidc", "flows": ["browser_authcode"]},
|
||||||
{Name: "z-some-ldap-idp", Type: "ldap", Flows: []string{"cli_password"}},
|
{"name": "z-some-ldap-idp", "type": "ldap", "flows": ["cli_password"]},
|
||||||
{Name: "z-some-oidc-idp", Type: "oidc", Flows: []string{"browser_authcode", "cli_password"}},
|
{"name": "z-some-oidc-idp", "type": "oidc", "flows": ["browser_authcode", "cli_password"]}
|
||||||
},
|
]
|
||||||
},
|
}`),
|
||||||
wantSecondResponseBodyJSON: &response{
|
wantSecondResponseBodyJSON: here.Doc(`{
|
||||||
IDPs: []identityProviderResponse{
|
"pinniped_identity_providers": [
|
||||||
{Name: "some-other-ldap-idp-1", Type: "ldap", Flows: []string{"cli_password"}},
|
{"name": "some-other-ldap-idp-1", "type": "ldap", "flows": ["cli_password"]},
|
||||||
{Name: "some-other-ldap-idp-2", Type: "ldap", Flows: []string{"cli_password"}},
|
{"name": "some-other-ldap-idp-2", "type": "ldap", "flows": ["cli_password"]},
|
||||||
{Name: "some-other-oidc-idp-1", Type: "oidc", Flows: []string{"browser_authcode", "cli_password"}},
|
{"name": "some-other-oidc-idp-1", "type": "oidc", "flows": ["browser_authcode", "cli_password"]},
|
||||||
{Name: "some-other-oidc-idp-2", Type: "oidc", Flows: []string{"browser_authcode"}},
|
{"name": "some-other-oidc-idp-2", "type": "oidc", "flows": ["browser_authcode"]}
|
||||||
},
|
]
|
||||||
},
|
}`),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "bad method",
|
name: "bad method",
|
||||||
@ -84,10 +84,8 @@ func TestIDPDiscovery(t *testing.T) {
|
|||||||
|
|
||||||
require.Equal(t, test.wantContentType, rsp.Header().Get("Content-Type"))
|
require.Equal(t, test.wantContentType, rsp.Header().Get("Content-Type"))
|
||||||
|
|
||||||
if test.wantFirstResponseBodyJSON != nil {
|
if test.wantFirstResponseBodyJSON != "" {
|
||||||
wantJSON, err := json.Marshal(test.wantFirstResponseBodyJSON)
|
require.JSONEq(t, test.wantFirstResponseBodyJSON, rsp.Body.String())
|
||||||
require.NoError(t, err)
|
|
||||||
require.JSONEq(t, string(wantJSON), rsp.Body.String())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.wantBodyString != "" {
|
if test.wantBodyString != "" {
|
||||||
@ -112,10 +110,8 @@ func TestIDPDiscovery(t *testing.T) {
|
|||||||
|
|
||||||
require.Equal(t, test.wantContentType, rsp.Header().Get("Content-Type"))
|
require.Equal(t, test.wantContentType, rsp.Header().Get("Content-Type"))
|
||||||
|
|
||||||
if test.wantFirstResponseBodyJSON != nil {
|
if test.wantFirstResponseBodyJSON != "" {
|
||||||
wantJSON, err := json.Marshal(test.wantSecondResponseBodyJSON)
|
require.JSONEq(t, test.wantSecondResponseBodyJSON, rsp.Body.String())
|
||||||
require.NoError(t, err)
|
|
||||||
require.JSONEq(t, string(wantJSON), rsp.Body.String())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.wantBodyString != "" {
|
if test.wantBodyString != "" {
|
||||||
|
Loading…
Reference in New Issue
Block a user