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