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 ( cde461...24f869 )
by
unknown
06:55
created

r.Build   B

Complexity

Conditions 8

Size

Total Lines 37
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

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