diff --git a/builtin/logical/aws/path_roles_test.go b/builtin/logical/aws/path_roles_test.go index 09da6ee73b36..846b60d0ca92 100644 --- a/builtin/logical/aws/path_roles_test.go +++ b/builtin/logical/aws/path_roles_test.go @@ -5,11 +5,14 @@ package aws import ( "context" + "errors" "reflect" "strconv" "strings" "testing" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/vault/sdk/logical" ) @@ -366,22 +369,74 @@ func TestRoleEntryValidationIamUserCred(t *testing.T) { CredentialTypes: []string{iamUserCred}, RoleArns: []string{"arn:aws:iam::123456789012:role/SomeRole"}, } - if roleEntry.validate() == nil { - t.Errorf("bad: invalid roleEntry with invalid RoleArns parameter %#v passed validation", roleEntry) - } + assertMultiError(t, roleEntry.validate(), + []error{ + errors.New( + "cannot supply role_arns when credential_type isn't assumed_role", + ), + }) roleEntry = awsRoleEntry{ CredentialTypes: []string{iamUserCred}, PolicyArns: []string{adminAccessPolicyARN}, DefaultSTSTTL: 1, } - if roleEntry.validate() == nil { - t.Errorf("bad: invalid roleEntry with unrecognized DefaultSTSTTL %#v passed validation", roleEntry) - } + assertMultiError(t, roleEntry.validate(), + []error{ + errors.New( + "default_sts_ttl parameter only valid for assumed_role, federation_token, and session_token credential types", + ), + }) roleEntry.DefaultSTSTTL = 0 + roleEntry.MaxSTSTTL = 1 - if roleEntry.validate() == nil { - t.Errorf("bad: invalid roleEntry with unrecognized MaxSTSTTL %#v passed validation", roleEntry) + assertMultiError(t, roleEntry.validate(), + []error{ + errors.New( + "max_sts_ttl parameter only valid for assumed_role, federation_token, and session_token credential types", + ), + }) + roleEntry.MaxSTSTTL = 0 + + roleEntry.SessionTags = map[string]string{ + "Key1": "Value1", + "Key2": "Value2", + } + assertMultiError(t, roleEntry.validate(), + []error{ + errors.New( + "cannot supply session_tags when credential_type isn't assumed_role", + ), + }) + roleEntry.SessionTags = nil + + roleEntry.ExternalID = "my-ext-id" + assertMultiError(t, roleEntry.validate(), + []error{ + errors.New( + "cannot supply external_id when credential_type isn't assumed_role"), + }) +} + +func assertMultiError(t *testing.T, err error, expected []error) { + t.Helper() + + if err == nil { + t.Errorf("expected error, got nil") + return + } + + var multiErr *multierror.Error + if errors.As(err, &multiErr) { + if multiErr.Len() != len(expected) { + t.Errorf("expected %d error, got %d", len(expected), multiErr.Len()) + } else { + if !reflect.DeepEqual(expected, multiErr.Errors) { + t.Errorf("expected error %q, actual %q", expected, multiErr.Errors) + } + } + } else { + t.Errorf("expected multierror, got %T", err) } } diff --git a/builtin/logical/aws/secret_access_keys.go b/builtin/logical/aws/secret_access_keys.go index 0a126a6ed6af..5120dcb48a2d 100644 --- a/builtin/logical/aws/secret_access_keys.go +++ b/builtin/logical/aws/secret_access_keys.go @@ -14,6 +14,7 @@ import ( "github.com/aws/aws-sdk-go/service/sts" "github.com/hashicorp/errwrap" "github.com/hashicorp/go-secure-stdlib/awsutil" + "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/template" "github.com/hashicorp/vault/sdk/logical" @@ -298,13 +299,16 @@ func (b *backend) assumeRole(ctx context.Context, s logical.Storage, if externalID != "" { assumeRoleInput.SetExternalId(externalID) } - if len(sessionTags) > 0 { - var tags []*sts.Tag - for k, v := range sessionTags { - tags = append(tags, &sts.Tag{Key: aws.String(k), Value: aws.String(v)}) - } - assumeRoleInput.SetTags(tags) + var tags []*sts.Tag + for k, v := range sessionTags { + tags = append(tags, + &sts.Tag{ + Key: aws.String(k), + Value: aws.String(v), + }, + ) } + assumeRoleInput.SetTags(tags) tokenResp, err := stsClient.AssumeRoleWithContext(ctx, assumeRoleInput) if err != nil { return logical.ErrorResponse("Error assuming role: %s", err), awsutil.CheckAWSError(err)