mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-11-04 04:28:08 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			210 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			210 lines
		
	
	
		
			6.2 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{}
 | 
						|
	config.System = &testSystemView{}
 | 
						|
 | 
						|
	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{}
 | 
						|
	config.System = &testSystemView{}
 | 
						|
 | 
						|
	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,
 | 
						|
		)
 | 
						|
	}
 | 
						|
}
 |