From 4f154100ff31808d4c68a4cb0806f8bb4d823156 Mon Sep 17 00:00:00 2001 From: Matt Moyer Date: Thu, 11 Mar 2021 16:14:56 -0600 Subject: [PATCH] Remove "--concierge-mode" flag from "pinniped login [...]" commands. Signed-off-by: Matt Moyer --- cmd/pinniped/cmd/login_oidc.go | 90 ++------------------------- cmd/pinniped/cmd/login_oidc_test.go | 38 ----------- cmd/pinniped/cmd/login_static.go | 30 ++------- cmd/pinniped/cmd/login_static_test.go | 13 ---- 4 files changed, 11 insertions(+), 160 deletions(-) diff --git a/cmd/pinniped/cmd/login_oidc.go b/cmd/pinniped/cmd/login_oidc.go index 7dd29943..3887ccf7 100644 --- a/cmd/pinniped/cmd/login_oidc.go +++ b/cmd/pinniped/cmd/login_oidc.go @@ -14,14 +14,8 @@ import ( "net/http" "os" "path/filepath" - "strings" "time" - corev1 "k8s.io/api/core/v1" - - authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1" - loginv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/login/v1alpha1" - "github.com/coreos/go-oidc/v3/oidc" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -71,7 +65,6 @@ type oidcLoginFlags struct { conciergeEndpoint string conciergeCABundle string conciergeAPIGroupSuffix string - conciergeMode conciergeModeFlag } func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command { @@ -102,7 +95,6 @@ func oidcLoginCommand(deps oidcLoginCommandDeps) *cobra.Command { cmd.Flags().StringVar(&flags.conciergeEndpoint, "concierge-endpoint", "", "API base for the Concierge endpoint") cmd.Flags().StringVar(&flags.conciergeCABundle, "concierge-ca-bundle-data", "", "CA bundle to use when connecting to the Concierge") cmd.Flags().StringVar(&flags.conciergeAPIGroupSuffix, "concierge-api-group-suffix", groupsuffix.PinnipedDefaultSuffix, "Concierge API group suffix") - cmd.Flags().Var(&flags.conciergeMode, "concierge-mode", "Concierge mode of operation") mustMarkHidden(cmd, "debug-session-cache") mustMarkRequired(cmd, "issuer") @@ -179,37 +171,17 @@ func runOIDCLogin(cmd *cobra.Command, deps oidcLoginCommandDeps, flags oidcLogin } cred := tokenCredential(token) - // If there is no concierge configuration, return the credential directly. - if concierge == nil { - return json.NewEncoder(cmd.OutOrStdout()).Encode(cred) - } + // If the concierge was configured, exchange the credential for a separate short-lived, cluster-specific credential. + if concierge != nil { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() - // If the concierge was configured, we need to do extra steps to make the credential usable. - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - - // The exact behavior depends on in which mode the Concierge is operating. - switch flags.conciergeMode { - case modeUnknown, modeTokenCredentialRequestAPI: - // do a credential exchange request - cred, err := deps.exchangeToken(ctx, concierge, token.IDToken.Token) + cred, err = deps.exchangeToken(ctx, concierge, token.IDToken.Token) if err != nil { return fmt.Errorf("could not complete concierge credential exchange: %w", err) } - return json.NewEncoder(cmd.OutOrStdout()).Encode(cred) - - case modeImpersonationProxy: - // Put the token into a TokenCredentialRequest - // put the TokenCredentialRequest in an ExecCredential - req, err := execCredentialForImpersonationProxy(token.IDToken.Token, flags.conciergeAuthenticatorType, flags.conciergeAuthenticatorName, &token.IDToken.Expiry) - if err != nil { - return err - } - return json.NewEncoder(cmd.OutOrStdout()).Encode(req) - - default: - return fmt.Errorf("unsupported Concierge mode %q", flags.conciergeMode.String()) } + return json.NewEncoder(cmd.OutOrStdout()).Encode(cred) } func makeClient(caBundlePaths []string, caBundleData []string) (*http.Client, error) { @@ -271,53 +243,3 @@ func mustGetConfigDir() string { } return filepath.Join(home, ".config", xdgAppName) } - -func execCredentialForImpersonationProxy( - idToken string, - conciergeAuthenticatorType string, - conciergeAuthenticatorName string, - tokenExpiry *metav1.Time, -) (*clientauthv1beta1.ExecCredential, error) { - // TODO maybe de-dup this with conciergeclient.go - // TODO reuse code from internal/testutil/impersonationtoken here to create token - var kind string - switch strings.ToLower(conciergeAuthenticatorType) { - case "webhook": - kind = "WebhookAuthenticator" - case "jwt": - kind = "JWTAuthenticator" - default: - return nil, fmt.Errorf(`invalid authenticator type: %q, supported values are "webhook" and "jwt"`, kind) - } - reqJSON, err := json.Marshal(&loginv1alpha1.TokenCredentialRequest{ - TypeMeta: metav1.TypeMeta{ - Kind: "TokenCredentialRequest", - APIVersion: loginv1alpha1.GroupName + "/v1alpha1", - }, - Spec: loginv1alpha1.TokenCredentialRequestSpec{ - Token: idToken, // TODO - Authenticator: corev1.TypedLocalObjectReference{ - APIGroup: &authenticationv1alpha1.SchemeGroupVersion.Group, - Kind: kind, - Name: conciergeAuthenticatorName, - }, - }, - }) - if err != nil { - return nil, fmt.Errorf("Error creating TokenCredentialRequest for impersonation proxy: %w", err) - } - encodedToken := base64.StdEncoding.EncodeToString(reqJSON) - cred := &clientauthv1beta1.ExecCredential{ - TypeMeta: metav1.TypeMeta{ - Kind: "ExecCredential", - APIVersion: "client.authentication.k8s.io/v1beta1", - }, - Status: &clientauthv1beta1.ExecCredentialStatus{ - Token: encodedToken, - }, - } - if !tokenExpiry.IsZero() { - cred.Status.ExpirationTimestamp = tokenExpiry - } - return cred, nil -} diff --git a/cmd/pinniped/cmd/login_oidc_test.go b/cmd/pinniped/cmd/login_oidc_test.go index f36d67cd..7bba6d9b 100644 --- a/cmd/pinniped/cmd/login_oidc_test.go +++ b/cmd/pinniped/cmd/login_oidc_test.go @@ -8,7 +8,6 @@ import ( "context" "crypto/x509/pkix" "encoding/base64" - "encoding/json" "fmt" "io/ioutil" "path/filepath" @@ -16,12 +15,9 @@ import ( "time" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" clientauthv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1" - authenticationv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/authentication/v1alpha1" - loginv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/login/v1alpha1" "go.pinniped.dev/internal/certauthority" "go.pinniped.dev/internal/here" "go.pinniped.dev/internal/testutil" @@ -69,7 +65,6 @@ func TestLoginOIDCCommand(t *testing.T) { --concierge-authenticator-type string Concierge authenticator type (e.g., 'webhook', 'jwt') --concierge-ca-bundle-data string CA bundle to use when connecting to the Concierge --concierge-endpoint string API base for the Concierge endpoint - --concierge-mode mode Concierge mode of operation (default TokenCredentialRequestAPI) --enable-concierge Use the Concierge to login -h, --help help for oidc --issuer string OpenID Connect issuer URL @@ -199,21 +194,6 @@ func TestLoginOIDCCommand(t *testing.T) { wantOptionsCount: 7, wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"token":"exchanged-token"}}` + "\n", }, - { - name: "success with impersonation proxy", - args: []string{ - "--client-id", "test-client-id", - "--issuer", "test-issuer", - "--enable-concierge", - "--concierge-mode", "ImpersonationProxy", - "--concierge-authenticator-type", "webhook", - "--concierge-authenticator-name", "test-authenticator", - "--concierge-endpoint", "https://127.0.0.1:1234/", - "--concierge-ca-bundle-data", base64.StdEncoding.EncodeToString(testCA.Bundle()), - }, - wantOptionsCount: 3, - wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"expirationTimestamp":"3020-10-12T13:14:15Z","token":"` + impersonationProxyTestToken("test-id-token") + `"}}` + "\n", - }, } for _, tt := range tests { tt := tt @@ -270,21 +250,3 @@ func TestLoginOIDCCommand(t *testing.T) { }) } } - -func impersonationProxyTestToken(token string) string { - reqJSON, _ := json.Marshal(&loginv1alpha1.TokenCredentialRequest{ - TypeMeta: metav1.TypeMeta{ - Kind: "TokenCredentialRequest", - APIVersion: loginv1alpha1.GroupName + "/v1alpha1", - }, - Spec: loginv1alpha1.TokenCredentialRequestSpec{ - Token: token, - Authenticator: corev1.TypedLocalObjectReference{ - APIGroup: &authenticationv1alpha1.SchemeGroupVersion.Group, - Kind: "WebhookAuthenticator", - Name: "test-authenticator", - }, - }, - }) - return base64.StdEncoding.EncodeToString(reqJSON) -} diff --git a/cmd/pinniped/cmd/login_static.go b/cmd/pinniped/cmd/login_static.go index c9942551..4e8bef67 100644 --- a/cmd/pinniped/cmd/login_static.go +++ b/cmd/pinniped/cmd/login_static.go @@ -47,7 +47,6 @@ type staticLoginParams struct { conciergeEndpoint string conciergeCABundle string conciergeAPIGroupSuffix string - conciergeMode conciergeModeFlag } func staticLoginCommand(deps staticLoginDeps) *cobra.Command { @@ -70,7 +69,6 @@ func staticLoginCommand(deps staticLoginDeps) *cobra.Command { cmd.Flags().StringVar(&flags.conciergeEndpoint, "concierge-endpoint", "", "API base for the Concierge endpoint") cmd.Flags().StringVar(&flags.conciergeCABundle, "concierge-ca-bundle-data", "", "CA bundle to use when connecting to the Concierge") cmd.Flags().StringVar(&flags.conciergeAPIGroupSuffix, "concierge-api-group-suffix", groupsuffix.PinnipedDefaultSuffix, "Concierge API group suffix") - cmd.Flags().Var(&flags.conciergeMode, "concierge-mode", "Concierge mode of operation") cmd.RunE = func(cmd *cobra.Command, args []string) error { return runStaticLogin(cmd.OutOrStdout(), deps, flags) } @@ -115,34 +113,16 @@ func runStaticLogin(out io.Writer, deps staticLoginDeps, flags staticLoginParams } cred := tokenCredential(&oidctypes.Token{IDToken: &oidctypes.IDToken{Token: token}}) - // If there is no concierge configuration, return the credential directly. - if concierge == nil { - return json.NewEncoder(out).Encode(cred) - } - - // If the concierge is enabled, we need to do extra steps. - switch flags.conciergeMode { - case modeUnknown, modeTokenCredentialRequestAPI: - // do a credential exchange request + // If the concierge was configured, exchange the credential for a separate short-lived, cluster-specific credential. + if concierge != nil { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - cred, err := deps.exchangeToken(ctx, concierge, token) + var err error + cred, err = deps.exchangeToken(ctx, concierge, token) if err != nil { return fmt.Errorf("could not complete concierge credential exchange: %w", err) } - return json.NewEncoder(out).Encode(cred) - - case modeImpersonationProxy: - // Put the token into a TokenCredentialRequest - // put the TokenCredentialRequest in an ExecCredential - req, err := execCredentialForImpersonationProxy(token, flags.conciergeAuthenticatorType, flags.conciergeAuthenticatorName, nil) - if err != nil { - return err - } - return json.NewEncoder(out).Encode(req) - - default: - return fmt.Errorf("unsupported Concierge mode %q", flags.conciergeMode.String()) } + return json.NewEncoder(out).Encode(cred) } diff --git a/cmd/pinniped/cmd/login_static_test.go b/cmd/pinniped/cmd/login_static_test.go index 9ee5a969..fc81edc4 100644 --- a/cmd/pinniped/cmd/login_static_test.go +++ b/cmd/pinniped/cmd/login_static_test.go @@ -56,7 +56,6 @@ func TestLoginStaticCommand(t *testing.T) { --concierge-authenticator-type string Concierge authenticator type (e.g., 'webhook', 'jwt') --concierge-ca-bundle-data string CA bundle to use when connecting to the Concierge --concierge-endpoint string API base for the Concierge endpoint - --concierge-mode mode Concierge mode of operation (default TokenCredentialRequestAPI) --enable-concierge Use the Concierge to login -h, --help help for static --token string Static token to present during login @@ -152,18 +151,6 @@ func TestLoginStaticCommand(t *testing.T) { }, wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"token":"test-token"}}` + "\n", }, - { - name: "impersonation proxy success", - args: []string{ - "--enable-concierge", - "--concierge-mode", "ImpersonationProxy", - "--token", "test-token", - "--concierge-endpoint", "https://127.0.0.1/", - "--concierge-authenticator-type", "webhook", - "--concierge-authenticator-name", "test-authenticator", - }, - wantStdout: `{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1beta1","spec":{},"status":{"token":"` + impersonationProxyTestToken("test-token") + `"}}` + "\n", - }, } for _, tt := range tests { tt := tt