mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-11 00:57:00 +02:00
* Adding explicit MPL license for sub-package. This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Adding explicit MPL license for sub-package. This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Updating the license from MPL to Business Source License. Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at https://hashi.co/bsl-blog, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl. * add missing license headers * Update copyright file headers to BUS-1.1 * Fix test that expected exact offset on hcl file --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> Co-authored-by: Sarah Thompson <sthompson@hashicorp.com> Co-authored-by: Brian Kassouf <bkassouf@hashicorp.com>
206 lines
6.1 KiB
Go
206 lines
6.1 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package aws
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/vault/sdk/logical"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestNormalizeDisplayName_NormRequired(t *testing.T) {
|
|
invalidNames := map[string]string{
|
|
"^#$test name\nshould be normalized)(*": "___test_name_should_be_normalized___",
|
|
"^#$test name1 should be normalized)(*": "___test_name1_should_be_normalized___",
|
|
"^#$test name should be normalized)(*": "___test_name__should_be_normalized___",
|
|
"^#$test name__should be normalized)(*": "___test_name__should_be_normalized___",
|
|
}
|
|
|
|
for k, v := range invalidNames {
|
|
normalizedName := normalizeDisplayName(k)
|
|
if normalizedName != v {
|
|
t.Fatalf(
|
|
"normalizeDisplayName does not normalize AWS name correctly: %s should resolve to %s",
|
|
k,
|
|
normalizedName)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNormalizeDisplayName_NormNotRequired(t *testing.T) {
|
|
validNames := []string{
|
|
"test_name_should_normalize_to_itself@example.com",
|
|
"test1_name_should_normalize_to_itself@example.com",
|
|
"UPPERlower0123456789-_,.@example.com",
|
|
}
|
|
|
|
for _, n := range validNames {
|
|
normalizedName := normalizeDisplayName(n)
|
|
if normalizedName != n {
|
|
t.Fatalf(
|
|
"normalizeDisplayName erroneously normalizes valid names: expected %s but normalized to %s",
|
|
n,
|
|
normalizedName)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGenUsername(t *testing.T) {
|
|
type testCase struct {
|
|
name string
|
|
policy string
|
|
userType string
|
|
UsernameTemplate string
|
|
expectedError string
|
|
expectedRegex string
|
|
expectedLength int
|
|
}
|
|
|
|
tests := map[string]testCase{
|
|
"Truncated to 64. No warnings expected": {
|
|
name: "name1",
|
|
policy: "policy1",
|
|
userType: "iam_user",
|
|
UsernameTemplate: defaultUserNameTemplate,
|
|
expectedError: "",
|
|
expectedRegex: `^vault-name1-policy1-[0-9]+-[a-zA-Z0-9]+`,
|
|
expectedLength: 64,
|
|
},
|
|
"Truncated to 32. No warnings expected": {
|
|
name: "name1",
|
|
policy: "policy1",
|
|
userType: "sts",
|
|
UsernameTemplate: defaultUserNameTemplate,
|
|
expectedError: "",
|
|
expectedRegex: `^vault-[0-9]+-[a-zA-Z0-9]+`,
|
|
expectedLength: 32,
|
|
},
|
|
"Too long. Error expected — IAM": {
|
|
name: "this---is---a---very---long---name",
|
|
policy: "long------policy------name",
|
|
userType: "assume_role",
|
|
UsernameTemplate: `{{ if (eq .Type "IAM") }}{{ printf "%s-%s-%s-%s" (.DisplayName) (.PolicyName) (unix_time) (random 20) }}{{ end }}`,
|
|
expectedError: "the username generated by the template exceeds the IAM username length limits of 64 chars",
|
|
expectedRegex: "",
|
|
expectedLength: 64,
|
|
},
|
|
"Too long. Error expected — STS": {
|
|
name: "this---is---a---very---long---name",
|
|
policy: "long------policy------name",
|
|
userType: "sts",
|
|
UsernameTemplate: `{{ if (eq .Type "STS") }}{{ printf "%s-%s-%s-%s" (.DisplayName) (.PolicyName) (unix_time) (random 20) }}{{ end }}`,
|
|
expectedError: "the username generated by the template exceeds the STS username length limits of 32 chars",
|
|
expectedRegex: "",
|
|
expectedLength: 32,
|
|
},
|
|
}
|
|
|
|
for testDescription, testCase := range tests {
|
|
t.Run(testDescription, func(t *testing.T) {
|
|
testUsername, err := genUsername(testCase.name, testCase.policy, testCase.userType, testCase.UsernameTemplate)
|
|
if err != nil && !strings.Contains(err.Error(), testCase.expectedError) {
|
|
t.Fatalf("expected an error %s; instead received %s", testCase.expectedError, err)
|
|
}
|
|
|
|
if err == nil {
|
|
require.Regexp(t, testCase.expectedRegex, testUsername)
|
|
|
|
if len(testUsername) > testCase.expectedLength {
|
|
t.Fatalf("expected username to be of length %d, got %d", testCase.expectedLength, len(testUsername))
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReadConfig_DefaultTemplate(t *testing.T) {
|
|
config := logical.TestBackendConfig()
|
|
config.StorageView = &logical.InmemStorage{}
|
|
b := Backend(config)
|
|
if err := b.Setup(context.Background(), config); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testTemplate := ""
|
|
configData := map[string]interface{}{
|
|
"connection_uri": "test_uri",
|
|
"username": "guest",
|
|
"password": "guest",
|
|
"username_template": testTemplate,
|
|
}
|
|
configReq := &logical.Request{
|
|
Operation: logical.UpdateOperation,
|
|
Path: "config/root",
|
|
Storage: config.StorageView,
|
|
Data: configData,
|
|
}
|
|
resp, err := b.HandleRequest(context.Background(), configReq)
|
|
if err != nil || (resp != nil && resp.IsError()) {
|
|
t.Fatalf("bad: resp: %#v\nerr:%s", resp, err)
|
|
}
|
|
if resp != nil {
|
|
t.Fatal("expected a nil response")
|
|
}
|
|
|
|
configResult, err := readConfig(context.Background(), config.StorageView)
|
|
if err != nil {
|
|
t.Fatalf("expected err to be nil; got %s", err)
|
|
}
|
|
|
|
// No template provided, config set to defaultUsernameTemplate
|
|
if configResult.UsernameTemplate != defaultUserNameTemplate {
|
|
t.Fatalf(
|
|
"expected template %s; got %s",
|
|
defaultUserNameTemplate,
|
|
configResult.UsernameTemplate,
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestReadConfig_CustomTemplate(t *testing.T) {
|
|
config := logical.TestBackendConfig()
|
|
config.StorageView = &logical.InmemStorage{}
|
|
b := Backend(config)
|
|
if err := b.Setup(context.Background(), config); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testTemplate := "`foo-{{ .DisplayName }}`"
|
|
configData := map[string]interface{}{
|
|
"connection_uri": "test_uri",
|
|
"username": "guest",
|
|
"password": "guest",
|
|
"username_template": testTemplate,
|
|
}
|
|
configReq := &logical.Request{
|
|
Operation: logical.UpdateOperation,
|
|
Path: "config/root",
|
|
Storage: config.StorageView,
|
|
Data: configData,
|
|
}
|
|
resp, err := b.HandleRequest(context.Background(), configReq)
|
|
if err != nil || (resp != nil && resp.IsError()) {
|
|
t.Fatalf("bad: resp: %#v\nerr:%s", resp, err)
|
|
}
|
|
if resp != nil {
|
|
t.Fatal("expected a nil response")
|
|
}
|
|
|
|
configResult, err := readConfig(context.Background(), config.StorageView)
|
|
if err != nil {
|
|
t.Fatalf("expected err to be nil; got %s", err)
|
|
}
|
|
|
|
if configResult.UsernameTemplate != testTemplate {
|
|
t.Fatalf(
|
|
"expected template %s; got %s",
|
|
testTemplate,
|
|
configResult.UsernameTemplate,
|
|
)
|
|
}
|
|
}
|