uri_credential.go raw

   1  package credentials
   2  
   3  import (
   4  	"encoding/json"
   5  	"fmt"
   6  	"os"
   7  	"time"
   8  
   9  	"github.com/alibabacloud-go/tea/tea"
  10  	"github.com/aliyun/credentials-go/credentials/internal/utils"
  11  	"github.com/aliyun/credentials-go/credentials/request"
  12  )
  13  
  14  // URLCredential is a kind of credential
  15  type URLCredentialsProvider struct {
  16  	URL string
  17  	*credentialUpdater
  18  	*sessionCredential
  19  	runtime *utils.Runtime
  20  }
  21  
  22  type URLResponse struct {
  23  	AccessKeyId     string `json:"AccessKeyId" xml:"AccessKeyId"`
  24  	AccessKeySecret string `json:"AccessKeySecret" xml:"AccessKeySecret"`
  25  	SecurityToken   string `json:"SecurityToken" xml:"SecurityToken"`
  26  	Expiration      string `json:"Expiration" xml:"Expiration"`
  27  }
  28  
  29  func newURLCredential(URL string) *URLCredentialsProvider {
  30  	credentialUpdater := new(credentialUpdater)
  31  	if URL == "" {
  32  		URL = os.Getenv("ALIBABA_CLOUD_CREDENTIALS_URI")
  33  	}
  34  	return &URLCredentialsProvider{
  35  		URL:               URL,
  36  		credentialUpdater: credentialUpdater,
  37  	}
  38  }
  39  
  40  func (e *URLCredentialsProvider) GetCredential() (*CredentialModel, error) {
  41  	if e.sessionCredential == nil || e.needUpdateCredential() {
  42  		err := e.updateCredential()
  43  		if err != nil {
  44  			return nil, err
  45  		}
  46  	}
  47  	credential := &CredentialModel{
  48  		AccessKeyId:     tea.String(e.sessionCredential.AccessKeyId),
  49  		AccessKeySecret: tea.String(e.sessionCredential.AccessKeySecret),
  50  		SecurityToken:   tea.String(e.sessionCredential.SecurityToken),
  51  		Type:            tea.String("credential_uri"),
  52  	}
  53  	return credential, nil
  54  }
  55  
  56  // GetAccessKeyId reutrns  URLCredential's AccessKeyId
  57  // if AccessKeyId is not exist or out of date, the function will update it.
  58  func (e *URLCredentialsProvider) GetAccessKeyId() (accessKeyId *string, err error) {
  59  	c, err := e.GetCredential()
  60  	if err != nil {
  61  		return
  62  	}
  63  	accessKeyId = c.AccessKeyId
  64  	return
  65  }
  66  
  67  // GetAccessSecret reutrns  URLCredential's AccessKeySecret
  68  // if AccessKeySecret is not exist or out of date, the function will update it.
  69  func (e *URLCredentialsProvider) GetAccessKeySecret() (accessKeySecret *string, err error) {
  70  	c, err := e.GetCredential()
  71  	if err != nil {
  72  		return
  73  	}
  74  	accessKeySecret = c.AccessKeySecret
  75  	return
  76  }
  77  
  78  // GetSecurityToken reutrns  URLCredential's SecurityToken
  79  // if SecurityToken is not exist or out of date, the function will update it.
  80  func (e *URLCredentialsProvider) GetSecurityToken() (securityToken *string, err error) {
  81  	c, err := e.GetCredential()
  82  	if err != nil {
  83  		return
  84  	}
  85  	securityToken = c.SecurityToken
  86  	return
  87  }
  88  
  89  // GetBearerToken is useless for URLCredential
  90  func (e *URLCredentialsProvider) GetBearerToken() *string {
  91  	return tea.String("")
  92  }
  93  
  94  // GetType reutrns  URLCredential's type
  95  func (e *URLCredentialsProvider) GetType() *string {
  96  	return tea.String("credential_uri")
  97  }
  98  
  99  func (e *URLCredentialsProvider) updateCredential() (err error) {
 100  	if e.runtime == nil {
 101  		e.runtime = new(utils.Runtime)
 102  	}
 103  	request := request.NewCommonRequest()
 104  	request.URL = e.URL
 105  	request.Method = "GET"
 106  	content, err := doAction(request, e.runtime)
 107  	if err != nil {
 108  		return fmt.Errorf("get credentials from %s failed with error: %s", e.URL, err.Error())
 109  	}
 110  	var resp *URLResponse
 111  	err = json.Unmarshal(content, &resp)
 112  	if err != nil {
 113  		return fmt.Errorf("get credentials from %s failed with error, json unmarshal fail: %s", e.URL, err.Error())
 114  	}
 115  	if resp.AccessKeyId == "" || resp.AccessKeySecret == "" || resp.SecurityToken == "" || resp.Expiration == "" {
 116  		return fmt.Errorf("get credentials failed: AccessKeyId: %s, AccessKeySecret: %s, SecurityToken: %s, Expiration: %s", resp.AccessKeyId, resp.AccessKeySecret, resp.SecurityToken, resp.Expiration)
 117  	}
 118  
 119  	expirationTime, err := time.Parse("2006-01-02T15:04:05Z", resp.Expiration)
 120  	e.lastUpdateTimestamp = time.Now().Unix()
 121  	e.credentialExpiration = int(expirationTime.Unix() - time.Now().Unix())
 122  	e.sessionCredential = &sessionCredential{
 123  		AccessKeyId:     resp.AccessKeyId,
 124  		AccessKeySecret: resp.AccessKeySecret,
 125  		SecurityToken:   resp.SecurityToken,
 126  	}
 127  
 128  	return
 129  }
 130