Repository: Versent/saml2aws
Pull request #171 (2018-05-13 01:54:29)

feat(config) You can now configure an aws profile per account.
So rather than only providing the option to override via a flag, this is now saved in the configuration :tada:.


Patch:
diff --git a/cmd/saml2aws/commands/exec.go b/cmd/saml2aws/commands/exec.go
index fcd850d..8532ac6 100644
--- a/cmd/saml2aws/commands/exec.go
+++ b/cmd/saml2aws/commands/exec.go
@@ -22,7 +22,12 @@ func Exec(execFlags *flags.LoginExecFlags, cmdline []string) error {
 		return fmt.Errorf("Command to execute required")
 	}
 
-	sharedCreds := awsconfig.NewSharedCredentials(execFlags.Profile)
+	account, err := buildIdpAccount(execFlags)
+	if err != nil {
+		return errors.Wrap(err, "error building login details")
+	}
+
+	sharedCreds := awsconfig.NewSharedCredentials(account.Profile)
 
 	// this checks if the credentials file has been created yet
 	// can only really be triggered if saml2aws exec is run on a new
@@ -45,7 +50,7 @@ func Exec(execFlags *flags.LoginExecFlags, cmdline []string) error {
 		return errors.New("error aws credentials have expired")
 	}
 
-	ok, err := checkToken(execFlags.Profile)
+	ok, err := checkToken(account.Profile)
 	if err != nil {
 		return errors.Wrap(err, "error validating token")
 	}
diff --git a/cmd/saml2aws/commands/login.go b/cmd/saml2aws/commands/login.go
index ee5f94b..e83f92e 100644
--- a/cmd/saml2aws/commands/login.go
+++ b/cmd/saml2aws/commands/login.go
@@ -23,7 +23,12 @@ func Login(loginFlags *flags.LoginExecFlags) error {
 
 	logger := logrus.WithField("command", "login")
 
-	sharedCreds := awsconfig.NewSharedCredentials(loginFlags.Profile)
+	account, err := buildIdpAccount(loginFlags)
+	if err != nil {
+		return errors.Wrap(err, "error building login details")
+	}
+
+	sharedCreds := awsconfig.NewSharedCredentials(account.Profile)
 
 	logger.Debug("check if Creds Exist")
 
@@ -37,11 +42,6 @@ func Login(loginFlags *flags.LoginExecFlags) error {
 		return nil
 	}
 
-	account, err := buildIdpAccount(loginFlags)
-	if err != nil {
-		return errors.Wrap(err, "error building login details")
-	}
-
 	loginDetails, err := resolveLoginDetails(account, loginFlags)
 	if err != nil {
 		fmt.Printf("%+v\n", err)
diff --git a/cmd/saml2aws/main.go b/cmd/saml2aws/main.go
index 4540ede..7d64919 100644
--- a/cmd/saml2aws/main.go
+++ b/cmd/saml2aws/main.go
@@ -70,13 +70,13 @@ func main() {
 	cmdLogin := app.Command("login", "Login to a SAML 2.0 IDP and convert the SAML assertion to an STS token.")
 	loginFlags := new(flags.LoginExecFlags)
 	loginFlags.CommonFlags = commonFlags
-	cmdLogin.Flag("profile", "The AWS profile to save the temporary credentials").Short('p').Default("saml").StringVar(&loginFlags.Profile)
+	cmdLogin.Flag("profile", "The AWS profile to save the temporary credentials").Short('p').StringVar(&commonFlags.Profile)
 
 	// `exec` command and settings
 	cmdExec := app.Command("exec", "Exec the supplied command with env vars from STS token.")
 	execFlags := new(flags.LoginExecFlags)
 	execFlags.CommonFlags = commonFlags
-	cmdExec.Flag("profile", "The AWS profile to save the temporary credentials").Short('p').Default("saml").StringVar(&execFlags.Profile)
+	cmdExec.Flag("profile", "The AWS profile to save the temporary credentials").Short('p').StringVar(&commonFlags.Profile)
 	cmdLine := buildCmdList(cmdExec.Arg("command", "The command to execute."))
 
 	// `list` command and settings
diff --git a/input.go b/input.go
index f2d8c5d..cd696ac 100644
--- a/input.go
+++ b/input.go
@@ -34,6 +34,8 @@ func PromptForConfigurationDetails(idpAccount *cfg.IDPAccount) error {
 		idpAccount.MFA = mfas[0]
 	}
 
+	idpAccount.Profile = prompter.String("AWS Profile", idpAccount.Profile)
+
 	fmt.Println("")
 
 	idpAccount.URL = prompter.String("URL", idpAccount.URL)
diff --git a/pkg/cfg/cfg.go b/pkg/cfg/cfg.go
index 5c3bc78..ec1b528 100644
--- a/pkg/cfg/cfg.go
+++ b/pkg/cfg/cfg.go
@@ -24,6 +24,9 @@ const (
 	// DefaultSessionDuration this is the default session duration which can be overridden in the AWS console
 	// see https://aws.amazon.com/blogs/security/enable-federated-api-access-to-your-aws-resources-for-up-to-12-hours-using-iam-roles/
 	DefaultSessionDuration = 3600
+
+	// DefaultProfile this is the default profile name used to save the credentials in the aws cli
+	DefaultProfile = "saml"
 )
 
 // IDPAccount saml IDP account
@@ -36,6 +39,7 @@ type IDPAccount struct {
 	Timeout              int    `ini:"timeout"`
 	AmazonWebservicesURN string `ini:"aws_urn"`
 	SessionDuration      int    `ini:"aws_session_duration"`
+	Profile              string `ini:"aws_profile"`
 }
 
 func (ia IDPAccount) String() string {
@@ -47,7 +51,8 @@ func (ia IDPAccount) String() string {
   SkipVerify: %v
   AmazonWebservicesURN: %s
   SessionDuration: %d
-}`, ia.URL, ia.Username, ia.Provider, ia.MFA, ia.SkipVerify, ia.AmazonWebservicesURN, ia.SessionDuration)
+  Profile: %s
+}`, ia.URL, ia.Username, ia.Provider, ia.MFA, ia.SkipVerify, ia.AmazonWebservicesURN, ia.SessionDuration, ia.Profile)
 }
 
 // Validate validate the required / expected fields are set
@@ -69,6 +74,10 @@ func (ia *IDPAccount) Validate() error {
 		return errors.New("MFA empty in idp account")
 	}
 
+	if ia.Profile == "" {
+		return errors.New("Profile empty in idp account")
+	}
+
 	return nil
 }
 
@@ -77,6 +86,7 @@ func NewIDPAccount() *IDPAccount {
 	return &IDPAccount{
 		AmazonWebservicesURN: DefaultAmazonWebservicesURN,
 		SessionDuration:      DefaultSessionDuration,
+		Profile:              DefaultProfile,
 	}
 }
 
diff --git a/pkg/flags/flags.go b/pkg/flags/flags.go
index 265f0df..543c39a 100644
--- a/pkg/flags/flags.go
+++ b/pkg/flags/flags.go
@@ -17,6 +17,7 @@ type CommonFlags struct {
 	SessionDuration      int
 	SkipPrompt           bool
 	SkipVerify           bool
+	Profile              string
 }
 
 // RoleSupplied role arn has been passed as a flag
@@ -27,7 +28,6 @@ func (cf *CommonFlags) RoleSupplied() bool {
 // LoginExecFlags flags for the Login / Exec commands
 type LoginExecFlags struct {
 	CommonFlags *CommonFlags
-	Profile     string
 }
 
 // ApplyFlagOverrides overrides IDPAccount with command line settings
@@ -59,4 +59,8 @@ func ApplyFlagOverrides(commonFlags *CommonFlags, account *cfg.IDPAccount) {
 	if commonFlags.SessionDuration != 0 {
 		account.SessionDuration = commonFlags.SessionDuration
 	}
+
+	if commonFlags.Profile != "" {
+		account.Profile = commonFlags.Profile
+	}
 }


Test patch:
diff --git a/pkg/cfg/cfg_test.go b/pkg/cfg/cfg_test.go
index 5319f4d..72d543f 100644
--- a/pkg/cfg/cfg_test.go
+++ b/pkg/cfg/cfg_test.go
@@ -33,6 +33,7 @@ func TestNewConfigManagerLoad(t *testing.T) {
 		MFA:                  "sms",
 		AmazonWebservicesURN: DefaultAmazonWebservicesURN,
 		SessionDuration:      3600,
+		Profile:              "saml",
 	}, idpAccount)
 
 	idpAccount, err = cfgm.LoadIDPAccount("test1234")
@@ -40,6 +41,7 @@ func TestNewConfigManagerLoad(t *testing.T) {
 	require.Equal(t, &IDPAccount{
 		AmazonWebservicesURN: DefaultAmazonWebservicesURN,
 		SessionDuration:      3600,
+		Profile:              "saml",
 	}, idpAccount)
 }
 
@@ -59,6 +61,7 @@ func TestNewConfigManagerLoadVerify(t *testing.T) {
 		MFA:                  "sms",
 		AmazonWebservicesURN: DefaultAmazonWebservicesURN,
 		SessionDuration:      3600,
+		Profile:              "saml",
 	}, idpAccount)
 
 	idpAccount, err = cfgm.LoadVerifyIDPAccount("test1234")
