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 ( cd6b32...09e2c6 )
by Jackson
08:24
created

r.Build   B

Complexity

Conditions 6

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 16
nop 0
dl 0
loc 28
rs 8.6666
c 0
b 0
f 0
1
package providers
2
3
import (
4
	"encoding/json"
5
	"errors"
6
	"fmt"
7
	"io/ioutil"
8
	"net/http"
9
	"net/url"
10
	"strconv"
11
	"strings"
12
	"time"
13
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 RAMRoleARNCredentialsProvider struct {
41
	credentialsProvider CredentialsProvider
42
	roleArn             string
43
	roleSessionName     string
44
	durationSeconds     int
45
	policy              string
46
	stsRegion           string
47
	externalId          string
48
	// inner
49
	expirationTimestamp int64
50
	lastUpdateTimestamp int64
51
	sessionCredentials  *sessionCredentials
52
}
53
54
type RAMRoleARNCredentialsProviderBuilder struct {
55
	provider *RAMRoleARNCredentialsProvider
56
}
57
58
func NewRAMRoleARNCredentialsProviderBuilder() *RAMRoleARNCredentialsProviderBuilder {
59
	return &RAMRoleARNCredentialsProviderBuilder{
60
		provider: &RAMRoleARNCredentialsProvider{},
61
	}
62
}
63
64
func (builder *RAMRoleARNCredentialsProviderBuilder) WithCredentialsProvider(credentialsProvider CredentialsProvider) *RAMRoleARNCredentialsProviderBuilder {
65
	builder.provider.credentialsProvider = credentialsProvider
66
	return builder
67
}
68
69
func (builder *RAMRoleARNCredentialsProviderBuilder) WithRoleArn(roleArn string) *RAMRoleARNCredentialsProviderBuilder {
70
	builder.provider.roleArn = roleArn
71
	return builder
72
}
73
74
func (builder *RAMRoleARNCredentialsProviderBuilder) WithStsRegion(regionId string) *RAMRoleARNCredentialsProviderBuilder {
75
	builder.provider.stsRegion = regionId
76
	return builder
77
}
78
79
func (builder *RAMRoleARNCredentialsProviderBuilder) WithRoleSessionName(roleSessionName string) *RAMRoleARNCredentialsProviderBuilder {
80
	builder.provider.roleSessionName = roleSessionName
81
	return builder
82
}
83
84
func (builder *RAMRoleARNCredentialsProviderBuilder) WithPolicy(policy string) *RAMRoleARNCredentialsProviderBuilder {
85
	builder.provider.policy = policy
86
	return builder
87
}
88
89
func (builder *RAMRoleARNCredentialsProviderBuilder) WithExternalId(externalId string) *RAMRoleARNCredentialsProviderBuilder {
90
	builder.provider.externalId = externalId
91
	return builder
92
}
93
94
func (builder *RAMRoleARNCredentialsProviderBuilder) WithDurationSeconds(durationSeconds int) *RAMRoleARNCredentialsProviderBuilder {
95
	builder.provider.durationSeconds = durationSeconds
96
	return builder
97
}
98
99
func (builder *RAMRoleARNCredentialsProviderBuilder) Build() (provider *RAMRoleARNCredentialsProvider, err error) {
100
	if builder.provider.credentialsProvider == nil {
101
		err = errors.New("must specify a previous credentials provider to asssume role")
102
		return
103
	}
104
105
	if builder.provider.roleArn == "" {
106
		err = errors.New("the RoleArn is empty")
107
		return
108
	}
109
110
	if builder.provider.roleSessionName == "" {
111
		builder.provider.roleSessionName = "credentials-go-" + strconv.FormatInt(time.Now().UnixNano()/1000, 10)
112
	}
113
114
	// duration seconds
115
	if builder.provider.durationSeconds == 0 {
116
		// default to 3600
117
		builder.provider.durationSeconds = 3600
118
	}
119
120
	if builder.provider.durationSeconds < 900 {
121
		err = errors.New("session duration should be in the range of 900s - max session duration")
122
		return
123
	}
124
125
	provider = builder.provider
126
	return
127
}
128
129
func (provider *RAMRoleARNCredentialsProvider) getCredentials(cc *Credentials) (session *sessionCredentials, err error) {
130
	method := "POST"
131
	var host string
132
	if provider.stsRegion != "" {
133
		host = fmt.Sprintf("sts.%s.aliyuncs.com", provider.stsRegion)
134
	} else {
135
		host = "sts.aliyuncs.com"
136
	}
137
138
	queries := make(map[string]string)
139
	queries["Version"] = "2015-04-01"
140
	queries["Action"] = "AssumeRole"
141
	queries["Format"] = "JSON"
142
	queries["Timestamp"] = utils.GetTimeInFormatISO8601()
143
	queries["SignatureMethod"] = "HMAC-SHA1"
144
	queries["SignatureVersion"] = "1.0"
145
	queries["SignatureNonce"] = utils.GetNonce()
146
	queries["AccessKeyId"] = cc.AccessKeyId
147
	if cc.SecurityToken != "" {
148
		queries["SecurityToken"] = cc.SecurityToken
149
	}
150
151
	bodyForm := make(map[string]string)
152
	bodyForm["RoleArn"] = provider.roleArn
153
	if provider.policy != "" {
154
		bodyForm["Policy"] = provider.policy
155
	}
156
	if provider.externalId != "" {
157
		bodyForm["ExternalId"] = provider.externalId
158
	}
159
	bodyForm["RoleSessionName"] = provider.roleSessionName
160
	bodyForm["DurationSeconds"] = strconv.Itoa(provider.durationSeconds)
161
162
	// caculate signature
163
	signParams := make(map[string]string)
164
	for key, value := range queries {
165
		signParams[key] = value
166
	}
167
	for key, value := range bodyForm {
168
		signParams[key] = value
169
	}
170
171
	stringToSign := utils.GetURLFormedMap(signParams)
172
	stringToSign = strings.Replace(stringToSign, "+", "%20", -1)
173
	stringToSign = strings.Replace(stringToSign, "*", "%2A", -1)
174
	stringToSign = strings.Replace(stringToSign, "%7E", "~", -1)
175
	stringToSign = url.QueryEscape(stringToSign)
176
	stringToSign = method + "&%2F&" + stringToSign
177
	secret := cc.AccessKeySecret + "&"
178
	queries["Signature"] = utils.ShaHmac1(stringToSign, secret)
179
180
	querystring := utils.GetURLFormedMap(queries)
181
	// do request
182
	httpUrl := fmt.Sprintf("https://%s/?%s", host, querystring)
183
184
	body := utils.GetURLFormedMap(bodyForm)
185
186
	httpRequest, err := hookNewRequest(http.NewRequest)(method, httpUrl, strings.NewReader(body))
187
	if err != nil {
188
		return
189
	}
190
191
	// set headers
192
	httpRequest.Header["Accept-Encoding"] = []string{"identity"}
193
	httpRequest.Header["Content-Type"] = []string{"application/x-www-form-urlencoded"}
194
	httpRequest.Header["x-credentials-provider"] = []string{cc.ProviderName}
195
	httpClient := &http.Client{}
196
197
	httpResponse, err := hookDo(httpClient.Do)(httpRequest)
198
	if err != nil {
199
		return
200
	}
201
202
	defer httpResponse.Body.Close()
203
204
	responseBody, err := ioutil.ReadAll(httpResponse.Body)
205
	if err != nil {
206
		return
207
	}
208
209
	if httpResponse.StatusCode != http.StatusOK {
210
		err = errors.New("refresh session token failed: " + string(responseBody))
211
		return
212
	}
213
	var data assumeRoleResponse
214
	err = json.Unmarshal(responseBody, &data)
215
	if err != nil {
216
		err = fmt.Errorf("refresh RoleArn sts token err, json.Unmarshal fail: %s", err.Error())
217
		return
218
	}
219
	if data.Credentials == nil {
220
		err = fmt.Errorf("refresh RoleArn sts token err, fail to get credentials")
221
		return
222
	}
223
224
	if data.Credentials.AccessKeyId == nil || data.Credentials.AccessKeySecret == nil || data.Credentials.SecurityToken == nil {
225
		err = fmt.Errorf("refresh RoleArn sts token err, fail to get credentials")
226
		return
227
	}
228
229
	session = &sessionCredentials{
230
		AccessKeyId:     *data.Credentials.AccessKeyId,
231
		AccessKeySecret: *data.Credentials.AccessKeySecret,
232
		SecurityToken:   *data.Credentials.SecurityToken,
233
		Expiration:      *data.Credentials.Expiration,
234
	}
235
	return
236
}
237
238
func (provider *RAMRoleARNCredentialsProvider) needUpdateCredential() (result bool) {
239
	if provider.expirationTimestamp == 0 {
240
		return true
241
	}
242
243
	return provider.expirationTimestamp-time.Now().Unix() <= 180
244
}
245
246
func (provider *RAMRoleARNCredentialsProvider) GetCredentials() (cc *Credentials, err error) {
247
	if provider.sessionCredentials == nil || provider.needUpdateCredential() {
248
		// 获取前置凭证
249
		previousCredentials, err1 := provider.credentialsProvider.GetCredentials()
250
		if err1 != nil {
251
			return nil, err1
252
		}
253
		sessionCredentials, err2 := provider.getCredentials(previousCredentials)
254
		if err2 != nil {
255
			return nil, err2
256
		}
257
258
		expirationTime, err := time.Parse("2006-01-02T15:04:05Z", sessionCredentials.Expiration)
259
		if err != nil {
260
			return nil, err
261
		}
262
263
		provider.expirationTimestamp = expirationTime.Unix()
264
		provider.lastUpdateTimestamp = time.Now().Unix()
265
		provider.sessionCredentials = sessionCredentials
266
	}
267
268
	cc = &Credentials{
269
		AccessKeyId:     provider.sessionCredentials.AccessKeyId,
270
		AccessKeySecret: provider.sessionCredentials.AccessKeySecret,
271
		SecurityToken:   provider.sessionCredentials.SecurityToken,
272
	}
273
	return
274
}
275