package credentials import ( "encoding/json" "fmt" "os" "time" "github.com/alibabacloud-go/tea/tea" "github.com/aliyun/credentials-go/credentials/request" "github.com/aliyun/credentials-go/credentials/utils" ) // URLCredential is a kind of credential type URLCredential struct { URL string *credentialUpdater *sessionCredential runtime *utils.Runtime } type URLResponse struct { AccessKeyId string `json:"AccessKeyId" xml:"AccessKeyId"` AccessKeySecret string `json:"AccessKeySecret" xml:"AccessKeySecret"` SecurityToken string `json:"SecurityToken" xml:"SecurityToken"` Expiration string `json:"Expiration" xml:"Expiration"` } func newURLCredential(URL string) *URLCredential { credentialUpdater := new(credentialUpdater) if URL == "" { URL = os.Getenv("ALIBABA_CLOUD_CREDENTIALS_URI") } return &URLCredential{ URL: URL, credentialUpdater: credentialUpdater, } } func (e *URLCredential) GetCredential() (*CredentialModel, error) { if e.sessionCredential == nil || e.needUpdateCredential() { err := e.updateCredential() if err != nil { return nil, err } } credential := &CredentialModel{ AccessKeyId: tea.String(e.sessionCredential.AccessKeyId), AccessKeySecret: tea.String(e.sessionCredential.AccessKeySecret), SecurityToken: tea.String(e.sessionCredential.SecurityToken), Type: tea.String("credential_uri"), } return credential, nil } // GetAccessKeyId reutrns URLCredential's AccessKeyId // if AccessKeyId is not exist or out of date, the function will update it. func (e *URLCredential) GetAccessKeyId() (*string, error) { if e.sessionCredential == nil || e.needUpdateCredential() { err := e.updateCredential() if err != nil { if e.credentialExpiration > (int(time.Now().Unix()) - int(e.lastUpdateTimestamp)) { return &e.sessionCredential.AccessKeyId, nil } return tea.String(""), err } } return tea.String(e.sessionCredential.AccessKeyId), nil } // GetAccessSecret reutrns URLCredential's AccessKeySecret // if AccessKeySecret is not exist or out of date, the function will update it. func (e *URLCredential) GetAccessKeySecret() (*string, error) { if e.sessionCredential == nil || e.needUpdateCredential() { err := e.updateCredential() if err != nil { if e.credentialExpiration > (int(time.Now().Unix()) - int(e.lastUpdateTimestamp)) { return &e.sessionCredential.AccessKeySecret, nil } return tea.String(""), err } } return tea.String(e.sessionCredential.AccessKeySecret), nil } // GetSecurityToken reutrns URLCredential's SecurityToken // if SecurityToken is not exist or out of date, the function will update it. func (e *URLCredential) GetSecurityToken() (*string, error) { if e.sessionCredential == nil || e.needUpdateCredential() { err := e.updateCredential() if err != nil { if e.credentialExpiration > (int(time.Now().Unix()) - int(e.lastUpdateTimestamp)) { return &e.sessionCredential.SecurityToken, nil } return tea.String(""), err } } return tea.String(e.sessionCredential.SecurityToken), nil } // GetBearerToken is useless for URLCredential func (e *URLCredential) GetBearerToken() *string { return tea.String("") } // GetType reutrns URLCredential's type func (e *URLCredential) GetType() *string { return tea.String("credential_uri") } func (e *URLCredential) updateCredential() (err error) { if e.runtime == nil { e.runtime = new(utils.Runtime) } request := request.NewCommonRequest() request.URL = e.URL request.Method = "GET" content, err := doAction(request, e.runtime) if err != nil { return fmt.Errorf("refresh Ecs sts token err: %s", err.Error()) } var resp *URLResponse err = json.Unmarshal(content, &resp) if err != nil { return fmt.Errorf("refresh Ecs sts token err: Json Unmarshal fail: %s", err.Error()) } if resp.AccessKeyId == "" || resp.AccessKeySecret == "" || resp.SecurityToken == "" || resp.Expiration == "" { return fmt.Errorf("refresh Ecs sts token err: AccessKeyId: %s, AccessKeySecret: %s, SecurityToken: %s, Expiration: %s", resp.AccessKeyId, resp.AccessKeySecret, resp.SecurityToken, resp.Expiration) } expirationTime, err := time.Parse("2006-01-02T15:04:05Z", resp.Expiration) e.lastUpdateTimestamp = time.Now().Unix() e.credentialExpiration = int(expirationTime.Unix() - time.Now().Unix()) e.sessionCredential = &sessionCredential{ AccessKeyId: resp.AccessKeyId, AccessKeySecret: resp.AccessKeySecret, SecurityToken: resp.SecurityToken, } return }