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.

der.GetProviderName   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
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
	// Connection timeout, in milliseconds.
44
	ConnectTimeout int
45
	// Read timeout, in milliseconds.
46
	ReadTimeout int
47
}
48
49
type RAMRoleARNCredentialsProvider struct {
50
	// for previous credentials
51
	accessKeyId         string
52
	accessKeySecret     string
53
	securityToken       string
54
	credentialsProvider CredentialsProvider
55
56
	roleArn         string
57
	roleSessionName string
58
	durationSeconds int
59
	policy          string
60
	externalId      string
61
	// for sts endpoint
62
	stsRegionId string
63
	enableVpc   bool
64
	stsEndpoint string
65
	// for http options
66
	httpOptions *HttpOptions
67
	// inner
68
	expirationTimestamp  int64
69
	lastUpdateTimestamp  int64
70
	previousProviderName string
71
	sessionCredentials   *sessionCredentials
72
}
73
74
type RAMRoleARNCredentialsProviderBuilder struct {
75
	provider *RAMRoleARNCredentialsProvider
76
}
77
78
func NewRAMRoleARNCredentialsProviderBuilder() *RAMRoleARNCredentialsProviderBuilder {
79
	return &RAMRoleARNCredentialsProviderBuilder{
80
		provider: &RAMRoleARNCredentialsProvider{},
81
	}
82
}
83
84
func (builder *RAMRoleARNCredentialsProviderBuilder) WithAccessKeyId(accessKeyId string) *RAMRoleARNCredentialsProviderBuilder {
85
	builder.provider.accessKeyId = accessKeyId
86
	return builder
87
}
88
89
func (builder *RAMRoleARNCredentialsProviderBuilder) WithAccessKeySecret(accessKeySecret string) *RAMRoleARNCredentialsProviderBuilder {
90
	builder.provider.accessKeySecret = accessKeySecret
91
	return builder
92
}
93
94
func (builder *RAMRoleARNCredentialsProviderBuilder) WithSecurityToken(securityToken string) *RAMRoleARNCredentialsProviderBuilder {
95
	builder.provider.securityToken = securityToken
96
	return builder
97
}
98
99
func (builder *RAMRoleARNCredentialsProviderBuilder) WithCredentialsProvider(credentialsProvider CredentialsProvider) *RAMRoleARNCredentialsProviderBuilder {
100
	builder.provider.credentialsProvider = credentialsProvider
101
	return builder
102
}
103
104
func (builder *RAMRoleARNCredentialsProviderBuilder) WithRoleArn(roleArn string) *RAMRoleARNCredentialsProviderBuilder {
105
	builder.provider.roleArn = roleArn
106
	return builder
107
}
108
109
func (builder *RAMRoleARNCredentialsProviderBuilder) WithStsRegionId(regionId string) *RAMRoleARNCredentialsProviderBuilder {
110
	builder.provider.stsRegionId = regionId
111
	return builder
112
}
113
114
func (builder *RAMRoleARNCredentialsProviderBuilder) WithEnableVpc(enableVpc bool) *RAMRoleARNCredentialsProviderBuilder {
115
	builder.provider.enableVpc = enableVpc
116
	return builder
117
}
118
119
func (builder *RAMRoleARNCredentialsProviderBuilder) WithStsEndpoint(endpoint string) *RAMRoleARNCredentialsProviderBuilder {
120
	builder.provider.stsEndpoint = endpoint
121
	return builder
122
}
123
124
func (builder *RAMRoleARNCredentialsProviderBuilder) WithRoleSessionName(roleSessionName string) *RAMRoleARNCredentialsProviderBuilder {
125
	builder.provider.roleSessionName = roleSessionName
126
	return builder
127
}
128
129
func (builder *RAMRoleARNCredentialsProviderBuilder) WithPolicy(policy string) *RAMRoleARNCredentialsProviderBuilder {
130
	builder.provider.policy = policy
131
	return builder
132
}
133
134
func (builder *RAMRoleARNCredentialsProviderBuilder) WithExternalId(externalId string) *RAMRoleARNCredentialsProviderBuilder {
135
	builder.provider.externalId = externalId
136
	return builder
137
}
138
139
func (builder *RAMRoleARNCredentialsProviderBuilder) WithDurationSeconds(durationSeconds int) *RAMRoleARNCredentialsProviderBuilder {
140
	builder.provider.durationSeconds = durationSeconds
141
	return builder
142
}
143
144
func (builder *RAMRoleARNCredentialsProviderBuilder) WithHttpOptions(httpOptions *HttpOptions) *RAMRoleARNCredentialsProviderBuilder {
145
	builder.provider.httpOptions = httpOptions
146
	return builder
147
}
148
149
func (builder *RAMRoleARNCredentialsProviderBuilder) Build() (provider *RAMRoleARNCredentialsProvider, err error) {
150
	if builder.provider.credentialsProvider == nil {
151
		if builder.provider.accessKeyId != "" && builder.provider.accessKeySecret != "" && builder.provider.securityToken != "" {
152
			builder.provider.credentialsProvider, err = NewStaticSTSCredentialsProviderBuilder().
153
				WithAccessKeyId(builder.provider.accessKeyId).
154
				WithAccessKeySecret(builder.provider.accessKeySecret).
155
				WithSecurityToken(builder.provider.securityToken).
156
				Build()
157
			if err != nil {
158
				return
159
			}
160
		} else if builder.provider.accessKeyId != "" && builder.provider.accessKeySecret != "" {
161
			builder.provider.credentialsProvider, err = NewStaticAKCredentialsProviderBuilder().
162
				WithAccessKeyId(builder.provider.accessKeyId).
163
				WithAccessKeySecret(builder.provider.accessKeySecret).
164
				Build()
165
			if err != nil {
166
				return
167
			}
168
		} else {
169
			err = errors.New("must specify a previous credentials provider to assume role")
170
			return
171
		}
172
	}
173
174
	if builder.provider.roleArn == "" {
175
		if roleArn := os.Getenv("ALIBABA_CLOUD_ROLE_ARN"); roleArn != "" {
176
			builder.provider.roleArn = roleArn
177
		} else {
178
			err = errors.New("the RoleArn is empty")
179
			return
180
		}
181
	}
182
183
	if builder.provider.roleSessionName == "" {
184
		if roleSessionName := os.Getenv("ALIBABA_CLOUD_ROLE_SESSION_NAME"); roleSessionName != "" {
185
			builder.provider.roleSessionName = roleSessionName
186
		} else {
187
			builder.provider.roleSessionName = "credentials-go-" + strconv.FormatInt(time.Now().UnixNano()/1000, 10)
188
		}
189
	}
190
191
	// duration seconds
192
	if builder.provider.durationSeconds == 0 {
193
		// default to 3600
194
		builder.provider.durationSeconds = 3600
195
	}
196
197
	if builder.provider.durationSeconds < 900 {
198
		err = errors.New("session duration should be in the range of 900s - max session duration")
199
		return
200
	}
201
202
	// sts endpoint
203
	if builder.provider.stsEndpoint == "" {
204
		if !builder.provider.enableVpc {
205
			builder.provider.enableVpc = strings.ToLower(os.Getenv("ALIBABA_CLOUD_VPC_ENDPOINT_ENABLED")) == "true"
206
		}
207
		prefix := "sts"
208
		if builder.provider.enableVpc {
209
			prefix = "sts-vpc"
210
		}
211
		if builder.provider.stsRegionId != "" {
212
			builder.provider.stsEndpoint = fmt.Sprintf("%s.%s.aliyuncs.com", prefix, builder.provider.stsRegionId)
213
		} else if region := os.Getenv("ALIBABA_CLOUD_STS_REGION"); region != "" {
214
			builder.provider.stsEndpoint = fmt.Sprintf("%s.%s.aliyuncs.com", prefix, region)
215
		} else {
216
			builder.provider.stsEndpoint = "sts.aliyuncs.com"
217
		}
218
	}
219
220
	provider = builder.provider
221
	return
222
}
223
224
func (provider *RAMRoleARNCredentialsProvider) getCredentials(cc *Credentials) (session *sessionCredentials, err error) {
225
	method := "POST"
226
	req := &httputil.Request{
227
		Method:   method,
228
		Protocol: "https",
229
		Host:     provider.stsEndpoint,
230
		Headers:  map[string]string{},
231
	}
232
233
	queries := make(map[string]string)
234
	queries["Version"] = "2015-04-01"
235
	queries["Action"] = "AssumeRole"
236
	queries["Format"] = "JSON"
237
	queries["Timestamp"] = utils.GetTimeInFormatISO8601()
238
	queries["SignatureMethod"] = "HMAC-SHA1"
239
	queries["SignatureVersion"] = "1.0"
240
	queries["SignatureNonce"] = utils.GetNonce()
241
	queries["AccessKeyId"] = cc.AccessKeyId
242
243
	if cc.SecurityToken != "" {
244
		queries["SecurityToken"] = cc.SecurityToken
245
	}
246
247
	bodyForm := make(map[string]string)
248
	bodyForm["RoleArn"] = provider.roleArn
249
	if provider.policy != "" {
250
		bodyForm["Policy"] = provider.policy
251
	}
252
	if provider.externalId != "" {
253
		bodyForm["ExternalId"] = provider.externalId
254
	}
255
	bodyForm["RoleSessionName"] = provider.roleSessionName
256
	bodyForm["DurationSeconds"] = strconv.Itoa(provider.durationSeconds)
257
	req.Form = bodyForm
258
259
	// caculate signature
260
	signParams := make(map[string]string)
261
	for key, value := range queries {
262
		signParams[key] = value
263
	}
264
	for key, value := range bodyForm {
265
		signParams[key] = value
266
	}
267
268
	stringToSign := utils.GetURLFormedMap(signParams)
269
	stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
270
	stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
271
	stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
272
	stringToSign = url.QueryEscape(stringToSign)
273
	stringToSign = method + "&%2F&" + stringToSign
274
	secret := cc.AccessKeySecret + "&"
275
	queries["Signature"] = utils.ShaHmac1(stringToSign, secret)
276
277
	req.Queries = queries
278
279
	// set headers
280
	req.Headers["Accept-Encoding"] = "identity"
281
	req.Headers["Content-Type"] = "application/x-www-form-urlencoded"
282
	req.Headers["x-acs-credentials-provider"] = cc.ProviderName
283
284
	connectTimeout := 5 * time.Second
285
	readTimeout := 10 * time.Second
286
287
	if provider.httpOptions != nil && provider.httpOptions.ConnectTimeout > 0 {
288
		connectTimeout = time.Duration(provider.httpOptions.ConnectTimeout) * time.Millisecond
289
	}
290
	if provider.httpOptions != nil && provider.httpOptions.ReadTimeout > 0 {
291
		readTimeout = time.Duration(provider.httpOptions.ReadTimeout) * time.Millisecond
292
	}
293
	if provider.httpOptions != nil && provider.httpOptions.Proxy != "" {
294
		req.Proxy = provider.httpOptions.Proxy
295
	}
296
	req.ConnectTimeout = connectTimeout
297
	req.ReadTimeout = readTimeout
298
299
	res, err := httpDo(req)
300
	if err != nil {
301
		return
302
	}
303
304
	if res.StatusCode != http.StatusOK {
305
		err = errors.New("refresh session token failed: " + string(res.Body))
306
		return
307
	}
308
	var data assumeRoleResponse
309
	err = json.Unmarshal(res.Body, &data)
310
	if err != nil {
311
		err = fmt.Errorf("refresh RoleArn sts token err, json.Unmarshal fail: %s", err.Error())
312
		return
313
	}
314
	if data.Credentials == nil {
315
		err = fmt.Errorf("refresh RoleArn sts token err, fail to get credentials")
316
		return
317
	}
318
319
	if data.Credentials.AccessKeyId == nil || data.Credentials.AccessKeySecret == nil || data.Credentials.SecurityToken == nil {
320
		err = fmt.Errorf("refresh RoleArn sts token err, fail to get credentials")
321
		return
322
	}
323
324
	session = &sessionCredentials{
325
		AccessKeyId:     *data.Credentials.AccessKeyId,
326
		AccessKeySecret: *data.Credentials.AccessKeySecret,
327
		SecurityToken:   *data.Credentials.SecurityToken,
328
		Expiration:      *data.Credentials.Expiration,
329
	}
330
	return
331
}
332
333
func (provider *RAMRoleARNCredentialsProvider) needUpdateCredential() (result bool) {
334
	if provider.expirationTimestamp == 0 {
335
		return true
336
	}
337
338
	return provider.expirationTimestamp-time.Now().Unix() <= 180
339
}
340
341
func (provider *RAMRoleARNCredentialsProvider) GetCredentials() (cc *Credentials, err error) {
342
	if provider.sessionCredentials == nil || provider.needUpdateCredential() {
343
		// 获取前置凭证
344
		previousCredentials, err1 := provider.credentialsProvider.GetCredentials()
345
		if err1 != nil {
346
			return nil, err1
347
		}
348
		sessionCredentials, err2 := provider.getCredentials(previousCredentials)
349
		if err2 != nil {
350
			return nil, err2
351
		}
352
353
		expirationTime, err := time.Parse("2006-01-02T15:04:05Z", sessionCredentials.Expiration)
354
		if err != nil {
355
			return nil, err
356
		}
357
358
		provider.expirationTimestamp = expirationTime.Unix()
359
		provider.lastUpdateTimestamp = time.Now().Unix()
360
		provider.previousProviderName = previousCredentials.ProviderName
361
		provider.sessionCredentials = sessionCredentials
362
	}
363
364
	cc = &Credentials{
365
		AccessKeyId:     provider.sessionCredentials.AccessKeyId,
366
		AccessKeySecret: provider.sessionCredentials.AccessKeySecret,
367
		SecurityToken:   provider.sessionCredentials.SecurityToken,
368
		ProviderName:    fmt.Sprintf("%s/%s", provider.GetProviderName(), provider.previousProviderName),
369
	}
370
	return
371
}
372
373
func (provider *RAMRoleARNCredentialsProvider) GetProviderName() string {
374
	return "ram_role_arn"
375
}
376