@@ -76,6 +79,7 @@ func TestNewConfigManagerSave(t *testing.T) {
 		MFA:      "none",
 		Provider: "keycloak",
 		Username: "abc@whatever.com",
+		Profile:  "saml",
 	})
 	require.Nil(t, err)
 	idpAccount, err := cfgm.LoadVerifyIDPAccount("testing2")
@@ -86,6 +90,7 @@ func TestNewConfigManagerSave(t *testing.T) {
 		Provider:             "keycloak",
 		MFA:                  "none",
 		AmazonWebservicesURN: DefaultAmazonWebservicesURN,
+		Profile:              "saml",
 	}, idpAccount)
 
 	os.Remove(throwAwayConfig)
diff --git a/pkg/flags/flags_test.go b/pkg/flags/flags_test.go
index e199b4b..1a4b27e 100644
--- a/pkg/flags/flags_test.go
+++ b/pkg/flags/flags_test.go
@@ -36,6 +36,8 @@ func TestOverrideAllFlags(t *testing.T) {
 		URL:                  "https://id.example.com",
 		Username:             "myuser",
 		AmazonWebservicesURN: "urn:amazon:webservices",
+		SessionDuration:      3600,
+		Profile:              "saml",
 	}
 	idpa := &cfg.IDPAccount{
 		Provider:             "Ping",
@@ -53,6 +55,8 @@ func TestOverrideAllFlags(t *testing.T) {
 		URL:                  "https://id.example.com",
 		Username:             "myuser",
 		AmazonWebservicesURN: "urn:amazon:webservices",
+		SessionDuration:      3600,
+		Profile:              "saml",
 	}
 	ApplyFlagOverrides(commonFlags, idpa)