func()

in app.go [90:197]


func (app *App) AssumeRole(options AssumeRoleParameters) (*TemporaryCredentials, error) {
	profileName, err := app.profileName(options.UserRole)
	if err != nil {
		return nil, err
	}

	profile, err := app.awsConfig.GetProfile(profileName)
	if err != nil {
		return nil, err
	}
	if profile == nil {
		profile = &ProfileConfiguration{}
	}

	currentPrincipalIsAssumedRole, err := app.CurrentPrincipalIsAssumedRole()
	if err != nil {
		return nil, fmt.Errorf("unable to check IAM principal type: %v", err)
	}

	// If force refresh was requested, or the credentials from a previous session
	// are still valid return those
	if !app.credentialsExpired(profile.Expires) && !options.ForceRefresh {
		return app.awsConfig.GetCredentials(profileName)
	}

	// Get the full role ARN by combining the role prefix with the
	// user-provided role name
	roleARN := fmt.Sprintf("%s%s", app.config.RolePrefix, options.UserRole)
	profile.RoleARN = roleARN

	sessionName := profile.RoleSessionName
	if sessionName == "" {
		if options.RoleSessionName != "" {
			sessionName = options.RoleSessionName
		} else {
			if currentPrincipalIsAssumedRole {
				return nil, errAssumedRoleNeedsSessionName
			}
			sessionName, err = app.aws.Username()
			if err != nil {
				return nil, fmt.Errorf("unable to get username from AWS: %v", err)
			}
		}
		profile.RoleSessionName = sessionName
	}

	// We first try to assume role without MFA and if that doesn't work then we
	// try to assume role with MFA. Along the way, we collect errors in a
	// multierr, so that if there is a fatal problem then we can output all
	// errors so the user can see what happened along the way.
	var finalErr error

	// Try to assume role without MFA
	creds, err := app.aws.AssumeRole(roleARN, sessionName)
	if err != nil {
		if IsAWSAccessDeniedError(err) {
			finalErr = multierror.Append(finalErr, fmt.Errorf("error trying to AssumeRole without MFA: %v", err))
		} else {
			// Fail immediately if the error was something other than "access denied"
			return nil, err
		}
	}
	if creds != nil {
		profile.Expires = creds.Expires

		// Save credentials
		if err := app.save(profileName, profile, creds); err != nil {
			return nil, err
		}

		return creds, nil
	}

	if currentPrincipalIsAssumedRole {
		// assumed roles don't have an user name or MFA device associated with them
		return nil, finalErr
	}

	// Get user's MFA device
	mfaDeviceARN, err := app.mfaDevice()
	if err != nil {
		finalErr = multierror.Append(finalErr, fmt.Errorf("error trying to AssumeRole with MFA: %v", err))
		return nil, finalErr
	}
	profile.MFASerial = mfaDeviceARN

	// Get token
	mfaToken, err := app.mfaToken()
	if err != nil {
		finalErr = multierror.Append(finalErr, fmt.Errorf("error trying to AssumeRole with MFA: %v", err))
		return nil, finalErr
	}

	// Assume role
	creds, err = app.aws.AssumeRoleWithMFA(roleARN, sessionName, mfaDeviceARN, mfaToken)
	if err != nil {
		finalErr = multierror.Append(finalErr, fmt.Errorf("error trying to AssumeRole with MFA: %v; giving up", err))
		return nil, finalErr
	}
	profile.Expires = creds.Expires

	// Save credentials
	if err := app.save(profileName, profile, creds); err != nil {
		return nil, err
	}

	return creds, nil
}