test(e2e): Static/vault-generic Username-Password-Domain tests (#1538)

This commit is contained in:
Andrew Gaffney authored and irenarindos committed 2025-09-02 15:12:42 -04:00
1 parent 582efa2fd2
commit 822d1a7494
4 files changed
+177 -7

No files matched your search

@@ -238,6 +238,43 @@ func CreateStaticCredentialPasswordCli(t testing.TB, ctx context.Context, creden
return credentialId, nil
}
// CreateStaticCredentialPasswordDomainCli uses the cli to create a new username password domain credential in the
// provided static credential store.
// Returns the id of the new credential
func CreateStaticCredentialPasswordDomainCli(t testing.TB, ctx context.Context, credentialStoreId string, user string, password string, domain string) (string, error) {
name, err := base62.Random(16)
if err != nil {
return "", err
}
output := e2e.RunCommand(ctx, "boundary",
e2e.WithArgs(
"credentials", "create", "username-password-domain",
"-credential-store-id", credentialStoreId,
"-username", user,
"-password", "env://E2E_CREDENTIALS_PASSWORD",
"-domain", domain,
"-name", fmt.Sprintf("e2e Credential %s", name),
"-description", "e2e",
"-format", "json",
),
e2e.WithEnv("E2E_CREDENTIALS_PASSWORD", password),
)
if output.Err != nil {
return "", fmt.Errorf("%w: %s", output.Err, string(output.Stderr))
}
var createCredentialsResult credentials.CredentialCreateResult
err = json.Unmarshal(output.Stdout, &createCredentialsResult)
if err != nil {
return "", err
}
credentialId := createCredentialsResult.Item.Id
t.Logf("Created Username/Password/Domain Credentials: %s", credentialId)
return credentialId, nil
}
// CreateStaticCredentialJsonCli uses the cli to create a new json credential in the provided
// static credential store.
// Returns the id of the new credential
@@ -295,3 +332,28 @@ func CreateStaticCredentialPasswordApi(t testing.TB, ctx context.Context, client
t.Logf("Created Username/Password Credentials: %s", credentialId)
return credentialId, nil
}
// CreateStaticCredentialPasswordDomainApi uses the API to create a new username-password-domain credential in the
// provided static credential store.
// Returns the id of the new credential
func CreateStaticCredentialPasswordDomainApi(t testing.TB, ctx context.Context, client *api.Client, credentialStoreId string, user string, password string, domain string) (string, error) {
name, err := base62.Random(16)
if err != nil {
return "", err
}
c := credentials.NewClient(client)
createCredentialsResult, err := c.Create(ctx, "username_password_domain", credentialStoreId,
credentials.WithUsernamePasswordDomainCredentialUsername(user),
credentials.WithUsernamePasswordDomainCredentialPassword(password),
credentials.WithUsernamePasswordDomainCredentialDomain(domain),
credentials.WithName(fmt.Sprintf("e2e Credential %s", name)),
)
if err != nil {
return "", err
}
credentialId := createCredentialsResult.Item.Id
t.Logf("Created Username/Password/domain Credentials: %s", credentialId)
return credentialId, nil
}
@@ -30,6 +30,7 @@ const (
testCredentialsFile = "testdata/credential.json"
testPemFile = "testdata/private-key.pem"
testPassword = "password"
testDomain = "domain.com"
)
// TestCliStaticCredentialStore validates various credential-store operations using the cli
@@ -79,6 +80,8 @@ func TestCliStaticCredentialStore(t *testing.T) {
require.NoError(t, err)
jsonCredentialId, err := boundary.CreateStaticCredentialJsonCli(t, ctx, storeId, testCredentialsFile)
require.NoError(t, err)
updCredentialId, err := boundary.CreateStaticCredentialPasswordDomainCli(t, ctx, storeId, c.TargetSshUser, testPassword, testDomain)
require.NoError(t, err)
// Get credentials for target (expect empty)
output := e2e.RunCommand(ctx, "boundary",
@@ -97,6 +100,8 @@ func TestCliStaticCredentialStore(t *testing.T) {
require.NoError(t, err)
err = boundary.AddBrokeredCredentialSourceToTargetCli(t, ctx, targetId, pwCredentialId)
require.NoError(t, err)
err = boundary.AddBrokeredCredentialSourceToTargetCli(t, ctx, targetId, updCredentialId)
require.NoError(t, err)
// Get credentials for target
output = e2e.RunCommand(ctx, "boundary",
@@ -125,6 +130,7 @@ func TestCliStaticCredentialStore(t *testing.T) {
expectedCredentials := []map[string]any{
{"username": c.TargetSshUser, "password": testPassword},
{"username": c.TargetSshUser, "private_key": sshPrivateKey},
{"username": c.TargetSshUser, "password": testPassword, "domain": testDomain},
expectedJsonCredentials,
}
@@ -233,11 +239,15 @@ func TestApiStaticCredentialStore(t *testing.T) {
newCredentialsId := newCredentialsResult.Item.Id
t.Logf("Created Credentials: %s", newCredentialsId)
updCredentialId, err := boundary.CreateStaticCredentialPasswordDomainApi(t, ctx, client, storeId, c.TargetSshUser, testPassword, testDomain)
require.NoError(t, err)
t.Logf("Created Credentials: %s", updCredentialId)
// Add credentials to target
tClient := targets.NewClient(client)
_, err = tClient.AddCredentialSources(ctx, targetId, 0,
targets.WithAutomaticVersioning(true),
targets.WithBrokeredCredentialSourceIds([]string{newCredentialsId}),
targets.WithBrokeredCredentialSourceIds([]string{newCredentialsId, updCredentialId}),
)
require.NoError(t, err)
@@ -249,7 +259,16 @@ func TestApiStaticCredentialStore(t *testing.T) {
require.True(t, ok)
retrievedKey, ok := newSessionAuthorization.Credentials[0].Credential["private_key"].(string)
require.True(t, ok)
retrievedDomainUser, ok := newSessionAuthorization.Credentials[1].Credential["username"].(string)
require.True(t, ok)
retrievedDomainPW, ok := newSessionAuthorization.Credentials[1].Credential["password"].(string)
require.True(t, ok)
retrievedDomain, ok := newSessionAuthorization.Credentials[1].Credential["domain"].(string)
require.True(t, ok)
assert.Equal(t, c.TargetSshUser, retrievedUser)
assert.Equal(t, c.TargetSshUser, retrievedDomainUser)
assert.Equal(t, testPassword, retrievedDomainPW)
assert.Equal(t, testDomain, retrievedDomain)
require.Equal(t, string(k), retrievedKey)
t.Log("Successfully retrieved credentials for target")
}
@@ -76,6 +76,7 @@ func TestCliVaultCredentialStore(t *testing.T) {
// Create credentials in vault
privateKeySecretName := vault.CreateKvPrivateKeyCredential(t, c.VaultSecretPath, c.TargetSshUser, c.TargetSshKeyPath, kvPolicyFilePath)
passwordSecretName, password := vault.CreateKvPasswordCredential(t, c.VaultSecretPath, c.TargetSshUser, kvPolicyFilePath)
domainSecretName, domainPassword := vault.CreateKvPasswordDomainCredential(t, c.VaultSecretPath, c.TargetSshUser, "domain.com", kvPolicyFilePath)
kvPolicyName := vault.WritePolicy(t, ctx, kvPolicyFilePath)
t.Cleanup(func() {
output := e2e.RunCommand(ctx, "vault",
@@ -129,6 +130,16 @@ func TestCliVaultCredentialStore(t *testing.T) {
)
require.NoError(t, err)
// Create a credential library for the Domain
domainCredentialLibraryId, err := boundary.CreateVaultGenericCredentialLibraryCli(
t,
ctx,
storeId,
fmt.Sprintf("%s/data/%s", c.VaultSecretPath, domainSecretName),
"username_password_domain",
)
require.NoError(t, err)
// Get credentials for target (expect empty)
output = e2e.RunCommand(ctx, "boundary",
e2e.WithArgs("targets", "authorize-session", "-id", targetId, "-format", "json"),
@@ -144,6 +155,8 @@ func TestCliVaultCredentialStore(t *testing.T) {
require.NoError(t, err)
err = boundary.AddBrokeredCredentialSourceToTargetCli(t, ctx, targetId, passwordCredentialLibraryId)
require.NoError(t, err)
err = boundary.AddBrokeredCredentialSourceToTargetCli(t, ctx, targetId, domainCredentialLibraryId)
require.NoError(t, err)
// Get credentials for target
output = e2e.RunCommand(ctx, "boundary",
@@ -154,10 +167,11 @@ func TestCliVaultCredentialStore(t *testing.T) {
require.NoError(t, err)
newSessionAuthorization := newSessionAuthorizationResult.Item
require.Len(t, newSessionAuthorization.Credentials, 2)
require.Len(t, newSessionAuthorization.Credentials, 3)
for _, v := range newSessionAuthorization.Credentials {
if v.CredentialSource.CredentialType == "ssh_private_key" {
switch v.CredentialSource.CredentialType {
case "ssh_private_key":
retrievedUser, ok := v.Credential["username"].(string)
require.True(t, ok)
retrievedKey, ok := v.Credential["private_key"].(string)
@@ -168,7 +182,7 @@ func TestCliVaultCredentialStore(t *testing.T) {
require.NoError(t, err)
require.Equal(t, string(keyData), retrievedKey)
t.Log("Successfully retrieved private key credentials for target")
} else if v.CredentialSource.CredentialType == "username_password" {
case "username_password":
retrievedUser, ok := v.Credential["username"].(string)
require.True(t, ok)
retrievedPassword, ok := v.Credential["password"].(string)
@@ -176,6 +190,17 @@ func TestCliVaultCredentialStore(t *testing.T) {
assert.Equal(t, c.TargetSshUser, retrievedUser)
assert.Equal(t, password, retrievedPassword)
t.Log("Successfully retrieved password credentials for target")
case "username_password_domain":
retrievedUser, ok := v.Credential["username"].(string)
require.True(t, ok)
retrievedPassword, ok := v.Credential["password"].(string)
require.True(t, ok)
retrievedDomain, ok := v.Credential["domain"].(string)
require.True(t, ok)
assert.Equal(t, c.TargetSshUser, retrievedUser)
assert.Equal(t, domainPassword, retrievedPassword)
assert.Equal(t, "domain.com", retrievedDomain)
t.Log("Successfully retrieved username/password/domain credentials for target")
}
}
}
@@ -229,6 +254,7 @@ func TestApiVaultCredentialStore(t *testing.T) {
// Create credential in vault
privateKeySecretName := vault.CreateKvPrivateKeyCredential(t, c.VaultSecretPath, c.TargetSshUser, c.TargetSshKeyPath, kvPolicyFilePath)
passwordSecretName, password := vault.CreateKvPasswordCredential(t, c.VaultSecretPath, c.TargetSshUser, kvPolicyFilePath)
domainSecretName, domainPassword := vault.CreateKvPasswordDomainCredential(t, c.VaultSecretPath, c.TargetSshUser, "domain.com", kvPolicyFilePath)
kvPolicyName := vault.WritePolicy(t, ctx, kvPolicyFilePath)
t.Log("Created Vault Credentials")
@@ -281,6 +307,15 @@ func TestApiVaultCredentialStore(t *testing.T) {
newPasswordCredentialLibraryId := newCredentialLibraryResult.Item.Id
t.Logf("Created Credential Library: %s", newPasswordCredentialLibraryId)
// Create a credential library for the domain
newCredentialLibraryResult, err = clClient.Create(ctx, "vault-generic", newCredentialStoreId,
credentiallibraries.WithVaultCredentialLibraryPath(c.VaultSecretPath+"/data/"+domainSecretName),
credentiallibraries.WithCredentialType("username_password_domain"),
)
require.NoError(t, err)
newDomainCredentialLibraryId := newCredentialLibraryResult.Item.Id
t.Logf("Created Credential Library: %s", newDomainCredentialLibraryId)
// Add private key brokered credentials to target
tClient := targets.NewClient(client)
_, err = tClient.AddCredentialSources(ctx, targetId, 0,
@@ -296,14 +331,22 @@ func TestApiVaultCredentialStore(t *testing.T) {
)
require.NoError(t, err)
// Add password brokered credentials to target
_, err = tClient.AddCredentialSources(ctx, targetId, 0,
targets.WithBrokeredCredentialSourceIds([]string{newDomainCredentialLibraryId}),
targets.WithAutomaticVersioning(true),
)
require.NoError(t, err)
// Get credentials for target
newSessionAuthorizationResult, err := tClient.AuthorizeSession(ctx, targetId)
require.NoError(t, err)
newSessionAuthorization := newSessionAuthorizationResult.Item
require.Len(t, newSessionAuthorization.Credentials, 2)
require.Len(t, newSessionAuthorization.Credentials, 3)
for _, v := range newSessionAuthorization.Credentials {
if v.CredentialSource.CredentialType == "ssh_private_key" {
switch v.CredentialSource.CredentialType {
case "ssh_private_key":
retrievedUser, ok := v.Credential["username"].(string)
require.True(t, ok)
assert.Equal(t, c.TargetSshUser, retrievedUser)
@@ -315,7 +358,8 @@ func TestApiVaultCredentialStore(t *testing.T) {
keysMatch := string(k) == retrievedKey // This is done to prevent printing out key info
require.True(t, keysMatch, "Key retrieved from vault does not match expected value")
t.Log("Successfully retrieved credentials for target")
} else if v.CredentialSource.CredentialType == "username_password" {
case "username_password":
retrievedUser, ok := v.Credential["username"].(string)
require.True(t, ok)
retrievedPassword, ok := v.Credential["password"].(string)
@@ -323,6 +367,18 @@ func TestApiVaultCredentialStore(t *testing.T) {
assert.Equal(t, c.TargetSshUser, retrievedUser)
assert.Equal(t, password, retrievedPassword)
t.Log("Successfully retrieved password credentials for target")
case "username_password_domain":
retrievedUser, ok := v.Credential["username"].(string)
require.True(t, ok)
retrievedPassword, ok := v.Credential["password"].(string)
require.True(t, ok)
retrievedDomain, ok := v.Credential["domain"].(string)
require.True(t, ok)
assert.Equal(t, c.TargetSshUser, retrievedUser)
assert.Equal(t, domainPassword, retrievedPassword)
assert.Equal(t, "domain.com", retrievedDomain)
t.Log("Successfully retrieved username/password/domain credentials for target")
}
}
}
+33
View File
@@ -101,6 +101,39 @@ func CreateKvPasswordCredential(t testing.TB, secretPath string, user string, kv
return
}
// CreateKvPasswordDomainCredential creates a username/password/domain credential in vault and creates a vault
// policy to be able to read that credential. Returns the name of the policy
func CreateKvPasswordDomainCredential(t testing.TB, secretPath string, user string, domain string, kvPolicyFilePath string) (secretName string, password string) {
secretName, err := base62.Random(16)
require.NoError(t, err)
// Update policy file
f, err := os.OpenFile(kvPolicyFilePath, os.O_APPEND|os.O_WRONLY, 0o644)
require.NoError(t, err)
_, err = f.WriteString(fmt.Sprintf("path \"%s/data/%s\" { capabilities = [\"read\"] }\n",
secretPath,
secretName,
))
require.NoError(t, err)
// Create secret
password, err = base62.Random(16)
require.NoError(t, err)
output := e2e.RunCommand(context.Background(), "vault",
e2e.WithArgs(
"kv", "put",
"-mount", secretPath,
secretName,
"username="+user,
"password="+password,
"domain="+domain,
),
)
require.NoError(t, output.Err, string(output.Stderr))
return
}
// WritePolicy adds a policy to vault. Provide a name for the policy that you want to create as well
// as the path to the file that contains the policy definition. Returns a policy name
func WritePolicy(t testing.TB, ctx context.Context, policyFilePath string) string {