GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( a23516...47c2ea )
by
unknown
07:09
created

credentials/internal/providers/ram_role_arn.go   A

Size/Duplication

Total Lines 301
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 42
eloc 197
dl 0
loc 301
rs 9.0399
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A providers.*RAMRoleARNCredentialsProviderBuilder.WithRoleArn 0 3 1
A providers.NewRAMRoleARNCredentialsProviderBuilder 0 3 1
A providers.*RAMRoleARNCredentialsProviderBuilder.WithStsEndpoint 0 3 1
B providers.*RAMRoleARNCredentialsProvider.GetCredentials 0 29 6
F providers.*RAMRoleARNCredentialsProvider.getCredentials 0 98 14
A providers.*RAMRoleARNCredentialsProviderBuilder.WithExternalId 0 3 1
A providers.*RAMRoleARNCredentialsProvider.needUpdateCredential 0 6 2
A providers.*RAMRoleARNCredentialsProviderBuilder.WithRoleSessionName 0 3 1
C providers.*RAMRoleARNCredentialsProviderBuilder.Build 0 39 9
A providers.*RAMRoleARNCredentialsProviderBuilder.WithHttpOptions 0 3 1
A providers.*RAMRoleARNCredentialsProviderBuilder.WithDurationSeconds 0 3 1
A providers.*RAMRoleARNCredentialsProviderBuilder.WithPolicy 0 3 1
A providers.*RAMRoleARNCredentialsProviderBuilder.WithCredentialsProvider 0 3 1
A providers.*RAMRoleARNCredentialsProvider.GetProviderName 0 2 1
A providers.*RAMRoleARNCredentialsProviderBuilder.WithStsRegionId 0 3 1
1
package providers
2
3
import (
4
	"encoding/json"
5
	"errors"
6
	"fmt"
7
	"net/http"
8
	"net/url"
9
	"os"
10
	"strconv"
11
	"strings"
12
	"time"
13
14
	httputil "github.com/aliyun/credentials-go/credentials/internal/http"
15
	"github.com/aliyun/credentials-go/credentials/internal/utils"
16
)
17
18
type assumedRoleUser struct {
19
}
20
21
type credentials struct {
22
	SecurityToken   *string `json:"SecurityToken"`
23
	Expiration      *string `json:"Expiration"`
24
	AccessKeySecret *string `json:"AccessKeySecret"`
25
	AccessKeyId     *string `json:"AccessKeyId"`
26
}
27
28
type assumeRoleResponse struct {
29
	RequestID       *string          `json:"RequestId"`
30
	AssumedRoleUser *assumedRoleUser `json:"AssumedRoleUser"`
31
	Credentials     *credentials     `json:"Credentials"`
32
}
33
34
type sessionCredentials struct {
35
	AccessKeyId     string
36
	AccessKeySecret string
37
	SecurityToken   string
38
	Expiration      string
39
}
40
41
type HttpOptions struct {
42
	Proxy          string
43
	ConnectTimeout int
44
	ReadTimeout    int
45
}
46
47
type RAMRoleARNCredentialsProvider struct {
48
	credentialsProvider CredentialsProvider
49
	roleArn             string
50
	roleSessionName     string
51
	durationSeconds     int
52
	policy              string
53
	externalId          string
54
	// for sts endpoint
55
	stsRegionId string
56
	stsEndpoint string
57
	// for http options
58
	httpOptions *HttpOptions
59
	// inner
60
	expirationTimestamp int64
61
	lastUpdateTimestamp int64
62
	sessionCredentials  *sessionCredentials
63
}
64
65
type RAMRoleARNCredentialsProviderBuilder struct {
66
	provider *RAMRoleARNCredentialsProvider
67
}
68
69
func NewRAMRoleARNCredentialsProviderBuilder() *RAMRoleARNCredentialsProviderBuilder {
70
	return &RAMRoleARNCredentialsProviderBuilder{
71
		provider: &RAMRoleARNCredentialsProvider{},
72
	}
73
}
74
75
func (builder *RAMRoleARNCredentialsProviderBuilder) WithCredentialsProvider(credentialsProvider CredentialsProvider) *RAMRoleARNCredentialsProviderBuilder {
76
	builder.provider.credentialsProvider = credentialsProvider
77
	return builder
78
}
79
80
func (builder *RAMRoleARNCredentialsProviderBuilder) WithRoleArn(roleArn string) *RAMRoleARNCredentialsProviderBuilder {
81
	builder.provider.roleArn = roleArn
82
	return builder
83
}
84
85
func (builder *RAMRoleARNCredentialsProviderBuilder) WithStsRegionId(regionId string) *RAMRoleARNCredentialsProviderBuilder {
86
	builder.provider.stsRegionId = regionId
87
	return builder
88
}
89
90
func (builder *RAMRoleARNCredentialsProviderBuilder) WithStsEndpoint(endpoint string) *RAMRoleARNCredentialsProviderBuilder {
91
	builder.provider.stsEndpoint = endpoint
92
	return builder
93
}
94
95
func (builder *RAMRoleARNCredentialsProviderBuilder) WithRoleSessionName(roleSessionName string) *RAMRoleARNCredentialsProviderBuilder {
96
	builder.provider.roleSessionName = roleSessionName
97
	return builder
98
}
99
100
func (builder *RAMRoleARNCredentialsProviderBuilder) WithPolicy(policy string) *RAMRoleARNCredentialsProviderBuilder {
101
	builder.provider.policy = policy
102
	return builder
103
}
104
105
func (builder *RAMRoleARNCredentialsProviderBuilder) WithExternalId(externalId string) *RAMRoleARNCredentialsProviderBuilder {
106
	builder.provider.externalId = externalId
107
	return builder
108
}
109
110
func (builder *RAMRoleARNCredentialsProviderBuilder) WithDurationSeconds(durationSeconds int) *RAMRoleARNCredentialsProviderBuilder {
111
	builder.provider.durationSeconds = durationSeconds
112
	return builder
113
}
114
115
func (builder *RAMRoleARNCredentialsProviderBuilder) WithHttpOptions(httpOptions *HttpOptions) *RAMRoleARNCredentialsProviderBuilder {
116
	builder.provider.httpOptions = httpOptions
117
	return builder
118
}
119
120
func (builder *RAMRoleARNCredentialsProviderBuilder) Build() (provider *RAMRoleARNCredentialsProvider, err error) {
121
	if builder.provider.credentialsProvider == nil {
122
		err = errors.New("must specify a previous credentials provider to asssume role")
123
		return
124
	}
125
126
	if builder.provider.roleArn == "" {
127
		err = errors.New("the RoleArn is empty")
128
		return
129
	}
130
131
	if builder.provider.roleSessionName == "" {
132
		builder.provider.roleSessionName = "credentials-go-" + strconv.FormatInt(time.Now().UnixNano()/1000, 10)
133
	}
134
135
	// duration seconds
136
	if builder.provider.durationSeconds == 0 {
137
		// default to 3600
138
		builder.provider.durationSeconds = 3600
139
	}
140
141
	if builder.provider.durationSeconds < 900 {
142
		err = errors.New("session duration should be in the range of 900s - max session duration")
143
		return
144
	}
145
146
	// sts endpoint
147
	if builder.provider.stsEndpoint == "" {
148
		if builder.provider.stsRegionId != "" {
149
			builder.provider.stsEndpoint = fmt.Sprintf("sts.%s.aliyuncs.com", builder.provider.stsRegionId)
150
		} else if region := os.Getenv("ALIBABA_CLOUD_STS_REGION"); region != "" {
151
			builder.provider.stsEndpoint = fmt.Sprintf("sts.%s.aliyuncs.com", region)
152
		} else {
153
			builder.provider.stsEndpoint = "sts.aliyuncs.com"
154
		}
155
	}
156
157
	provider = builder.provider
158
	return
159
}
160
161
func (provider *RAMRoleARNCredentialsProvider) getCredentials(cc *Credentials) (session *sessionCredentials, err error) {
162
	method := "POST"
163
	req := &httputil.Request{
164
		Method:   method,
165
		Protocol: "https",
166
		Host:     provider.stsEndpoint,
167
		Headers:  map[string]string{},
168
	}
169
170
	queries := make(map[string]string)
171
	queries["Version"] = "2015-04-01"
172
	queries["Action"] = "AssumeRole"
173
	queries["Format"] = "JSON"
174
	queries["Timestamp"] = utils.GetTimeInFormatISO8601()
175
	queries["SignatureMethod"] = "HMAC-SHA1"
176
	queries["SignatureVersion"] = "1.0"
177
	queries["SignatureNonce"] = utils.GetNonce()
178
	queries["AccessKeyId"] = cc.AccessKeyId
179
180
	if cc.SecurityToken != "" {
181
		queries["SecurityToken"] = cc.SecurityToken
182
	}
183
184
	bodyForm := make(map[string]string)
185
	bodyForm["RoleArn"] = provider.roleArn
186
	if provider.policy != "" {
187
		bodyForm["Policy"] = provider.policy
188
	}
189
	if provider.externalId != "" {
190
		bodyForm["ExternalId"] = provider.externalId
191
	}
192
	bodyForm["RoleSessionName"] = provider.roleSessionName
193
	bodyForm["DurationSeconds"] = strconv.Itoa(provider.durationSeconds)
194
	req.Form = bodyForm
195
196
	// caculate signature
197
	signParams := make(map[string]string)
198
	for key, value := range queries {
199
		signParams[key] = value
200
	}
201
	for key, value := range bodyForm {
202
		signParams[key] = value
203
	}
204
205
	stringToSign := utils.GetURLFormedMap(signParams)
206
	stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
207
	stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
208
	stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
209
	stringToSign = url.QueryEscape(stringToSign)
210
	stringToSign = method + "&%2F&" + stringToSign
211
	secret := cc.AccessKeySecret + "&"
212
	queries["Signature"] = utils.ShaHmac1(stringToSign, secret)
213
214
	req.Queries = queries
215
216
	// set headers
217
	req.Headers["Accept-Encoding"] = "identity"
218
	req.Headers["Content-Type"] = "application/x-www-form-urlencoded"
219
	req.Headers["x-acs-credentials-provider"] = cc.ProviderName
220
221
	if provider.httpOptions != nil {
222
		req.ConnectTimeout = time.Duration(provider.httpOptions.ConnectTimeout) * time.Second
223
		req.ReadTimeout = time.Duration(provider.httpOptions.ReadTimeout) * time.Second
224
		req.Proxy = provider.httpOptions.Proxy
225
	}
226
227
	res, err := httpDo(req)
228
	if err != nil {
229
		return
230
	}
231
232
	if res.StatusCode != http.StatusOK {
233
		err = errors.New("refresh session token failed: " + string(res.Body))
234
		return
235
	}
236
	var data assumeRoleResponse
237
	err = json.Unmarshal(res.Body, &data)
238
	if err != nil {
239
		err = fmt.Errorf("refresh RoleArn sts token err, json.Unmarshal fail: %s", err.Error())
240
		return
241
	}
242
	if data.Credentials == nil {
243
		err = fmt.Errorf("refresh RoleArn sts token err, fail to get credentials")
244
		return
245
	}
246
247
	if data.Credentials.AccessKeyId == nil || data.Credentials.AccessKeySecret == nil || data.Credentials.SecurityToken == nil {
248
		err = fmt.Errorf("refresh RoleArn sts token err, fail to get credentials")
249
		return
250
	}
251
252
	session = &sessionCredentials{
253
		AccessKeyId:     *data.Credentials.AccessKeyId,
254
		AccessKeySecret: *data.Credentials.AccessKeySecret,
255
		SecurityToken:   *data.Credentials.SecurityToken,
256
		Expiration:      *data.Credentials.Expiration,
257
	}
258
	return
259
}
260
261
func (provider *RAMRoleARNCredentialsProvider) needUpdateCredential() (result bool) {
262
	if provider.expirationTimestamp == 0 {
263
		return true
264
	}
265
266
	return provider.expirationTimestamp-time.Now().Unix() <= 180
267
}
268
269
func (provider *RAMRoleARNCredentialsProvider) GetCredentials() (cc *Credentials, err error) {
270
	if provider.sessionCredentials == nil || provider.needUpdateCredential() {
271
		// 获取前置凭证
272
		previousCredentials, err1 := provider.credentialsProvider.GetCredentials()
273
		if err1 != nil {
274
			return nil, err1
275
		}
276
		sessionCredentials, err2 := provider.getCredentials(previousCredentials)
277
		if err2 != nil {
278
			return nil, err2
279
		}
280
281
		expirationTime, err := time.Parse("2006-01-02T15:04:05Z", sessionCredentials.Expiration)
282
		if err != nil {
283
			return nil, err
284
		}
285
286
		provider.expirationTimestamp = expirationTime.Unix()
287
		provider.lastUpdateTimestamp = time.Now().Unix()
288
		provider.sessionCredentials = sessionCredentials
289
	}
290
291
	cc = &Credentials{
292
		AccessKeyId:     provider.sessionCredentials.AccessKeyId,
293
		AccessKeySecret: provider.sessionCredentials.AccessKeySecret,
294
		SecurityToken:   provider.sessionCredentials.SecurityToken,
295
		ProviderName:    fmt.Sprintf("%s/%s", provider.GetProviderName(), provider.credentialsProvider.GetProviderName()),
296
	}
297
	return
298
}
299
300
func (provider *RAMRoleARNCredentialsProvider) GetProviderName() string {
301
	return "ram_role_arn"
302
}
303