mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-09-20 06:54:20 +00:00
Add stub LDAP API type and integration test
The goal here was to start on an integration test to get us closer to the red test that we want so we can start working on LDAP. Signed-off-by: Andrew Keesler <akeesler@vmware.com>
This commit is contained in:
@@ -170,6 +170,20 @@ func TestGetAPIResourceList(t *testing.T) {
|
||||
Kind: "OIDCIdentityProvider",
|
||||
Verbs: []string{"get", "patch", "update"},
|
||||
},
|
||||
{
|
||||
Name: "ldapidentityproviders",
|
||||
SingularName: "ldapidentityprovider",
|
||||
Namespaced: true,
|
||||
Kind: "LDAPIdentityProvider",
|
||||
Verbs: []string{"delete", "deletecollection", "get", "list", "patch", "create", "update", "watch"},
|
||||
Categories: []string{"pinniped", "pinniped-idp", "pinniped-idps"},
|
||||
},
|
||||
{
|
||||
Name: "ldapidentityproviders/status",
|
||||
Namespaced: true,
|
||||
Kind: "LDAPIdentityProvider",
|
||||
Verbs: []string{"get", "patch", "update"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -17,12 +17,11 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
|
||||
coreosoidc "github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/oauth2"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
|
||||
configv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
|
||||
idpv1alpha1 "go.pinniped.dev/generated/latest/apis/supervisor/idp/v1alpha1"
|
||||
@@ -37,6 +36,52 @@ import (
|
||||
)
|
||||
|
||||
func TestSupervisorLogin(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
createIDP func(t *testing.T)
|
||||
requestAuthorization func(t *testing.T, downstreamAuthorizeURL, downstreamCallbackURL string)
|
||||
}{
|
||||
{
|
||||
name: "oidc",
|
||||
createIDP: func(t *testing.T) {
|
||||
t.Helper()
|
||||
env := library.IntegrationEnv(t)
|
||||
library.CreateTestOIDCIdentityProvider(t, idpv1alpha1.OIDCIdentityProviderSpec{
|
||||
Issuer: env.SupervisorTestUpstream.Issuer,
|
||||
TLS: &idpv1alpha1.TLSSpec{
|
||||
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorTestUpstream.CABundle)),
|
||||
},
|
||||
Client: idpv1alpha1.OIDCClient{
|
||||
SecretName: library.CreateClientCredsSecret(t, env.SupervisorTestUpstream.ClientID, env.SupervisorTestUpstream.ClientSecret).Name,
|
||||
},
|
||||
}, idpv1alpha1.PhaseReady)
|
||||
},
|
||||
requestAuthorization: requestAuthorizationUsingOIDCIdentityProvider,
|
||||
},
|
||||
{
|
||||
name: "ldap",
|
||||
createIDP: func(t *testing.T) {
|
||||
t.Helper()
|
||||
library.CreateTestLDAPIdentityProvider(t, idpv1alpha1.LDAPIdentityProviderSpec{
|
||||
Host: "something",
|
||||
}, "") // TODO: this should be Ready!
|
||||
},
|
||||
requestAuthorization: requestAuthorizationUsingLDAPIdentityProvider,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
testSupervisorLogin(t, test.createIDP, test.requestAuthorization)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testSupervisorLogin(
|
||||
t *testing.T,
|
||||
createIDP func(t *testing.T),
|
||||
requestAuthorization func(t *testing.T, downstreamAuthorizeURL, downstreamCallbackURL string),
|
||||
) {
|
||||
env := library.IntegrationEnv(t)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
@@ -119,16 +164,8 @@ func TestSupervisorLogin(t *testing.T) {
|
||||
}, 30*time.Second, 200*time.Millisecond)
|
||||
require.Equal(t, http.StatusOK, jwksRequestStatus)
|
||||
|
||||
// Create upstream OIDC provider and wait for it to become ready.
|
||||
library.CreateTestOIDCIdentityProvider(t, idpv1alpha1.OIDCIdentityProviderSpec{
|
||||
Issuer: env.SupervisorTestUpstream.Issuer,
|
||||
TLS: &idpv1alpha1.TLSSpec{
|
||||
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorTestUpstream.CABundle)),
|
||||
},
|
||||
Client: idpv1alpha1.OIDCClient{
|
||||
SecretName: library.CreateClientCredsSecret(t, env.SupervisorTestUpstream.ClientID, env.SupervisorTestUpstream.ClientSecret).Name,
|
||||
},
|
||||
}, idpv1alpha1.PhaseReady)
|
||||
// Create upstream IDP and wait for it to become ready.
|
||||
createIDP(t)
|
||||
|
||||
// Perform OIDC discovery for our downstream.
|
||||
var discovery *coreosoidc.Provider
|
||||
@@ -172,18 +209,8 @@ func TestSupervisorLogin(t *testing.T) {
|
||||
require.NoError(t, authorizeResp.Body.Close())
|
||||
expectSecurityHeaders(t, authorizeResp)
|
||||
|
||||
// Open the web browser and navigate to the downstream authorize URL.
|
||||
page := browsertest.Open(t)
|
||||
t.Logf("opening browser to downstream authorize URL %s", library.MaskTokens(downstreamAuthorizeURL))
|
||||
require.NoError(t, page.Navigate(downstreamAuthorizeURL))
|
||||
|
||||
// Expect to be redirected to the upstream provider and log in.
|
||||
browsertest.LoginToUpstream(t, page, env.SupervisorTestUpstream)
|
||||
|
||||
// Wait for the login to happen and us be redirected back to a localhost callback.
|
||||
t.Logf("waiting for redirect to callback")
|
||||
callbackURLPattern := regexp.MustCompile(`\A` + regexp.QuoteMeta(localCallbackServer.URL) + `\?.+\z`)
|
||||
browsertest.WaitForURL(t, page, callbackURLPattern)
|
||||
// Perform parameterized auth code acquisition.
|
||||
requestAuthorization(t, downstreamAuthorizeURL, localCallbackServer.URL)
|
||||
|
||||
// Expect that our callback handler was invoked.
|
||||
callback := localCallbackServer.waitForCallback(10 * time.Second)
|
||||
@@ -269,6 +296,29 @@ func verifyTokenResponse(
|
||||
require.NotEmpty(t, tokenResponse.RefreshToken)
|
||||
}
|
||||
|
||||
func requestAuthorizationUsingOIDCIdentityProvider(t *testing.T, downstreamAuthorizeURL, downstreamCallbackURL string) {
|
||||
t.Helper()
|
||||
env := library.IntegrationEnv(t)
|
||||
|
||||
// Open the web browser and navigate to the downstream authorize URL.
|
||||
page := browsertest.Open(t)
|
||||
t.Logf("opening browser to downstream authorize URL %s", library.MaskTokens(downstreamAuthorizeURL))
|
||||
require.NoError(t, page.Navigate(downstreamAuthorizeURL))
|
||||
|
||||
// Expect to be redirected to the upstream provider and log in.
|
||||
browsertest.LoginToUpstream(t, page, env.SupervisorTestUpstream)
|
||||
|
||||
// Wait for the login to happen and us be redirected back to a localhost callback.
|
||||
t.Logf("waiting for redirect to callback")
|
||||
callbackURLPattern := regexp.MustCompile(`\A` + regexp.QuoteMeta(downstreamCallbackURL) + `\?.+\z`)
|
||||
browsertest.WaitForURL(t, page, callbackURLPattern)
|
||||
}
|
||||
|
||||
func requestAuthorizationUsingLDAPIdentityProvider(t *testing.T, downstreamAuthorizeURL, downstreamCallbackURL string) {
|
||||
t.Helper()
|
||||
t.Skip("implement me!")
|
||||
}
|
||||
|
||||
func startLocalCallbackServer(t *testing.T) *localCallbackServer {
|
||||
// Handle the callback by sending the *http.Request object back through a channel.
|
||||
callbacks := make(chan *http.Request, 1)
|
||||
|
||||
+36
-1
@@ -377,7 +377,7 @@ func CreateTestOIDCIdentityProvider(t *testing.T, spec idpv1alpha1.OIDCIdentityP
|
||||
upstreams := client.IDPV1alpha1().OIDCIdentityProviders(env.SupervisorNamespace)
|
||||
|
||||
created, err := upstreams.Create(ctx, &idpv1alpha1.OIDCIdentityProvider{
|
||||
ObjectMeta: testObjectMeta(t, "upstream"),
|
||||
ObjectMeta: testObjectMeta(t, "upstream-oidc-idp"),
|
||||
Spec: spec,
|
||||
}, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
@@ -401,6 +401,41 @@ func CreateTestOIDCIdentityProvider(t *testing.T, spec idpv1alpha1.OIDCIdentityP
|
||||
return result
|
||||
}
|
||||
|
||||
func CreateTestLDAPIdentityProvider(t *testing.T, spec idpv1alpha1.LDAPIdentityProviderSpec, expectedPhase idpv1alpha1.LDAPIdentityProviderPhase) *idpv1alpha1.LDAPIdentityProvider {
|
||||
t.Helper()
|
||||
env := IntegrationEnv(t)
|
||||
client := NewSupervisorClientset(t)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
// Create the LDAPIdentityProvider using GenerateName to get a random name.
|
||||
upstreams := client.IDPV1alpha1().LDAPIdentityProviders(env.SupervisorNamespace)
|
||||
|
||||
created, err := upstreams.Create(ctx, &idpv1alpha1.LDAPIdentityProvider{
|
||||
ObjectMeta: testObjectMeta(t, "upstream-ldap-idp"),
|
||||
Spec: spec,
|
||||
}, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Always clean this up after this point.
|
||||
t.Cleanup(func() {
|
||||
t.Logf("cleaning up test LDAPIdentityProvider %s/%s", created.Namespace, created.Name)
|
||||
err := upstreams.Delete(context.Background(), created.Name, metav1.DeleteOptions{})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
t.Logf("created test LDAPIdentityProvider %s", created.Name)
|
||||
|
||||
// Wait for the LDAPIdentityProvider to enter the expected phase (or time out).
|
||||
var result *idpv1alpha1.LDAPIdentityProvider
|
||||
require.Eventuallyf(t, func() bool {
|
||||
var err error
|
||||
result, err = upstreams.Get(ctx, created.Name, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
return result.Status.Phase == expectedPhase
|
||||
}, 60*time.Second, 1*time.Second, "expected the LDAPIdentityProvider to go into phase %s", expectedPhase)
|
||||
return result
|
||||
}
|
||||
|
||||
func CreateTestClusterRoleBinding(t *testing.T, subject rbacv1.Subject, roleRef rbacv1.RoleRef) *rbacv1.ClusterRoleBinding {
|
||||
t.Helper()
|
||||
client := NewKubernetesClientset(t)
|
||||
|
||||
Reference in New Issue
Block a user