// Copyright 2021 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 // Package impersonationtoken contains a test utility to generate a token to be used against our // impersonation proxy. // // It is its own package to fix import cycles involving concierge/scheme, testutil, and groupsuffix. package impersonationtoken import ( "encoding/base64" "testing" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" loginv1alpha1 "go.pinniped.dev/generated/latest/apis/concierge/login/v1alpha1" conciergescheme "go.pinniped.dev/internal/concierge/scheme" "go.pinniped.dev/internal/groupsuffix" ) func Make( t *testing.T, token string, authenticator *corev1.TypedLocalObjectReference, apiGroupSuffix string, ) string { t.Helper() // The impersonation test token should be a base64-encoded TokenCredentialRequest object. The API // group of the TokenCredentialRequest object, and its Spec.Authenticator, should match whatever // is installed on the cluster. This API group is usually replaced by the kubeclient middleware, // but this object is not touched by the middleware since it is in a HTTP header. Therefore, we // need to make a manual edit here. scheme, loginGV, _ := conciergescheme.New(apiGroupSuffix) tokenCredentialRequest := loginv1alpha1.TokenCredentialRequest{ TypeMeta: metav1.TypeMeta{ Kind: "TokenCredentialRequest", APIVersion: loginGV.Group + "/v1alpha1", }, Spec: loginv1alpha1.TokenCredentialRequestSpec{ Token: token, Authenticator: *authenticator.DeepCopy(), }, } // It is assumed that the provided authenticator uses the default pinniped.dev API group, since // this is usually replaced by the kubeclient middleware. Since we are not going through the // kubeclient middleware, we need to make this replacement ourselves. require.NotNil(t, tokenCredentialRequest.Spec.Authenticator.APIGroup, "expected authenticator to have non-nil API group") authenticatorAPIGroup, ok := groupsuffix.Replace(*tokenCredentialRequest.Spec.Authenticator.APIGroup, apiGroupSuffix) require.True(t, ok, "couldn't replace suffix of %q with %q", *tokenCredentialRequest.Spec.Authenticator.APIGroup, apiGroupSuffix) tokenCredentialRequest.Spec.Authenticator.APIGroup = &authenticatorAPIGroup codecs := serializer.NewCodecFactory(scheme) respInfo, ok := runtime.SerializerInfoForMediaType(codecs.SupportedMediaTypes(), runtime.ContentTypeJSON) require.True(t, ok, "couldn't find serializer info for media type") reqJSON, err := runtime.Encode(respInfo.PrettySerializer, &tokenCredentialRequest) require.NoError(t, err) return base64.StdEncoding.EncodeToString(reqJSON) }