Skip to content

Commit 1b36fc7

Browse files
author
Chris Gilmer
committed
Allow users to assume MFA device is already configured
1 parent bf9e57b commit 1b36fc7

File tree

2 files changed

+57
-9
lines changed

2 files changed

+57
-9
lines changed

cmd/cli.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ const (
2727
IAMRoleFlag string = "iam-role"
2828

2929
// OutputFlag is the Output Flag
30-
OutputFlag = "output"
30+
OutputFlag string = "output"
31+
32+
// NoMFAFlag indicates that no MFA device should be configured as one exists
33+
NoMFAFlag string = "no-mfa"
3134

3235
// VerboseFlag is the Verbose Flag
3336
VerboseFlag string = "verbose"

cmd/setup.go

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"errors"
45
"fmt"
56
"io/ioutil"
67
"log"
@@ -47,8 +48,11 @@ func setupUserInitFlags(flag *pflag.FlagSet) {
4748
flag.String(IAMRoleFlag, "", "The IAM role name assigned to the user being setup")
4849
flag.String(OutputFlag, "json", "The AWS CLI output format")
4950

51+
// No MFA Setup
52+
flag.Bool(NoMFAFlag, false, "When present do not provision an MFA device, assume one exists")
53+
5054
// Verbose
51-
flag.BoolP(VerboseFlag, "v", false, "log messages at the debug level.")
55+
flag.BoolP(VerboseFlag, "v", false, "log messages at the debug level")
5256

5357
flag.SortFlags = false
5458
}
@@ -93,6 +97,7 @@ type User struct {
9397
SecretAccessKey string
9498
QrTempFile *os.File
9599
Keyring *keyring.Keyring
100+
NoMFA bool
96101
}
97102

98103
// Setup orchestrates the tasks to create the user's MFA and rotate access
@@ -108,14 +113,21 @@ func (u *User) Setup(logger *log.Logger) {
108113
logger.Fatal(err)
109114
}
110115

111-
err = u.CreateVirtualMFADevice(logger)
112-
if err != nil {
113-
logger.Fatal(err)
114-
}
116+
if u.NoMFA {
117+
err = u.GetMFADevice(logger)
118+
if err != nil {
119+
logger.Fatal(err)
120+
}
121+
} else {
122+
err = u.CreateVirtualMFADevice(logger)
123+
if err != nil {
124+
logger.Fatal(err)
125+
}
115126

116-
err = u.EnableVirtualMFADevice(logger)
117-
if err != nil {
118-
logger.Fatal(err)
127+
err = u.EnableVirtualMFADevice(logger)
128+
if err != nil {
129+
logger.Fatal(err)
130+
}
119131
}
120132

121133
err = u.UpdateAWSConfigFile(logger)
@@ -200,6 +212,37 @@ func (u *User) newMFASession(logger *log.Logger) (*session.Session, error) {
200212
return mfaSession, nil
201213
}
202214

215+
// GetMFADevice gets the user's existing virtual MFA device and updates the
216+
// MFA serial in the profile field.
217+
func (u *User) GetMFADevice(logger *log.Logger) error {
218+
logger.Println("Getting the existing MFA device...")
219+
220+
sess, err := u.newSession()
221+
if err != nil {
222+
return fmt.Errorf("unable to get new session: %w", err)
223+
}
224+
svc := iam.New(sess)
225+
226+
mfaDeviceInput := &iam.ListMFADevicesInput{
227+
UserName: aws.String(u.Name),
228+
}
229+
230+
mfaDeviceOutput, err := svc.ListMFADevices(mfaDeviceInput)
231+
if err != nil {
232+
return fmt.Errorf("unable to get MFA: %w", err)
233+
}
234+
235+
if len(mfaDeviceOutput.MFADevices) == 0 {
236+
return errors.New("no MFA devices registered")
237+
}
238+
mfaDevice := mfaDeviceOutput.MFADevices[0]
239+
240+
u.BaseProfile.MFASerial = *mfaDevice.SerialNumber
241+
u.RoleProfile.MFASerial = *mfaDevice.SerialNumber
242+
243+
return nil
244+
}
245+
203246
// CreateVirtualMFADevice creates the user's virtual MFA device and updates the
204247
// MFA serial in the profile field.
205248
func (u *User) CreateVirtualMFADevice(logger *log.Logger) error {
@@ -572,6 +615,7 @@ func setupUserFunction(cmd *cobra.Command, args []string) error {
572615
iamUser := v.GetString(IAMUserFlag)
573616
iamRole := v.GetString(IAMRoleFlag)
574617
output := v.GetString(OutputFlag)
618+
noMFA := v.GetBool(NoMFAFlag)
575619

576620
// Validator used to validate input options for MFA
577621
validate = validator.New()
@@ -628,6 +672,7 @@ func setupUserFunction(cmd *cobra.Command, args []string) error {
628672
Config: config,
629673
QrTempFile: tempfile,
630674
Keyring: keyring,
675+
NoMFA: noMFA,
631676
}
632677
err = checkExistingAWSProfile(baseProfile.Name, config, logger)
633678
if err != nil {

0 commit comments

Comments
 (0)