2023-06-05 09:52:48 -07:00
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
2023-03-20 11:02:17 -07:00
package credential
2021-09-30 17:05:27 -07:00
import (
2021-10-05 16:36:53 -07:00
"errors"
"fmt"
2021-09-30 17:05:27 -07:00
"testing"
"time"
2021-10-05 16:36:53 -07:00
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/hashicorp/go-secure-stdlib/awsutil"
2021-09-30 17:05:27 -07:00
"github.com/stretchr/testify/require"
2023-03-20 11:02:17 -07:00
"google.golang.org/protobuf/types/known/structpb"
2021-09-30 17:05:27 -07:00
)
2023-03-20 11:02:17 -07:00
func TestNewAwsCredentialPersistedState ( t * testing . T ) {
2021-10-06 12:47:05 -07:00
staticTime := time . Now ()
cases := [] struct {
name string
2023-03-20 11:02:17 -07:00
opts [] AwsCredentialPersistedStateOption
expected * AwsCredentialPersistedState
2021-10-06 12:47:05 -07:00
expectedErr string
}{
{
name : "error" ,
2023-03-20 11:02:17 -07:00
opts : [] AwsCredentialPersistedStateOption {
func ( s * AwsCredentialPersistedState ) error {
2021-10-06 12:47:05 -07:00
return errors . New ( testOptionErr )
},
},
expectedErr : testOptionErr ,
},
{
2023-07-18 16:33:24 -07:00
name : "with credentials config" ,
2023-03-20 11:02:17 -07:00
opts : [] AwsCredentialPersistedStateOption {
2023-07-18 16:33:24 -07:00
WithCredentialsConfig (
& awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
Region : "us-west-2" ,
},
),
2021-10-06 12:47:05 -07:00
},
2023-03-20 11:02:17 -07:00
expected : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
Region : "us-west-2" ,
},
2021-10-06 12:47:05 -07:00
},
},
{
name : "rotation time" ,
2023-03-20 11:02:17 -07:00
opts : [] AwsCredentialPersistedStateOption {
WithCredsLastRotatedTime ( staticTime ),
2021-10-06 12:47:05 -07:00
},
2023-03-20 11:02:17 -07:00
expected : & AwsCredentialPersistedState {
2021-10-06 12:47:05 -07:00
CredsLastRotatedTime : staticTime ,
},
},
2022-09-02 14:35:34 -04:00
{
2023-07-18 16:33:24 -07:00
name : "double set credentials config" ,
2023-03-20 11:02:17 -07:00
opts : [] AwsCredentialPersistedStateOption {
2023-07-18 16:33:24 -07:00
WithCredentialsConfig ( & awsutil . CredentialsConfig {}),
WithCredentialsConfig ( & awsutil . CredentialsConfig {}),
2022-09-02 14:35:34 -04:00
},
2023-07-18 16:33:24 -07:00
expectedErr : "credentials config already set" ,
2021-10-06 12:47:05 -07:00
},
{
2022-09-02 14:35:34 -04:00
name : "double set rotation time" ,
2023-03-20 11:02:17 -07:00
opts : [] AwsCredentialPersistedStateOption {
WithCredsLastRotatedTime ( staticTime ),
WithCredsLastRotatedTime ( time . Now ()),
2021-10-06 12:47:05 -07:00
},
expectedErr : "last rotation time already set" ,
},
}
for _ , tc := range cases {
tc := tc
t . Run ( tc . name , func ( t * testing . T ) {
require := require . New ( t )
2023-03-20 11:02:17 -07:00
actual , err := NewAwsCredentialPersistedState ( tc . opts ... )
2021-10-06 12:47:05 -07:00
if tc . expectedErr != "" {
require . EqualError ( err , tc . expectedErr )
return
}
require . NoError ( err )
2023-07-18 16:33:24 -07:00
require . Equal ( tc . expected . CredsLastRotatedTime , actual . CredsLastRotatedTime )
if tc . expected . CredentialsConfig != nil {
require . NotNil ( actual . CredentialsConfig )
require . Equal ( tc . expected . CredentialsConfig . AccessKey , actual . CredentialsConfig . AccessKey )
require . Equal ( tc . expected . CredentialsConfig . SecretKey , actual . CredentialsConfig . SecretKey )
require . Equal ( tc . expected . CredentialsConfig . Region , actual . CredentialsConfig . Region )
}
2021-10-06 12:47:05 -07:00
})
}
}
2023-03-20 11:02:17 -07:00
func TestAwsCredentialPersistedStateFromProto ( t * testing . T ) {
2021-09-30 17:05:27 -07:00
cases := [] struct {
name string
2023-07-18 16:33:24 -07:00
secrets * structpb . Struct
attrs * CredentialAttributes
2023-03-20 11:02:17 -07:00
opts [] AwsCredentialPersistedStateOption
expected * AwsCredentialPersistedState
2021-09-30 17:05:27 -07:00
expectedErr string
}{
{
2023-07-18 16:33:24 -07:00
name : "missing credential attributes" ,
expectedErr : "missing credential attributes" ,
},
{
name : "missing secrets" ,
attrs : & CredentialAttributes {
Region : "us-west-2" ,
},
expected : & AwsCredentialPersistedState {
CredentialsConfig : & awsutil . CredentialsConfig {
Region : "us-west-2" ,
},
},
2021-09-30 17:05:27 -07:00
},
{
2023-07-18 16:33:24 -07:00
name : "missing long-term access key id" ,
secrets : & structpb . Struct {},
attrs : & CredentialAttributes {
Region : "us-west-2" ,
},
expected : & AwsCredentialPersistedState {
CredentialsConfig : & awsutil . CredentialsConfig {
Region : "us-west-2" ,
},
},
2021-09-30 17:05:27 -07:00
},
{
2023-07-18 16:33:24 -07:00
name : "missing long-term secret access key" ,
secrets : & structpb . Struct {},
attrs : & CredentialAttributes {
Region : "us-west-2" ,
},
expected : & AwsCredentialPersistedState {
CredentialsConfig : & awsutil . CredentialsConfig {
Region : "us-west-2" ,
},
},
},
{
name : "with long-term static credentials" ,
secrets : & structpb . Struct {
Fields : map [ string ] * structpb . Value {
ConstAccessKeyId : structpb . NewStringValue ( "foobar" ),
ConstSecretAccessKey : structpb . NewStringValue ( "bazqux" ),
},
},
attrs : & CredentialAttributes {
Region : "us-west-2" ,
},
expected : & AwsCredentialPersistedState {
CredentialsConfig : & awsutil . CredentialsConfig {
Region : "us-west-2" ,
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
},
2021-09-30 17:05:27 -07:00
},
},
{
name : "bad last rotated time" ,
2023-07-18 16:33:24 -07:00
secrets : & structpb . Struct {
Fields : map [ string ] * structpb . Value {
ConstAccessKeyId : structpb . NewStringValue ( "foobar" ),
ConstSecretAccessKey : structpb . NewStringValue ( "bazqux" ),
ConstCredsLastRotatedTime : structpb . NewStringValue ( "notatime" ),
},
},
attrs : & CredentialAttributes {
Region : "us-west-2" ,
2021-09-30 17:05:27 -07:00
},
expectedErr : "persisted state integrity error: could not parse time in value \"creds_last_rotated_time\": parsing time \"notatime\" as \"2006-01-02T15:04:05.999999999Z07:00\": cannot parse \"notatime\" as \"2006\"" ,
},
2021-10-06 12:47:05 -07:00
{
name : "option error" ,
2023-07-18 16:33:24 -07:00
secrets : & structpb . Struct {
Fields : map [ string ] * structpb . Value {
ConstAccessKeyId : structpb . NewStringValue ( "foobar" ),
ConstSecretAccessKey : structpb . NewStringValue ( "bazqux" ),
ConstCredsLastRotatedTime : structpb . NewStringValue ( "2006-01-02T15:04:05+07:00" ),
},
},
attrs : & CredentialAttributes {
Region : "us-west-2" ,
2023-03-20 11:02:17 -07:00
},
opts : [] AwsCredentialPersistedStateOption {
func ( s * AwsCredentialPersistedState ) error {
2021-10-06 12:47:05 -07:00
return errors . New ( testOptionErr )
},
},
expectedErr : testOptionErr ,
},
2021-09-30 17:05:27 -07:00
{
name : "good with non-zero timestamp" ,
2023-07-18 16:33:24 -07:00
secrets : & structpb . Struct {
Fields : map [ string ] * structpb . Value {
ConstAccessKeyId : structpb . NewStringValue ( "foobar" ),
ConstSecretAccessKey : structpb . NewStringValue ( "bazqux" ),
ConstCredsLastRotatedTime : structpb . NewStringValue ( "2006-01-02T15:04:05+07:00" ),
},
},
attrs : & CredentialAttributes {
Region : "us-west-2" ,
2023-03-20 11:02:17 -07:00
},
expected : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
Region : "us-west-2" ,
},
2021-09-30 17:05:27 -07:00
CredsLastRotatedTime : func () time . Time {
t , err := time . Parse ( time . RFC3339 , "2006-01-02T15:04:05+07:00" )
if err != nil {
panic ( err )
}
return t
}(),
},
},
{
name : "good with zero timestamp" ,
2023-07-18 16:33:24 -07:00
secrets : & structpb . Struct {
Fields : map [ string ] * structpb . Value {
ConstAccessKeyId : structpb . NewStringValue ( "foobar" ),
ConstSecretAccessKey : structpb . NewStringValue ( "bazqux" ),
ConstCredsLastRotatedTime : structpb . NewStringValue (( time . Time {}). Format ( time . RFC3339Nano )),
},
},
attrs : & CredentialAttributes {
Region : "us-west-2" ,
2021-09-30 17:05:27 -07:00
},
2023-03-20 11:02:17 -07:00
expected : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
Region : "us-west-2" ,
},
2021-10-06 12:47:05 -07:00
CredsLastRotatedTime : time . Time {},
},
},
2021-10-05 16:36:53 -07:00
{
2023-07-18 16:33:24 -07:00
name : "with assume role" ,
attrs : & CredentialAttributes {
Region : "us-west-2" ,
RoleArn : "arn:aws:iam::123456789012:role/S3Access" ,
RoleExternalId : "1234567890" ,
RoleSessionName : "test-session" ,
RoleTags : map [ string ] string {
"foo" : "bar" ,
},
2021-10-05 16:36:53 -07:00
},
2023-07-18 16:33:24 -07:00
expected : & AwsCredentialPersistedState {
CredentialsConfig : & awsutil . CredentialsConfig {
Region : "us-west-2" ,
RoleARN : "arn:aws:iam::123456789012:role/S3Access" ,
RoleExternalId : "1234567890" ,
RoleSessionName : "test-session" ,
RoleTags : map [ string ] string {
"foo" : "bar" ,
},
},
},
},
{
name : "with assume role & static credentials" ,
secrets : & structpb . Struct {
Fields : map [ string ] * structpb . Value {
ConstAccessKeyId : structpb . NewStringValue ( "foobar" ),
ConstSecretAccessKey : structpb . NewStringValue ( "bazqux" ),
ConstCredsLastRotatedTime : structpb . NewStringValue (( time . Time {}). Format ( time . RFC3339Nano )),
},
},
attrs : & CredentialAttributes {
Region : "us-west-2" ,
RoleArn : "arn:aws:iam::123456789012:role/S3Access" ,
RoleExternalId : "1234567890" ,
RoleSessionName : "test-session" ,
RoleTags : map [ string ] string {
"foo" : "bar" ,
},
2021-10-05 16:36:53 -07:00
},
2023-03-20 11:02:17 -07:00
expected : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
Region : "us-west-2" ,
RoleARN : "arn:aws:iam::123456789012:role/S3Access" ,
RoleExternalId : "1234567890" ,
RoleSessionName : "test-session" ,
RoleTags : map [ string ] string {
"foo" : "bar" ,
},
},
2021-10-05 16:36:53 -07:00
CredsLastRotatedTime : time . Time {},
},
},
}
for _ , tc := range cases {
tc := tc
t . Run ( tc . name , func ( t * testing . T ) {
require := require . New ( t )
2023-03-20 11:02:17 -07:00
2023-07-18 16:33:24 -07:00
actual , err := AwsCredentialPersistedStateFromProto ( tc . secrets , tc . attrs , tc . opts ... )
2021-10-05 16:36:53 -07:00
if tc . expectedErr != "" {
require . EqualError ( err , tc . expectedErr )
return
}
require . NoError ( err )
2023-07-18 16:33:24 -07:00
require . NotNil ( actual )
require . Equal ( tc . expected . CredsLastRotatedTime , actual . CredsLastRotatedTime )
if tc . expected . CredentialsConfig != nil {
require . NotNil ( actual . CredentialsConfig )
require . Equal ( tc . expected . CredentialsConfig . AccessKey , actual . CredentialsConfig . AccessKey )
require . Equal ( tc . expected . CredentialsConfig . SecretKey , actual . CredentialsConfig . SecretKey )
require . Equal ( tc . expected . CredentialsConfig . Region , actual . CredentialsConfig . Region )
require . Equal ( tc . expected . CredentialsConfig . RoleARN , actual . CredentialsConfig . RoleARN )
require . Equal ( tc . expected . CredentialsConfig . RoleExternalId , actual . CredentialsConfig . RoleExternalId )
require . Equal ( tc . expected . CredentialsConfig . RoleSessionName , actual . CredentialsConfig . RoleSessionName )
require . Equal ( tc . expected . CredentialsConfig . RoleTags , actual . CredentialsConfig . RoleTags )
}
2021-10-05 16:36:53 -07:00
})
}
}
2023-07-18 16:33:24 -07:00
func TestAwsCatalogPersistedState_ValidateCreds ( t * testing . T ) {
2021-10-05 16:36:53 -07:00
cases := [] struct {
name string
2023-03-20 11:02:17 -07:00
in * AwsCredentialPersistedState
2021-10-05 16:36:53 -07:00
expectedErr string
}{
{
2023-07-18 16:33:24 -07:00
name : "missing credentials config" ,
in : & AwsCredentialPersistedState {},
expectedErr : "missing credentials config" ,
2021-10-05 16:36:53 -07:00
},
{
name : "validation error" ,
2023-03-20 11:02:17 -07:00
in : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
Region : "us-west-2" ,
},
testOpts : [] awsutil . Option {
awsutil . WithSTSAPIFunc (
awsutil . NewMockSTS (
awsutil . WithGetCallerIdentityError ( errors . New ( testGetCallerIdentityErr )),
),
),
},
2021-10-05 16:36:53 -07:00
},
expectedErr : fmt . Sprintf ( "error validating credentials: %s" , testGetCallerIdentityErr ),
},
{
name : "good" ,
2023-03-20 11:02:17 -07:00
in : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
Region : "us-west-2" ,
},
testOpts : [] awsutil . Option { awsutil . WithSTSAPIFunc ( awsutil . NewMockSTS ())},
2021-10-05 16:36:53 -07:00
},
},
}
for _ , tc := range cases {
tc := tc
t . Run ( tc . name , func ( t * testing . T ) {
require := require . New ( t )
err := tc . in . ValidateCreds ()
if tc . expectedErr != "" {
require . EqualError ( err , tc . expectedErr )
return
}
require . NoError ( err )
})
}
}
2023-07-18 16:33:24 -07:00
func TestAwsCatalogPersistedState_RotateCreds ( t * testing . T ) {
2021-10-05 16:36:53 -07:00
cases := [] struct {
name string
2023-03-20 11:02:17 -07:00
in * AwsCredentialPersistedState
2023-07-18 16:33:24 -07:00
exepected * awsutil . CredentialsConfig
2021-10-05 16:36:53 -07:00
expectedNonZeroRotatedTime bool
expectedErr string
}{
{
2023-07-18 16:33:24 -07:00
name : "missing credentials config" ,
in : & AwsCredentialPersistedState {},
expectedErr : "missing credentials config" ,
2021-10-05 16:36:53 -07:00
},
{
name : "rotation error" ,
2023-03-20 11:02:17 -07:00
in : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
Region : "us-west-2" ,
},
2021-10-05 16:36:53 -07:00
testOpts : [] awsutil . Option {
awsutil . WithIAMAPIFunc (
awsutil . NewMockIAM (
awsutil . WithGetUserError ( errors . New ( testGetUserErr )),
),
),
},
},
expectedErr : fmt . Sprintf ( "error rotating credentials: error calling CreateAccessKey: error calling aws.GetUser: %s" , testGetUserErr ),
},
{
name : "good" ,
2023-03-20 11:02:17 -07:00
in : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
Region : "us-west-2" ,
},
2021-10-05 16:36:53 -07:00
testOpts : [] awsutil . Option {
awsutil . WithSTSAPIFunc (
awsutil . NewMockSTS (),
),
awsutil . WithIAMAPIFunc (
awsutil . NewMockIAM (
awsutil . WithGetUserOutput (
& iam . GetUserOutput {
User : & iam . User {
Arn : aws . String ( "arn:aws:iam::123456789012:user/JohnDoe" ),
UserId : aws . String ( "AIDAJQABLZS4A3QDU576Q" ),
UserName : aws . String ( "JohnDoe" ),
},
},
),
awsutil . WithCreateAccessKeyOutput (
& iam . CreateAccessKeyOutput {
AccessKey : & iam . AccessKey {
AccessKeyId : aws . String ( "one" ),
SecretAccessKey : aws . String ( "two" ),
UserName : aws . String ( "JohnDoe" ),
},
},
),
),
),
},
},
2023-07-18 16:33:24 -07:00
exepected : & awsutil . CredentialsConfig {
AccessKey : "one" ,
SecretKey : "two" ,
Region : "us-west-2" ,
},
2021-10-05 16:36:53 -07:00
expectedNonZeroRotatedTime : true ,
},
}
for _ , tc := range cases {
tc := tc
t . Run ( tc . name , func ( t * testing . T ) {
require := require . New ( t )
err := tc . in . RotateCreds ()
if tc . expectedErr != "" {
require . EqualError ( err , tc . expectedErr )
return
}
require . NoError ( err )
2023-07-18 16:33:24 -07:00
require . Equal ( tc . exepected . AccessKey , tc . in . CredentialsConfig . AccessKey )
require . Equal ( tc . exepected . SecretKey , tc . in . CredentialsConfig . SecretKey )
2021-10-05 16:36:53 -07:00
require . Equal ( tc . expectedNonZeroRotatedTime , ! tc . in . CredsLastRotatedTime . IsZero ())
})
}
}
2023-07-18 16:33:24 -07:00
func TestAwsCatalogPersistedState_ReplaceCreds ( t * testing . T ) {
2021-10-05 16:36:53 -07:00
// NOTE: Not safe to run this test in parallel
state := new ( testMockIAMState )
cases := [] struct {
2023-07-18 16:33:24 -07:00
name string
in * AwsCredentialPersistedState
credentialConfig * awsutil . CredentialsConfig
expected * awsutil . CredentialsConfig
expectedDeleteCalled bool
expectedErr string
2021-10-05 16:36:53 -07:00
}{
{
2023-07-18 16:33:24 -07:00
name : "missing new credentials config" ,
2023-03-20 11:02:17 -07:00
in : & AwsCredentialPersistedState {},
2023-07-18 16:33:24 -07:00
expectedErr : "missing new credentials config" ,
2021-10-05 16:36:53 -07:00
},
{
2023-07-18 16:33:24 -07:00
name : "missing credentials config" ,
in : & AwsCredentialPersistedState {},
credentialConfig : & awsutil . CredentialsConfig {},
expectedErr : "missing credentials config" ,
2021-10-05 16:36:53 -07:00
},
{
name : "deletion error" ,
2023-03-20 11:02:17 -07:00
in : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
},
2021-10-05 16:36:53 -07:00
CredsLastRotatedTime : time . Now (),
testOpts : [] awsutil . Option {
awsutil . WithIAMAPIFunc (
awsutil . NewMockIAM (
awsutil . WithDeleteAccessKeyError ( errors . New ( testDeleteAccessKeyErr )),
),
),
},
},
2023-07-18 16:33:24 -07:00
credentialConfig : & awsutil . CredentialsConfig {},
expectedErr : fmt . Sprintf ( "error deleting old access key: %s" , testDeleteAccessKeyErr ),
2021-10-05 16:36:53 -07:00
},
{
name : "good with delete of old rotated" ,
2023-03-20 11:02:17 -07:00
in : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
},
2021-10-05 16:36:53 -07:00
CredsLastRotatedTime : time . Now (),
testOpts : [] awsutil . Option {
awsutil . WithIAMAPIFunc (
newTestMockIAM ( state ),
),
},
},
2023-07-18 16:33:24 -07:00
credentialConfig : & awsutil . CredentialsConfig {
AccessKey : "one" ,
SecretKey : "two" ,
},
expected : & awsutil . CredentialsConfig {
AccessKey : "one" ,
SecretKey : "two" ,
},
expectedDeleteCalled : true ,
2021-10-05 16:36:53 -07:00
},
{
name : "good without delete of old rotated" ,
2023-03-20 11:02:17 -07:00
in : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
},
2021-10-05 16:36:53 -07:00
testOpts : [] awsutil . Option {
awsutil . WithIAMAPIFunc (
newTestMockIAM ( state ),
),
},
},
2023-07-18 16:33:24 -07:00
credentialConfig : & awsutil . CredentialsConfig {
AccessKey : "one" ,
SecretKey : "two" ,
},
expected : & awsutil . CredentialsConfig {
AccessKey : "one" ,
SecretKey : "two" ,
},
expectedDeleteCalled : false ,
2021-10-05 16:36:53 -07:00
},
}
for _ , tc := range cases {
tc := tc
t . Run ( tc . name , func ( t * testing . T ) {
require := require . New ( t )
state . Reset ()
2023-07-18 16:33:24 -07:00
err := tc . in . ReplaceCreds ( tc . credentialConfig )
2021-10-05 16:36:53 -07:00
if tc . expectedErr != "" {
require . EqualError ( err , tc . expectedErr )
return
}
require . NoError ( err )
2023-07-18 16:33:24 -07:00
require . Equal ( tc . expected . AccessKey , tc . in . CredentialsConfig . AccessKey )
require . Equal ( tc . expected . SecretKey , tc . in . CredentialsConfig . SecretKey )
2021-10-05 16:36:53 -07:00
require . Zero ( tc . in . CredsLastRotatedTime )
require . Equal ( tc . expectedDeleteCalled , state . DeleteAccessKeyCalled )
})
}
}
2023-07-18 16:33:24 -07:00
func TestAwsCatalogPersistedState_DeleteCreds ( t * testing . T ) {
2021-10-05 16:36:53 -07:00
cases := [] struct {
name string
2023-03-20 11:02:17 -07:00
in * AwsCredentialPersistedState
2021-10-05 16:36:53 -07:00
expectedErr string
}{
{
2023-07-18 16:33:24 -07:00
name : "missing credentials config" ,
in : & AwsCredentialPersistedState {},
expectedErr : "missing credentials config" ,
2021-10-05 16:36:53 -07:00
},
{
name : "deletion error" ,
2023-03-20 11:02:17 -07:00
in : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
},
2021-10-05 16:36:53 -07:00
testOpts : [] awsutil . Option {
awsutil . WithIAMAPIFunc (
awsutil . NewMockIAM (
awsutil . WithDeleteAccessKeyError ( errors . New ( testDeleteAccessKeyErr )),
),
),
},
},
2021-10-06 12:47:05 -07:00
expectedErr : fmt . Sprintf ( "error deleting old access key: %s" , testDeleteAccessKeyErr ),
2021-10-05 16:36:53 -07:00
},
{
name : "deletion error, but OK because key was just gone" ,
2023-03-20 11:02:17 -07:00
in : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
},
2021-10-05 16:36:53 -07:00
testOpts : [] awsutil . Option {
awsutil . WithIAMAPIFunc (
awsutil . NewMockIAM (
awsutil . WithDeleteAccessKeyError (
awserr . New ( iam . ErrCodeNoSuchEntityException , "" , nil ),
),
),
),
},
},
},
{
name : "good" ,
2023-03-20 11:02:17 -07:00
in : & AwsCredentialPersistedState {
2023-07-18 16:33:24 -07:00
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
},
2021-10-05 16:36:53 -07:00
testOpts : [] awsutil . Option {
awsutil . WithIAMAPIFunc (
awsutil . NewMockIAM (),
),
},
},
},
}
for _ , tc := range cases {
tc := tc
t . Run ( tc . name , func ( t * testing . T ) {
require := require . New ( t )
err := tc . in . DeleteCreds ()
if tc . expectedErr != "" {
require . EqualError ( err , tc . expectedErr )
return
}
require . NoError ( err )
2023-07-18 16:33:24 -07:00
require . Nil ( tc . in . CredentialsConfig )
2021-10-05 16:36:53 -07:00
require . Zero ( tc . in . CredsLastRotatedTime )
})
}
}
2023-07-18 16:33:24 -07:00
func TestAwsCatalogPersistedState_GetSession ( t * testing . T ) {
2021-10-05 16:36:53 -07:00
require := require . New ( t )
2023-07-18 16:33:24 -07:00
cases := [] struct {
name string
in * AwsCredentialPersistedState
expectedErr string
}{
{
name : "error" ,
in : & AwsCredentialPersistedState {
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "foobar" ,
SecretKey : "bazqux" ,
},
testOpts : [] awsutil . Option { awsutil . MockOptionErr ( errors . New ( testOptionErr ))},
},
expectedErr : fmt . Sprintf ( "error reading options in GetSession: %s" , testOptionErr ),
},
{
name : "static credentials" ,
in : & AwsCredentialPersistedState {
CredentialsConfig : & awsutil . CredentialsConfig {
AccessKey : "AKIA_foobar" ,
SecretKey : "bazqux" ,
},
testOpts : [] awsutil . Option {
awsutil . WithIAMAPIFunc (
awsutil . NewMockIAM (),
),
},
},
},
{
name : "assume role" ,
in : & AwsCredentialPersistedState {
CredentialsConfig : func () * awsutil . CredentialsConfig {
config , err := awsutil . NewCredentialsConfig (
awsutil . WithRegion ( "us-west-2" ),
awsutil . WithRoleArn ( "arn:aws:iam::123456789012:role/S3Access" ),
awsutil . WithRoleExternalId ( "1234567890" ),
awsutil . WithRoleSessionName ( "assume-role" ),
awsutil . WithRoleTags ( map [ string ] string {
"foo" : "bar" ,
}),
)
require . NoError ( err )
return config
}(),
testOpts : [] awsutil . Option {
awsutil . WithIAMAPIFunc (
awsutil . NewMockIAM (),
),
},
},
},
2021-10-05 16:36:53 -07:00
}
2023-07-18 16:33:24 -07:00
for _ , tc := range cases {
tc := tc
t . Run ( tc . name , func ( t * testing . T ) {
_ , err := tc . in . GetSession ()
if tc . expectedErr != "" {
require . EqualError ( err , tc . expectedErr )
return
}
require . NoError ( err )
})
}
}
2021-10-05 16:36:53 -07:00
2023-07-18 16:33:24 -07:00
func TestHasStaticCredentials ( t * testing . T ) {
require := require . New ( t )
cases := [] struct {
name string
accessKey string
expected bool
}{
{
name : "dynamic credential" ,
accessKey : "ASIAEXAMPLE" ,
expected : false ,
},
{
name : "static credential" ,
accessKey : "AKIAEXAMPLE" ,
expected : true ,
},
{
name : "other credential" ,
accessKey : "EXAMPLE" ,
expected : false ,
},
{
name : "empty" ,
accessKey : "" ,
expected : false ,
},
}
for _ , tc := range cases {
tc := tc
t . Run ( tc . name , func ( t * testing . T ) {
require . Equal ( tc . expected , HasStaticCredentials ( tc . accessKey ))
})
}
}
func TestHasDynamicCredentials ( t * testing . T ) {
require := require . New ( t )
cases := [] struct {
name string
accessKey string
expected bool
}{
{
name : "dynamic credential" ,
accessKey : "ASIAEXAMPLE" ,
expected : true ,
},
{
name : "static credential" ,
accessKey : "AKIAEXAMPLE" ,
expected : false ,
},
{
name : "other credential" ,
accessKey : "EXAMPLE" ,
expected : false ,
},
{
name : "empty" ,
accessKey : "" ,
expected : false ,
},
}
for _ , tc := range cases {
tc := tc
t . Run ( tc . name , func ( t * testing . T ) {
require . Equal ( tc . expected , HasDynamicCredentials ( tc . accessKey ))
})
}
2021-10-05 16:36:53 -07:00
}