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 ( 25ec51...117080 )
by
unknown
07:44
created

der.GetProviderName   A

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
	"os"
8
	"strconv"
9
	"strings"
10
	"time"
11
12
	httputil "github.com/aliyun/credentials-go/credentials/internal/http"
13
)
14
15
type ECSRAMRoleCredentialsProvider struct {
16
	roleName      string
17
	disableIMDSv1 bool
18
	// for sts
19
	session             *sessionCredentials
20
	expirationTimestamp int64
21
	// for http options
22
	httpOptions *HttpOptions
23
}
24
25
type ECSRAMRoleCredentialsProviderBuilder struct {
26
	provider *ECSRAMRoleCredentialsProvider
27
}
28
29
func NewECSRAMRoleCredentialsProviderBuilder() *ECSRAMRoleCredentialsProviderBuilder {
30
	return &ECSRAMRoleCredentialsProviderBuilder{
31
		provider: &ECSRAMRoleCredentialsProvider{},
32
	}
33
}
34
35
func (builder *ECSRAMRoleCredentialsProviderBuilder) WithRoleName(roleName string) *ECSRAMRoleCredentialsProviderBuilder {
36
	builder.provider.roleName = roleName
37
	return builder
38
}
39
40
func (builder *ECSRAMRoleCredentialsProviderBuilder) WithDisableIMDSv1(disableIMDSv1 bool) *ECSRAMRoleCredentialsProviderBuilder {
41
	builder.provider.disableIMDSv1 = disableIMDSv1
42
	return builder
43
}
44
45
func (builder *ECSRAMRoleCredentialsProviderBuilder) WithHttpOptions(httpOptions *HttpOptions) *ECSRAMRoleCredentialsProviderBuilder {
46
	builder.provider.httpOptions = httpOptions
47
	return builder
48
}
49
50
const defaultMetadataTokenDuration = 21600 // 6 hours
51
52
func (builder *ECSRAMRoleCredentialsProviderBuilder) Build() (provider *ECSRAMRoleCredentialsProvider, err error) {
53
54
	if strings.ToLower(os.Getenv("ALIBABA_CLOUD_ECS_METADATA_DISABLED")) == "true" {
55
		err = errors.New("IMDS credentials is disabled")
56
		return
57
	}
58
59
	// 设置 roleName 默认值
60
	if builder.provider.roleName == "" {
61
		builder.provider.roleName = os.Getenv("ALIBABA_CLOUD_ECS_METADATA")
62
	}
63
64
	if !builder.provider.disableIMDSv1 {
65
		builder.provider.disableIMDSv1 = strings.ToLower(os.Getenv("ALIBABA_CLOUD_IMDSV1_DISABLED")) == "true"
66
	}
67
68
	provider = builder.provider
69
	return
70
}
71
72
type ecsRAMRoleResponse struct {
73
	Code            *string `json:"Code"`
74
	AccessKeyId     *string `json:"AccessKeyId"`
75
	AccessKeySecret *string `json:"AccessKeySecret"`
76
	SecurityToken   *string `json:"SecurityToken"`
77
	LastUpdated     *string `json:"LastUpdated"`
78
	Expiration      *string `json:"Expiration"`
79
}
80
81
func (provider *ECSRAMRoleCredentialsProvider) needUpdateCredential() bool {
82
	if provider.expirationTimestamp == 0 {
83
		return true
84
	}
85
86
	return provider.expirationTimestamp-time.Now().Unix() <= 180
87
}
88
89
func (provider *ECSRAMRoleCredentialsProvider) getRoleName() (roleName string, err error) {
90
	req := &httputil.Request{
91
		Method:   "GET",
92
		Protocol: "http",
93
		Host:     "100.100.100.200",
94
		Path:     "/latest/meta-data/ram/security-credentials/",
95
		Headers:  map[string]string{},
96
	}
97
98
	connectTimeout := 1 * time.Second
99
	readTimeout := 1 * time.Second
100
101
	if provider.httpOptions != nil && provider.httpOptions.ConnectTimeout > 0 {
102
		connectTimeout = time.Duration(provider.httpOptions.ConnectTimeout) * time.Millisecond
103
	}
104
	if provider.httpOptions != nil && provider.httpOptions.ReadTimeout > 0 {
105
		readTimeout = time.Duration(provider.httpOptions.ReadTimeout) * time.Millisecond
106
	}
107
	if provider.httpOptions != nil && provider.httpOptions.Proxy != "" {
108
		req.Proxy = provider.httpOptions.Proxy
109
	}
110
	req.ConnectTimeout = connectTimeout
111
	req.ReadTimeout = readTimeout
112
113
	metadataToken, err := provider.getMetadataToken()
114
	if err != nil {
115
		return "", err
116
	}
117
	if metadataToken != "" {
118
		req.Headers["x-aliyun-ecs-metadata-token"] = metadataToken
119
	}
120
121
	res, err := httpDo(req)
122
	if err != nil {
123
		err = fmt.Errorf("get role name failed: %s", err.Error())
124
		return
125
	}
126
127
	if res.StatusCode != 200 {
128
		err = fmt.Errorf("get role name failed: %s %d", req.BuildRequestURL(), res.StatusCode)
129
		return
130
	}
131
132
	roleName = strings.TrimSpace(string(res.Body))
133
	return
134
}
135
136
func (provider *ECSRAMRoleCredentialsProvider) getCredentials() (session *sessionCredentials, err error) {
137
	roleName := provider.roleName
138
	if roleName == "" {
139
		roleName, err = provider.getRoleName()
140
		if err != nil {
141
			return
142
		}
143
	}
144
145
	req := &httputil.Request{
146
		Method:   "GET",
147
		Protocol: "http",
148
		Host:     "100.100.100.200",
149
		Path:     "/latest/meta-data/ram/security-credentials/" + roleName,
150
		Headers:  map[string]string{},
151
	}
152
153
	connectTimeout := 1 * time.Second
154
	readTimeout := 1 * time.Second
155
156
	if provider.httpOptions != nil && provider.httpOptions.ConnectTimeout > 0 {
157
		connectTimeout = time.Duration(provider.httpOptions.ConnectTimeout) * time.Millisecond
158
	}
159
	if provider.httpOptions != nil && provider.httpOptions.ReadTimeout > 0 {
160
		readTimeout = time.Duration(provider.httpOptions.ReadTimeout) * time.Millisecond
161
	}
162
	if provider.httpOptions != nil && provider.httpOptions.Proxy != "" {
163
		req.Proxy = provider.httpOptions.Proxy
164
	}
165
	req.ConnectTimeout = connectTimeout
166
	req.ReadTimeout = readTimeout
167
168
	metadataToken, err := provider.getMetadataToken()
169
	if err != nil {
170
		return nil, err
171
	}
172
	if metadataToken != "" {
173
		req.Headers["x-aliyun-ecs-metadata-token"] = metadataToken
174
	}
175
176
	res, err := httpDo(req)
177
	if err != nil {
178
		err = fmt.Errorf("refresh Ecs sts token err: %s", err.Error())
179
		return
180
	}
181
182
	if res.StatusCode != 200 {
183
		err = fmt.Errorf("refresh Ecs sts token err, httpStatus: %d, message = %s", res.StatusCode, string(res.Body))
184
		return
185
	}
186
187
	var data ecsRAMRoleResponse
188
	err = json.Unmarshal(res.Body, &data)
189
	if err != nil {
190
		err = fmt.Errorf("refresh Ecs sts token err, json.Unmarshal fail: %s", err.Error())
191
		return
192
	}
193
194
	if data.AccessKeyId == nil || data.AccessKeySecret == nil || data.SecurityToken == nil {
195
		err = fmt.Errorf("refresh Ecs sts token err, fail to get credentials")
196
		return
197
	}
198
199
	if *data.Code != "Success" {
200
		err = fmt.Errorf("refresh Ecs sts token err, Code is not Success")
201
		return
202
	}
203
204
	session = &sessionCredentials{
205
		AccessKeyId:     *data.AccessKeyId,
206
		AccessKeySecret: *data.AccessKeySecret,
207
		SecurityToken:   *data.SecurityToken,
208
		Expiration:      *data.Expiration,
209
	}
210
	return
211
}
212
213
func (provider *ECSRAMRoleCredentialsProvider) GetCredentials() (cc *Credentials, err error) {
214
	if provider.session == nil || provider.needUpdateCredential() {
215
		session, err1 := provider.getCredentials()
216
		if err1 != nil {
217
			return nil, err1
218
		}
219
220
		provider.session = session
221
		expirationTime, err2 := time.Parse("2006-01-02T15:04:05Z", session.Expiration)
222
		if err2 != nil {
223
			return nil, err2
224
		}
225
		provider.expirationTimestamp = expirationTime.Unix()
226
	}
227
228
	cc = &Credentials{
229
		AccessKeyId:     provider.session.AccessKeyId,
230
		AccessKeySecret: provider.session.AccessKeySecret,
231
		SecurityToken:   provider.session.SecurityToken,
232
		ProviderName:    provider.GetProviderName(),
233
	}
234
	return
235
}
236
237
func (provider *ECSRAMRoleCredentialsProvider) GetProviderName() string {
238
	return "ecs_ram_role"
239
}
240
241
func (provider *ECSRAMRoleCredentialsProvider) getMetadataToken() (metadataToken string, err error) {
242
	// PUT http://100.100.100.200/latest/api/token
243
	req := &httputil.Request{
244
		Method:   "PUT",
245
		Protocol: "http",
246
		Host:     "100.100.100.200",
247
		Path:     "/latest/api/token",
248
		Headers: map[string]string{
249
			"X-aliyun-ecs-metadata-token-ttl-seconds": strconv.Itoa(defaultMetadataTokenDuration),
250
		},
251
	}
252
253
	connectTimeout := 1 * time.Second
254
	readTimeout := 1 * time.Second
255
256
	if provider.httpOptions != nil && provider.httpOptions.ConnectTimeout > 0 {
257
		connectTimeout = time.Duration(provider.httpOptions.ConnectTimeout) * time.Millisecond
258
	}
259
	if provider.httpOptions != nil && provider.httpOptions.ReadTimeout > 0 {
260
		readTimeout = time.Duration(provider.httpOptions.ReadTimeout) * time.Millisecond
261
	}
262
	if provider.httpOptions != nil && provider.httpOptions.Proxy != "" {
263
		req.Proxy = provider.httpOptions.Proxy
264
	}
265
	req.ConnectTimeout = connectTimeout
266
	req.ReadTimeout = readTimeout
267
268
	res, _err := httpDo(req)
269
	if _err != nil {
270
		if provider.disableIMDSv1 {
271
			err = fmt.Errorf("get metadata token failed: %s", _err.Error())
272
		}
273
		return
274
	}
275
	if res.StatusCode != 200 {
276
		if provider.disableIMDSv1 {
277
			err = fmt.Errorf("refresh Ecs sts token err, httpStatus: %d, message = %s", res.StatusCode, string(res.Body))
278
		}
279
		return
280
	}
281
	metadataToken = string(res.Body)
282
	return
283
}
284