@@ -252,6 +252,16 @@ func TestAccessKeyDefaultProvisioner(t *testing.T) {
252252 configPath := filepath .Join (t .TempDir (), "awsConfig" )
253253 t .Setenv ("AWS_CONFIG_FILE" , configPath )
254254
255+ // setup profiles in config file
256+ file := ini .Empty ()
257+ profileDefault , err := file .NewSection ("default" )
258+ require .NoError (t , err )
259+ _ , err = profileDefault .NewKey ("region" , "us-central-1" )
260+ require .NoError (t , err )
261+
262+ err = file .SaveTo (configPath )
263+ require .NoError (t , err )
264+
255265 plugintest .TestProvisioner (t , AccessKey ().DefaultProvisioner , map [string ]plugintest.ProvisionCase {
256266 "default" : {
257267 ItemFields : map [sdk.FieldName ]string {
@@ -282,22 +292,37 @@ func TestSTSProvisioner(t *testing.T) {
282292 require .NoError (t , err )
283293 _ , err = profileDev .NewKey ("role_arn" , "aws:iam::123456789012:role/testRole2" )
284294 require .NoError (t , err )
295+
285296 profileProd , err := file .NewSection ("profile prod" )
286297 require .NoError (t , err )
287298 _ , err = profileProd .NewKey ("mfa_serial" , "arn:aws:iam::123456789012:mfa/user1" )
288299 require .NoError (t , err )
300+
289301 profileDefault , err := file .NewSection ("default" )
290302 require .NoError (t , err )
291- _ , err = profileDefault .NewKey ("role_arn" , "aws:iam::123456789012:role/testRole" )
292- require .NoError (t , err )
293303 _ , err = profileDefault .NewKey ("region" , "us-central-1" )
294304 require .NoError (t , err )
305+
295306 profileTest , err := file .NewSection ("profile test" )
296307 require .NoError (t , err )
297308 _ , err = profileTest .NewKey ("mfa_serial" , "arn:aws:iam::123456789012:mfa/user1" )
298309 require .NoError (t , err )
299310 _ , err = profileTest .NewKey ("role_arn" , "aws:iam::123456789012:role/testRole" )
300311 require .NoError (t , err )
312+
313+ profileSourceComplex , err := file .NewSection ("profile testSourceComplex" )
314+ require .NoError (t , err )
315+ _ , err = profileSourceComplex .NewKey ("mfa_serial" , "arn:aws:iam::123456789012:mfa/user1" )
316+ require .NoError (t , err )
317+ _ , err = profileSourceComplex .NewKey ("role_arn" , "aws:iam::123456789012:role/testRole" )
318+ require .NoError (t , err )
319+ _ , err = profileSourceComplex .NewKey ("source_profile" , "testSourceSimple" )
320+ require .NoError (t , err )
321+
322+ profileSourceSimple , err := file .NewSection ("profile testSourceSimple" )
323+ require .NoError (t , err )
324+ _ , err = profileSourceSimple .NewKey ("source_profile" , "default" )
325+ require .NoError (t , err )
301326 err = file .SaveTo (configPath )
302327 require .NoError (t , err )
303328
@@ -392,6 +417,132 @@ func TestSTSProvisioner(t *testing.T) {
392417 },
393418 },
394419 })
420+
421+ plugintest .TestProvisioner (t , STSProvisioner {
422+ profileName : "testSourceSimple" ,
423+ newProviderFactory : func (cacheState sdk.CacheState , cacheOps sdk.CacheOperations , fields map [sdk.FieldName ]string ) STSProviderFactory {
424+ return & mockProviderManager {ItemFields : map [sdk.FieldName ]string {
425+ fieldname .AccessKeyID : "AKIAHPIZFMD5EEXAMPLE" ,
426+ fieldname .SecretAccessKey : "lBfKB7P5ScmpxDeRoFLZvhJbqNGPoV0vIEXAMPLE" ,
427+ }}
428+ },
429+ }, map [string ]plugintest.ProvisionCase {
430+ "WithSourceProfileSimple" : {
431+ ItemFields : map [sdk.FieldName ]string {
432+ fieldname .AccessKeyID : "AKIAHPIZFMD5EEXAMPLE" ,
433+ fieldname .SecretAccessKey : "lBfKB7P5ScmpxDeRoFLZvhJbqNGPoV0vIEXAMPLE" ,
434+ },
435+ ExpectedOutput : sdk.ProvisionOutput {
436+ Environment : map [string ]string {
437+ "AWS_ACCESS_KEY_ID" : "AKIAHPIZFMD5EEXAMPLE" ,
438+ "AWS_SECRET_ACCESS_KEY" : "lBfKB7P5ScmpxDeRoFLZvhJbqNGPoV0vIEXAMPLE" ,
439+ "AWS_DEFAULT_REGION" : "us-central-1" ,
440+ },
441+ },
442+ },
443+ })
444+
445+ plugintest .TestProvisioner (t , STSProvisioner {
446+ profileName : "testSourceComplex" ,
447+ newProviderFactory : func (cacheState sdk.CacheState , cacheOps sdk.CacheOperations , fields map [sdk.FieldName ]string ) STSProviderFactory {
448+ return & mockProviderManager {}
449+ },
450+ }, map [string ]plugintest.ProvisionCase {
451+ "WithSourceProfileComplex" : {
452+ ItemFields : map [sdk.FieldName ]string {
453+ fieldname .AccessKeyID : "AKIAHPIZFMD5EEXAMPLE" ,
454+ fieldname .SecretAccessKey : "lBfKB7P5ScmpxDeRoFLZvhJbqNGPoV0vIEXAMPLE" ,
455+ fieldname .DefaultRegion : "us-central-1" ,
456+ fieldname .OneTimePassword : "908789" ,
457+ fieldname .MFASerial : "arn:aws:iam::123456789012:mfa/user1" ,
458+ },
459+ ExpectedOutput : sdk.ProvisionOutput {
460+ Environment : map [string ]string {
461+ "AWS_ACCESS_KEY_ID" : "AKIAHPIZFMD5EEXSTS" ,
462+ "AWS_SECRET_ACCESS_KEY" : "stststststst/K7MDENG/bPxRfiCYEXAMPLEKEY" ,
463+ "AWS_SESSION_TOKEN" : "stststststst/K7MDENG/bPxRfiCYEXAMPLEKEY///////stststststst/K7MDENG/bPxRfiCYEXAMPLEKEY///////stststststst/K7MDENG/bPxRfiCYEXAMPLEKEY" ,
464+ "AWS_DEFAULT_REGION" : "us-central-1" ,
465+ },
466+ },
467+ },
468+ })
469+ }
470+
471+ func TestSourceProfileLoop (t * testing.T ) {
472+ t .Setenv ("AWS_PROFILE" , "" )
473+ t .Setenv ("AWS_DEFAULT_REGION" , "" )
474+ configPath := filepath .Join (t .TempDir (), "awsConfig" )
475+ t .Setenv ("AWS_CONFIG_FILE" , configPath )
476+
477+ // setup profiles in config file
478+ file := ini .Empty ()
479+ profileDev , err := file .NewSection ("profile dev" )
480+ require .NoError (t , err )
481+ _ , err = profileDev .NewKey ("source_profile" , "default" )
482+ require .NoError (t , err )
483+
484+ profileDefault , err := file .NewSection ("default" )
485+ require .NoError (t , err )
486+ _ , err = profileDefault .NewKey ("source_profile" , "prod" )
487+ require .NoError (t , err )
488+
489+ profileProd , err := file .NewSection ("profile prod" )
490+ require .NoError (t , err )
491+ _ , err = profileProd .NewKey ("source_profile" , "dev" )
492+ require .NoError (t , err )
493+
494+ profileStaging , err := file .NewSection ("profile staging" )
495+ require .NoError (t , err )
496+ _ , err = profileStaging .NewKey ("source_profile" , "staging" )
497+ require .NoError (t , err )
498+
499+ err = file .SaveTo (configPath )
500+ require .NoError (t , err )
501+
502+ plugintest .TestProvisioner (t , STSProvisioner {
503+ profileName : "prod" ,
504+ newProviderFactory : func (cacheState sdk.CacheState , cacheOps sdk.CacheOperations , fields map [sdk.FieldName ]string ) STSProviderFactory {
505+ return & mockProviderManager {}
506+ },
507+ }, map [string ]plugintest.ProvisionCase {
508+ "WithEndlessLoop" : {
509+ ItemFields : map [sdk.FieldName ]string {
510+ fieldname .AccessKeyID : "AKIAHPIZFMD5EEXAMPLE" ,
511+ fieldname .SecretAccessKey : "lBfKB7P5ScmpxDeRoFLZvhJbqNGPoV0vIEXAMPLE" ,
512+ fieldname .DefaultRegion : "us-central-1" ,
513+ fieldname .OneTimePassword : "908789" ,
514+ fieldname .MFASerial : "arn:aws:iam::123456789012:mfa/user1" ,
515+ },
516+ ExpectedOutput : sdk.ProvisionOutput {
517+ Diagnostics : sdk.Diagnostics {Errors : []sdk.Error {{Message : "infinite loop in credential configuration detected. Attempting to load from profile \" prod\" which has already been visited" }}},
518+ },
519+ },
520+ })
521+
522+ plugintest .TestProvisioner (t , STSProvisioner {
523+ profileName : "staging" ,
524+ newProviderFactory : func (cacheState sdk.CacheState , cacheOps sdk.CacheOperations , fields map [sdk.FieldName ]string ) STSProviderFactory {
525+ return & mockProviderManager {}
526+ },
527+ }, map [string ]plugintest.ProvisionCase {
528+ "WithAcceptedLoop" : {
529+ ItemFields : map [sdk.FieldName ]string {
530+ fieldname .AccessKeyID : "AKIAHPIZFMD5EEXAMPLE" ,
531+ fieldname .SecretAccessKey : "lBfKB7P5ScmpxDeRoFLZvhJbqNGPoV0vIEXAMPLE" ,
532+ fieldname .DefaultRegion : "us-central-1" ,
533+ fieldname .OneTimePassword : "908789" ,
534+ fieldname .MFASerial : "arn:aws:iam::123456789012:mfa/user1" ,
535+ },
536+ ExpectedOutput : sdk.ProvisionOutput {
537+ Environment : map [string ]string {
538+ "AWS_ACCESS_KEY_ID" : "AKIAHPIZFMD5EEXSTS" ,
539+ "AWS_SECRET_ACCESS_KEY" : "stststststst/K7MDENG/bPxRfiCYEXAMPLEKEY" ,
540+ "AWS_SESSION_TOKEN" : "stststststst/K7MDENG/bPxRfiCYEXAMPLEKEY///////stststststst/K7MDENG/bPxRfiCYEXAMPLEKEY///////stststststst/K7MDENG/bPxRfiCYEXAMPLEKEY" ,
541+ "AWS_DEFAULT_REGION" : "us-central-1" ,
542+ },
543+ },
544+ },
545+ })
395546}
396547
397548func TestResolveLocalAnd1PasswordConfigurations (t * testing.T ) {
@@ -469,17 +620,7 @@ func TestResolveLocalAnd1PasswordConfigurations(t *testing.T) {
469620 ProfileName : "dev" ,
470621 MfaSerial : "arn:aws:iam::123456789012:mfa/user" ,
471622 },
472- err : fmt .Errorf ("MFA failed: an MFA serial was found but no OTP has been set up in 1Password" ),
473- },
474- {
475- description : "has mfa token but no mfa serial" ,
476- itemFields : map [sdk.FieldName ]string {
477- fieldname .OneTimePassword : "515467" ,
478- },
479- awsConfig : & confighelpers.Config {
480- ProfileName : "dev" ,
481- },
482- err : fmt .Errorf ("MFA failed: an OTP was found wihtout a corresponding MFA serial" ),
623+ err : fmt .Errorf ("MFA failed: MFA serial \" arn:aws:iam::123456789012:mfa/user\" was detected on the associated item or in the config file for the selected profile, but no 'One-Time Password' field was found.\n Learn how to add an OTP field to your item:\n https://developer.1password.com/docs/cli/shell-plugins/aws/#optional-set-up-multi-factor-authentication" ),
483624 },
484625 {
485626 description : "has region only in 1Password" ,
@@ -653,13 +794,17 @@ func (p mockAwsProvider) Retrieve(ctx context.Context) (aws.Credentials, error)
653794}
654795
655796type mockProviderManager struct {
656- CacheProviderFactory
797+ ItemFields map [sdk. FieldName ] string
657798}
658799
659- func (m mockProviderManager ) NewMFASessionTokenProvider (awsConfig * confighelpers.Config ) aws.CredentialsProvider {
800+ func (m mockProviderManager ) NewMFASessionTokenProvider (awsConfig * confighelpers.Config , srcCredProvider aws. CredentialsProvider ) aws.CredentialsProvider {
660801 return mockAwsProvider {}
661802}
662803
663- func (m mockProviderManager ) NewAssumeRoleProvider (awsConfig * confighelpers.Config ) aws.CredentialsProvider {
804+ func (m mockProviderManager ) NewAssumeRoleProvider (awsConfig * confighelpers.Config , srcCredProvider aws. CredentialsProvider ) aws.CredentialsProvider {
664805 return mockAwsProvider {}
665806}
807+
808+ func (m mockProviderManager ) NewAccessKeysProvider () aws.CredentialsProvider {
809+ return accessKeysProvider {itemFields : m .ItemFields }
810+ }
0 commit comments