in config/configure.go [356:527]
func configureCloudSSO(w io.Writer, cp *Profile) error {
cli.Printf(w, "CloudSSO Sign In Url [%s]: ", cp.CloudSSOSignInUrl)
userInputCloudSSOSignInUrl := ReadInput(cp.CloudSSOSignInUrl)
if userInputCloudSSOSignInUrl != cp.CloudSSOSignInUrl && cp.CloudSSOSignInUrl != "" {
// 需要清空其他的字段,完整的走登录
cp.AccessKeyId = ""
cp.AccessKeySecret = ""
cp.StsToken = ""
cp.CloudSSOAccessConfig = ""
cp.CloudSSOAccountId = ""
cp.CloudSSOSignInUrl = userInputCloudSSOSignInUrl
cp.AccessToken = ""
cp.StsExpiration = 0
cp.CloudSSOAccessTokenExpire = 0
} else {
cp.CloudSSOSignInUrl = userInputCloudSSOSignInUrl
}
if cp.CloudSSOSignInUrl == "" {
return fmt.Errorf("CloudSSOSignInUrl is required")
}
// start login in, get access token, then list account for choose
httpClient := util.NewHttpClient()
ssoLogin := cloudsso.SsoLogin{
SignInUrl: cp.CloudSSOSignInUrl,
// force login
ExpireTime: 0,
HttpClient: httpClient,
}
accessToken, err := cloudssoGetAccessToken(&ssoLogin)
if err != nil {
return fmt.Errorf("get access token failed: %s", err)
}
cp.AccessToken = accessToken.AccessToken
cp.CloudSSOAccessTokenExpire = util.GetCurrentUnixTime() + int64(accessToken.ExpiresIn)
// parse base url
baseUrl, err := url.Parse(ssoLogin.SignInUrl)
// list account for choose
userParameter := cloudsso.ListUserParameter{
AccessToken: cp.AccessToken,
BaseUrl: baseUrl.Scheme + "://" + baseUrl.Host,
HttpClient: httpClient,
}
allUser, err := cloudssoListAllUsers(&userParameter)
if err != nil {
return fmt.Errorf("list account failed: %s", err)
}
// if allUser is empty, return error
if len(allUser) == 0 {
return fmt.Errorf("no account found")
}
accountIdHistory := cp.CloudSSOAccountId
if accountIdHistory != "" {
// 已经指定了账号,检查是否存在,如果不存在需要继续指定
var exist = false
for _, user := range allUser {
if user.AccountId == accountIdHistory {
exist = true
break
}
}
if !exist {
cli.Printf(w, "Account %s not found, please choose again\n", accountIdHistory)
// clear history
cp.CloudSSOAccountId = ""
}
}
if cp.CloudSSOAccountId == "" {
// 只有当账户不存在时才需要重新选择
// if allUser has only one account, use it directly
if len(allUser) == 1 {
cp.CloudSSOAccountId = allUser[0].AccountId
cli.Printf(w, "Account: %s\n", allUser[0].DisplayName)
} else {
// print all user id
cli.Println(w, "Please choose an account:")
for i, user := range allUser {
fmt.Printf("%d. %s\n", i+1, user.DisplayName)
}
cli.Printf(w, "Please input the account number: ")
var accountNumber int
// read input
input := ReadInput("1")
// parse input to int
accountNumber, err = strconv.Atoi(input)
if err != nil {
return fmt.Errorf("invalid account number: %s", err)
}
if accountNumber < 1 || accountNumber > len(allUser) {
return fmt.Errorf("invalid account number")
}
cp.CloudSSOAccountId = allUser[accountNumber-1].AccountId
}
}
// get access configuration
accessConfigurationParameter := cloudsso.AccessConfigurationsParameter{
AccessToken: cp.AccessToken,
UrlPrefix: baseUrl.Scheme + "://" + baseUrl.Host,
HttpClient: httpClient,
AccountId: cp.CloudSSOAccountId,
}
accessConfigurations, err := cloudssoListAllAccessConfigurations(&accessConfigurationParameter, cloudsso.AccessConfigurationsRequest{
AccountId: cp.CloudSSOAccountId,
})
if err != nil {
return fmt.Errorf("list access configuration failed: %s", err)
}
if len(accessConfigurations) == 0 {
return fmt.Errorf("no access configuration found")
}
acHistory := cp.CloudSSOAccessConfig
if acHistory != "" {
// 判断是否存在
var exist = false
for _, accessConfiguration := range accessConfigurations {
if accessConfiguration.AccessConfigurationId == acHistory {
exist = true
break
}
}
if !exist {
cli.Printf(w, "Access Configuration %s not found, please choose again\n", acHistory)
// clear history
cp.CloudSSOAccessConfig = ""
}
}
if cp.CloudSSOAccessConfig == "" {
// if accessConfigurations has only one access configuration, use it directly
if len(accessConfigurations) == 1 {
cp.CloudSSOAccessConfig = accessConfigurations[0].AccessConfigurationId
cli.Printf(w, "Access Configuration: %s\n", accessConfigurations[0].AccessConfigurationId)
} else {
// print all access configuration id
cli.Println(w, "Please choose an access configuration:")
for i, accessConfiguration := range accessConfigurations {
cli.Printf(w, "%d. %s\n", i+1, accessConfiguration.AccessConfigurationName)
}
cli.Printf(w, "Please input the access configuration number: ")
var accessConfigurationNumber int
// read input
input := ReadInput("1")
// parse input to int
accessConfigurationNumber, err = strconv.Atoi(input)
if err != nil {
return fmt.Errorf("invalid access configuration number: %s", err)
}
if accessConfigurationNumber < 1 || accessConfigurationNumber > len(accessConfigurations) {
return fmt.Errorf("invalid access configuration number")
}
cp.CloudSSOAccessConfig = accessConfigurations[accessConfigurationNumber-1].AccessConfigurationId
}
}
// create sts token
stsInfo, err := cloudssoTryRefreshStsToken(&cp.CloudSSOSignInUrl, &cp.AccessToken, &cp.CloudSSOAccessConfig,
&cp.CloudSSOAccountId, httpClient)
if err != nil {
return fmt.Errorf("create sts token failed: %s", err)
}
cp.AccessKeyId = stsInfo.AccessKeyId
cp.AccessKeySecret = stsInfo.AccessKeySecret
cp.StsToken = stsInfo.SecurityToken
// Expiration is UTC time, 2015-04-09T11:52:19Z, convert to int
// Parse the time string
parsedTime, err := time.Parse(time.RFC3339, stsInfo.Expiration)
if err != nil {
return fmt.Errorf("parse expiration time failed: %s", err)
}
// Convert to Unix time (int64)
unixTime := parsedTime.Unix()
cp.StsExpiration = unixTime - 5
return nil
}