Skip to content

Commit

Permalink
use a goroutine with channel to fetch the MFA device in the background.
Browse files Browse the repository at this point in the history
  • Loading branch information
stanislas committed Jun 22, 2018
1 parent 8e5fd9f commit a78aa14
Showing 1 changed file with 36 additions and 12 deletions.
48 changes: 36 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
var (
version = "dev"
)

const admDuration = 3600
const standardDuration = 36000

Expand All @@ -35,10 +36,13 @@ func main() {
}
iamc := iam.New(cfg)
stsc := sts.New(cfg)
username := username(stsc)
mfaDevice := mfaDevice(iamc, username)
arn := mfaDeviceArnChan(stsc, iamc)
tokenCode := tokenCode()
credentials := sessionCredentials(stsc, mfaDevice, tokenCode, duration(profile))
mfaDeviceArn := <-arn
if mfaDeviceArn.error != nil {
panic(mfaDeviceArn.error)
}
credentials := sessionCredentials(stsc, mfaDeviceArn.arn, tokenCode, duration(profile))
storeCredentials(profile, region, credentials)
storeConfig(profile, region)
fmt.Printf("Credentials valid until: %s\n", credentials.Expiration)
Expand Down Expand Up @@ -76,26 +80,46 @@ func printVersion() {
fmt.Printf("Skuld version: %s\n", version)
}

func username(stsc *sts.STS) string {
callerIdResp, err := stsc.GetCallerIdentityRequest(nil).Send()
if err != nil {
panic("Unable to get the username.")
}
arn := callerIdResp.Arn
return strings.Split(*arn, ":user/")[1]
type arn struct {
arn string
error interface{}
}

func mfaDeviceArnChan(stsc *sts.STS, iamc *iam.IAM) chan arn {
result := make(chan arn)
go func() {
defer func() {
if err := recover(); err != nil {
result <- arn{error: err}
}
}()
deviceArn := mfaDeviceArn(stsc, iamc)
result <- arn{arn: deviceArn}
}()
return result;
}

func mfaDevice(iamc *iam.IAM, userArn string) string {
func mfaDeviceArn(stsc *sts.STS, iamc *iam.IAM) string {
userArn := userArn(stsc)
mfaDevice, err := iamc.ListMFADevicesRequest(
&iam.ListMFADevicesInput{UserName: &userArn},
).Send()
if err != nil {
println(err.Error())
panic("Unable to fetch the MFA device")
panic("Unable to fetch the MFA device Arn.")
}
return *mfaDevice.MFADevices[0].SerialNumber
}

func userArn(stsc *sts.STS) string {
callerIdResp, err := stsc.GetCallerIdentityRequest(nil).Send()
if err != nil {
panic("Unable to get the userArn.")
}
arn := callerIdResp.Arn
return strings.Split(*arn, ":user/")[1]
}

func duration(profile string) int64 {
if strings.HasSuffix(profile, "-adm") {
return admDuration
Expand Down

0 comments on commit a78aa14

Please sign in to comment.