Skip to content

Commit cf87e3b

Browse files
committed
fix: simplify role merge
update tests
1 parent dfc8ff3 commit cf87e3b

File tree

6 files changed

+35
-16
lines changed

6 files changed

+35
-16
lines changed

cmd/saml.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func getSaml(cmd *cobra.Command, args []string) error {
6969
if err != nil {
7070
return err
7171
}
72-
allRoles := credentialexchange.InsertRoleIntoChain(role, roleChain)
72+
allRoles := credentialexchange.MergeRoleChain(role, roleChain, isSso)
7373
conf := credentialexchange.CredentialConfig{
7474
ProviderUrl: providerUrl,
7575
PrincipalArn: principalArn,

cmd/specific.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func specific(cmd *cobra.Command, args []string) error {
6060
StoreInProfile: storeInProfile,
6161
Username: user.Username,
6262
Role: role,
63-
RoleChain: credentialexchange.InsertRoleIntoChain(role, roleChain),
63+
RoleChain: credentialexchange.MergeRoleChain(role, roleChain, false),
6464
},
6565
}
6666

internal/cmdutils/cmdutils.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ func GetCredsWebUI(ctx context.Context, svc credentialexchange.AuthSamlApi, secr
4848
return credentialexchange.SetCredentials(storedCreds, conf)
4949
}
5050

51+
// refreshAwsSsoCreds uses the temp user credentials returned via AWS SSO,
52+
// upon successful auth from the IDP.
53+
// Once credentials are captured they are used in the role assumption process.
5154
func refreshAwsSsoCreds(ctx context.Context, conf credentialexchange.CredentialConfig, secretStore SecretStorageImpl, svc credentialexchange.AuthSamlApi, webConfig *web.WebConfig) error {
5255
webBrowser := web.New(webConfig)
5356
capturedCreds, err := webBrowser.GetSSOCredentials(conf)

internal/credentialexchange/credentialexchange.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ type authWebTokenApi interface {
128128
AssumeRoleWithWebIdentity(ctx context.Context, params *sts.AssumeRoleWithWebIdentityInput, optFns ...func(*sts.Options)) (*sts.AssumeRoleWithWebIdentityOutput, error)
129129
}
130130

131+
// LoginAwsWebToken
131132
func LoginAwsWebToken(ctx context.Context, username string, svc authWebTokenApi) (*AWSCredentials, error) {
132133
// var role string
133134
r, exists := os.LookupEnv(AWS_ROLE_ARN)

internal/credentialexchange/helper.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,20 @@ func SessionName(username, selfName string) string {
4040
return fmt.Sprintf("%s-%s", strings.ReplaceAll(username, `\`, "--"), selfName)
4141
}
4242

43-
func InsertRoleIntoChain(role string, roleChain []string) []string {
43+
// MergeRoleChain inserts the main role into the role chain.
44+
//
45+
// This is mainly used with AWS SSO flow where
46+
// the SSO user credentials are used to assume the target role(s).
47+
func MergeRoleChain(role string, roleChain []string, insertRoleIntoChain bool) []string {
4448
// IF role is provided it can be assumed from the WEB_ID credentials
4549
// this is to maintain the old implementation
46-
rc := []string{}
47-
for _, r := range roleChain {
48-
if r != role {
49-
rc = append(rc, r)
50+
if insertRoleIntoChain {
51+
if role != "" {
52+
return append([]string{role}, roleChain...)
5053
}
54+
return roleChain
5155
}
52-
53-
return rc
56+
return roleChain
5457
}
5558

5659
func SetCredentials(creds *AWSCredentials, config CredentialConfig) error {
@@ -100,6 +103,8 @@ func returnStdOutAsJson(creds AWSCredentials) error {
100103
return nil
101104
}
102105

106+
// GetWebIdTokenFileContents reads the contents of the `AWS_WEB_IDENTITY_TOKEN_FILE` environment variable.
107+
// Used only with specific assume
103108
func GetWebIdTokenFileContents() (string, error) {
104109
// var content *string
105110
file, exists := os.LookupEnv(WEB_ID_TOKEN_VAR)

internal/credentialexchange/helper_test.go

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,21 +106,31 @@ func Test_InsertIntoRoleSlice_with(t *testing.T) {
106106
ttests := map[string]struct {
107107
role string
108108
roleChain []string
109+
isSso bool
109110
expect []string
110111
}{
111-
"chain empty and role specified": {
112-
"role", []string{}, []string{},
112+
"chain empty and role specified with insertRoleIntoChain as false": {
113+
"role", []string{}, false, []string{},
113114
},
114-
"chain set and role empty": {
115-
"", []string{"rolec1"}, []string{"rolec1"},
115+
"chain set and role empty with insertRoleIntoChain as false": {
116+
"", []string{"rolec1"}, false, []string{"rolec1"},
116117
},
117-
"both set and role is always first in list": {
118-
"role", []string{"rolec1"}, []string{"rolec1"},
118+
"both set and role is always first in list with insertRoleIntoChain as false": {
119+
"role", []string{"rolec1"}, false, []string{"rolec1"},
120+
},
121+
"chain empty and role specified with insertRoleIntoChain as true": {
122+
"role", []string{}, true, []string{"role"},
123+
},
124+
"chain set and role empty with insertRoleIntoChain as true": {
125+
"", []string{"rolec1"}, true, []string{"rolec1"},
126+
},
127+
"both set and role is always first in list with insertRoleIntoChain as true": {
128+
"role", []string{"rolec1"}, true, []string{"role", "rolec1"},
119129
},
120130
}
121131
for name, tt := range ttests {
122132
t.Run(name, func(t *testing.T) {
123-
if got := credentialexchange.InsertRoleIntoChain(tt.role, tt.roleChain); len(got) != len(tt.expect) {
133+
if got := credentialexchange.MergeRoleChain(tt.role, tt.roleChain, tt.isSso); len(got) != len(tt.expect) {
124134
t.Errorf("expected: %v, got: %v", tt.expect, got)
125135
}
126136
})

0 commit comments

Comments
 (0)