From 5c283d941cc70f93eb4b70f4e392c55233363edf Mon Sep 17 00:00:00 2001 From: Margo Crawford Date: Thu, 8 Jul 2021 15:00:04 -0700 Subject: [PATCH] Helper script for running active directory tests --- hack/prepare-for-integration-tests.sh | 23 +++++++++++++++++++++++ test/integration/supervisor_login_test.go | 17 ++++++++--------- test/testlib/client.go | 5 +++-- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index b918049b..ea57a557 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -50,6 +50,7 @@ skip_build=no clean_kind=no api_group_suffix="pinniped.dev" # same default as in the values.yaml ytt file skip_chromedriver_check=no +test_active_directory=no while (("$#")); do case "$1" in @@ -79,6 +80,10 @@ while (("$#")); do skip_chromedriver_check=yes shift ;; + --test-active-directory) + test_active_directory=yes + shift + ;; -*) log_error "Unsupported flag $1" >&2 exit 1 @@ -369,6 +374,24 @@ export PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_PASSWORD=${dex_test_password} export PINNIPED_TEST_SUPERVISOR_UPSTREAM_OIDC_EXPECTED_GROUPS= # Dex's local user store does not let us configure groups. export PINNIPED_TEST_API_GROUP_SUFFIX='${api_group_suffix}' +if [[ "$test_active_directory" == "yes" ]]; then + +if [[ -z "$(gcloud config list account --format "value(core.account)")" ]]; then + echo "Please run \`gcloud auth login\`" + exit 1 +fi + +export PINNIPED_TEST_AD_HOST="$(gcloud secrets versions access latest --secret="concourse-secrets" --project tanzu-user-authentication | yq e '.aws-ad-host' -))" +export PINNIPED_TEST_AD_BIND_ACCOUNT_USERNAME="$(gcloud secrets versions access latest --secret="concourse-secrets" --project tanzu-user-authentication | yq e '.aws-ad-bind-account-username' -))" +export PINNIPED_TEST_AD_BIND_ACCOUNT_PASSWORD="$(gcloud secrets versions access latest --secret="concourse-secrets" --project tanzu-user-authentication | yq e '.aws-ad-bind-account-password' -)" +export PINNIPED_TEST_AD_USER_UNIQUE_ID_ATTRIBUTE_NAME="objectGUID" +export PINNIPED_TEST_AD_USER_UNIQUE_ID_ATTRIBUTE_VALUE="$(gcloud secrets versions access latest --secret="concourse-secrets" --project tanzu-user-authentication | yq e '.aws-ad-user-unique-id-attribute-value' -)" +export PINNIPED_TEST_AD_USERNAME_ATTRIBUTE_NAME="sAMAccountName" +export PINNIPED_TEST_AD_USERNAME_ATTRIBUTE_VALUE="$(gcloud secrets versions access latest --secret="concourse-secrets" --project tanzu-user-authentication | yq e '.aws-ad-user-sAMAccountName' -))" +export PINNIPED_TEST_AD_USER_PASSWORD="$(gcloud secrets versions access latest --secret="concourse-secrets" --project tanzu-user-authentication | yq e '.aws-ad-user-password' -)" +export PINNIPED_TEST_AD_LDAPS_CA_BUNDLE="$(gcloud secrets versions access latest --secret="concourse-secrets" --project tanzu-user-authentication | yq e '.aws-ad-ca-data' -))" +fi + read -r -d '' PINNIPED_TEST_CLUSTER_CAPABILITY_YAML << PINNIPED_TEST_CLUSTER_CAPABILITY_YAML_EOF || true ${pinniped_cluster_capability_file_content} PINNIPED_TEST_CLUSTER_CAPABILITY_YAML_EOF diff --git a/test/integration/supervisor_login_test.go b/test/integration/supervisor_login_test.go index 1303f8d6..aec98094 100644 --- a/test/integration/supervisor_login_test.go +++ b/test/integration/supervisor_login_test.go @@ -250,7 +250,7 @@ func TestSupervisorLogin(t *testing.T) { }, ) adIDP := testlib.CreateTestActiveDirectoryIdentityProvider(t, idpv1alpha1.ActiveDirectoryIdentityProviderSpec{ - Host: env.SupervisorUpstreamLDAP.Host, + Host: env.SupervisorUpstreamActiveDirectory.Host, TLS: &idpv1alpha1.TLSSpec{ CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorUpstreamActiveDirectory.CABundle)), }, @@ -268,19 +268,18 @@ func TestSupervisorLogin(t *testing.T) { requestAuthorization: func(t *testing.T, downstreamAuthorizeURL, _ string, httpClient *http.Client) { requestAuthorizationUsingLDAPIdentityProvider(t, downstreamAuthorizeURL, - env.SupervisorUpstreamActiveDirectory.TestUsernameAttributeName, // username to present to server during login - env.SupervisorUpstreamActiveDirectory.TestUserPassword, // password to present to server during login + env.SupervisorUpstreamActiveDirectory.TestUsernameAttributeValue, // username to present to server during login + env.SupervisorUpstreamActiveDirectory.TestUserPassword, // password to present to server during login httpClient, ) }, // the ID token Subject should be the Host URL plus the value pulled from the requested UserSearch.Attributes.UID attribute wantDownstreamIDTokenSubjectToMatch: regexp.QuoteMeta( "ldaps://" + env.SupervisorUpstreamActiveDirectory.Host + - "?base=" + url.QueryEscape(env.SupervisorUpstreamActiveDirectory.UserSearchBase) + "&sub=" + base64.RawURLEncoding.EncodeToString([]byte(env.SupervisorUpstreamActiveDirectory.TestUserUniqueIDAttributeValue)), ), // the ID token Username should have been pulled from the requested UserSearch.Attributes.Username attribute - wantDownstreamIDTokenUsernameToMatch: regexp.QuoteMeta(env.SupervisorUpstreamActiveDirectory.TestUserDN), + wantDownstreamIDTokenUsernameToMatch: regexp.QuoteMeta(env.SupervisorUpstreamActiveDirectory.TestUsernameAttributeValue), wantDownstreamIDTokenGroups: env.SupervisorUpstreamActiveDirectory.TestUserDirectGroupsCNs, }, } @@ -337,7 +336,7 @@ func requireSuccessfulActiveDirectoryIdentityProviderConditions(t *testing.T, ad require.Equal(t, "loaded bind secret", condition.Message) case "TLSConfigurationValid": require.Equal(t, "loaded TLS configuration", condition.Message) - case "LDAPConnectionValid": + case "ActiveDirectoryConnectionValid": require.Equal(t, expectedActiveDirectoryConnectionValidMessage, condition.Message) } } @@ -345,7 +344,7 @@ func requireSuccessfulActiveDirectoryIdentityProviderConditions(t *testing.T, ad require.ElementsMatch(t, [][]string{ {"BindSecretValid", "True", "Success"}, {"TLSConfigurationValid", "True", "Success"}, - {"LDAPConnectionValid", "True", "Success"}, + {"ActiveDirectoryConnectionValid", "True", "Success"}, }, conditionsSummary) } @@ -604,7 +603,7 @@ func requestAuthorizationUsingOIDCIdentityProvider(t *testing.T, downstreamAutho func requestAuthorizationUsingLDAPIdentityProvider(t *testing.T, downstreamAuthorizeURL, upstreamUsername, upstreamPassword string, httpClient *http.Client) { t.Helper() - ctx, cancelFunc := context.WithTimeout(context.Background(), time.Minute) + ctx, cancelFunc := context.WithTimeout(context.Background(), 2*time.Minute) defer cancelFunc() authRequest, err := http.NewRequestWithContext(ctx, http.MethodGet, downstreamAuthorizeURL, nil) @@ -635,7 +634,7 @@ func requestAuthorizationUsingLDAPIdentityProvider(t *testing.T, downstreamAutho return false, nil } return true, nil - }, 30*time.Second, 200*time.Millisecond) + }, 60*time.Second, 200*time.Millisecond) expectSecurityHeaders(t, authResponse, true) diff --git a/test/testlib/client.go b/test/testlib/client.go index a206c2d5..0cebe5ad 100644 --- a/test/testlib/client.go +++ b/test/testlib/client.go @@ -15,11 +15,12 @@ import ( "testing" "time" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "github.com/stretchr/testify/require" authorizationv1 "k8s.io/api/authorization/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" - k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -441,7 +442,7 @@ func CreateTestActiveDirectoryIdentityProvider(t *testing.T, spec idpv1alpha1.Ac ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() - // Create the LDAPIdentityProvider using GenerateName to get a random name. + // Create the ActiveDirectoryIdentityProvider using GenerateName to get a random name. upstreams := client.IDPV1alpha1().ActiveDirectoryIdentityProviders(env.SupervisorNamespace) created, err := upstreams.Create(ctx, &idpv1alpha1.ActiveDirectoryIdentityProvider{