mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-01-06 05:27:23 +00:00
Implement the OIDCClientSecretRequest API
This commit is a WIP commit because it doesn't include many tests for the new feature. Co-authored-by: Ryan Richard <richardry@vmware.com> Co-authored-by: Benjamin A. Petersen <ben@benjaminapetersen.me>
This commit is contained in:
@@ -1404,7 +1404,7 @@ func TestSupervisorLogin_Browser(t *testing.T) {
|
||||
require.Equal(t, http.StatusForbidden, status)
|
||||
require.Equal(t,
|
||||
`{"error":"access_denied","error_description":"The resource owner or authorization server denied the request. `+
|
||||
`missing the 'pinniped:request-audience' scope"}`,
|
||||
`Missing the 'pinniped:request-audience' scope."}`,
|
||||
body)
|
||||
},
|
||||
},
|
||||
|
||||
@@ -361,6 +361,53 @@ func TestOIDCClientStaticValidation_Parallel(t *testing.T) {
|
||||
},
|
||||
wantErr: `OIDCClient.config.supervisor.pinniped.dev "zone" is invalid: [metadata.name: Invalid value: "zone": metadata.name in body should match '^client\.oauth\.pinniped\.dev-', spec.allowedGrantTypes[0]: Unsupported value: "the": supported values: "authorization_code", "refresh_token", "urn:ietf:params:oauth:grant-type:token-exchange", spec.allowedRedirectURIs[0]: Invalid value: "of": spec.allowedRedirectURIs[0] in body should match '^https://.+|^http://(127\.0\.0\.1|\[::1\])(:\d+)?/', spec.allowedScopes[0]: Unsupported value: "enders": supported values: "openid", "offline_access", "username", "groups", "pinniped:request-audience"]`,
|
||||
},
|
||||
{
|
||||
name: "just the prefix is not valid",
|
||||
client: &supervisorconfigv1alpha1.OIDCClient{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "client.oauth.pinniped.dev-",
|
||||
},
|
||||
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
|
||||
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{
|
||||
"https://example.com",
|
||||
"http://127.0.0.1/yoyo",
|
||||
},
|
||||
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{
|
||||
"authorization_code",
|
||||
"refresh_token",
|
||||
"urn:ietf:params:oauth:grant-type:token-exchange",
|
||||
},
|
||||
AllowedScopes: []supervisorconfigv1alpha1.Scope{
|
||||
"openid",
|
||||
"offline_access",
|
||||
"username",
|
||||
"groups",
|
||||
"pinniped:request-audience",
|
||||
},
|
||||
},
|
||||
},
|
||||
fixWant: func(t *testing.T, err error, want string) string {
|
||||
require.Error(t, err)
|
||||
prefix := `OIDCClient.config.supervisor.pinniped.dev "client.oauth.pinniped.dev-" is invalid: metadata.name: Invalid value: "client.oauth.pinniped.dev-": `
|
||||
suffix := ` must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`
|
||||
|
||||
oldErrContains := `a DNS-1123 subdomain` // Kube 1.19 and before used this error text
|
||||
newErrContains := `a lowercase RFC 1123 subdomain` // Newer versions of Kube use this error text
|
||||
|
||||
gotErr := err.Error()
|
||||
switch {
|
||||
case strings.Contains(gotErr, oldErrContains):
|
||||
return prefix + oldErrContains + suffix
|
||||
case strings.Contains(gotErr, newErrContains):
|
||||
return prefix + newErrContains + suffix
|
||||
default:
|
||||
require.Failf(t, "the error message did not contain %q or %q. actual message was: %s",
|
||||
oldErrContains, newErrContains, gotErr)
|
||||
return ""
|
||||
}
|
||||
},
|
||||
wantErr: `this will be replaced by fixWant()`,
|
||||
},
|
||||
{
|
||||
name: "everything valid",
|
||||
client: &supervisorconfigv1alpha1.OIDCClient{
|
||||
@@ -606,7 +653,7 @@ func TestOIDCClientControllerValidations_Parallel(t *testing.T) {
|
||||
|
||||
if tt.secret != nil {
|
||||
// Force the Secret's name to match the client created above.
|
||||
tt.secret.Name = oidcclientsecretstorage.New(nil, nil).GetName(client.UID)
|
||||
tt.secret.Name = oidcclientsecretstorage.New(nil).GetName(client.UID)
|
||||
secret, err := secrets.Create(ctx, tt.secret, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
|
||||
@@ -5,6 +5,7 @@ package integration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -12,6 +13,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"go.pinniped.dev/generated/latest/apis/supervisor/clientsecret/v1alpha1"
|
||||
supervisorconfigv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
|
||||
"go.pinniped.dev/test/testlib"
|
||||
)
|
||||
|
||||
@@ -19,27 +21,61 @@ func TestOIDCClientSecretRequest_HappyPath_Parallel(t *testing.T) {
|
||||
env := testlib.IntegrationEnv(t)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
t.Cleanup(cancel)
|
||||
|
||||
client := testlib.NewSupervisorClientset(t)
|
||||
|
||||
oidcClient, err := client.ConfigV1alpha1().OIDCClients(env.SupervisorNamespace).Create(ctx,
|
||||
&supervisorconfigv1alpha1.OIDCClient{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "client.oauth.pinniped.dev-",
|
||||
},
|
||||
Spec: supervisorconfigv1alpha1.OIDCClientSpec{
|
||||
AllowedRedirectURIs: []supervisorconfigv1alpha1.RedirectURI{
|
||||
"https://example.com",
|
||||
"http://127.0.0.1/yoyo",
|
||||
},
|
||||
AllowedGrantTypes: []supervisorconfigv1alpha1.GrantType{
|
||||
"authorization_code",
|
||||
"refresh_token",
|
||||
"urn:ietf:params:oauth:grant-type:token-exchange",
|
||||
},
|
||||
AllowedScopes: []supervisorconfigv1alpha1.Scope{
|
||||
"openid",
|
||||
"offline_access",
|
||||
"username",
|
||||
"groups",
|
||||
"pinniped:request-audience",
|
||||
},
|
||||
},
|
||||
},
|
||||
metav1.CreateOptions{},
|
||||
)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
deleteErr := client.ConfigV1alpha1().OIDCClients(env.SupervisorNamespace).Delete(ctx, oidcClient.Name, metav1.DeleteOptions{})
|
||||
require.NoError(t, deleteErr)
|
||||
})
|
||||
|
||||
response, err := client.ClientsecretV1alpha1().OIDCClientSecretRequests(env.SupervisorNamespace).Create(ctx,
|
||||
&v1alpha1.OIDCClientSecretRequest{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: oidcClient.Name,
|
||||
},
|
||||
Spec: v1alpha1.OIDCClientSecretRequestSpec{
|
||||
GenerateNewSecret: true,
|
||||
},
|
||||
}, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
// the hardcoded values from the nonfunctional request
|
||||
require.Equal(t, response.Status.TotalClientSecrets, 20)
|
||||
require.Equal(t, response.Status.GeneratedSecret, "not-a-real-secret")
|
||||
require.Equal(t, response.Status.TotalClientSecrets, 1)
|
||||
require.Len(t, response.Status.GeneratedSecret, hex.EncodedLen(32))
|
||||
}
|
||||
|
||||
func TestOIDCClientSecretRequest_Unauthenticated_Parallel(t *testing.T) {
|
||||
env := testlib.IntegrationEnv(t)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
t.Cleanup(cancel)
|
||||
|
||||
client := testlib.NewAnonymousSupervisorClientset(t)
|
||||
|
||||
|
||||
@@ -441,7 +441,7 @@ func createOIDCClientSecret(t *testing.T, forOIDCClient *configv1alpha1.OIDCClie
|
||||
|
||||
created, err := kubeClient.CoreV1().Secrets(env.SupervisorNamespace).Create(ctx, &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: oidcclientsecretstorage.New(nil, nil).GetName(forOIDCClient.UID), // use the required name
|
||||
Name: oidcclientsecretstorage.New(nil).GetName(forOIDCClient.UID), // use the required name
|
||||
Labels: map[string]string{"storage.pinniped.dev/type": "oidc-client-secret", "pinniped.dev/test": ""},
|
||||
Annotations: map[string]string{"pinniped.dev/testName": t.Name()},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user