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.

credentials.NewCredential   F
last analyzed

Complexity

Conditions 25

Size

Total Lines 153
Code Lines 125

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 25
eloc 125
nop 1
dl 0
loc 153
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like credentials.NewCredential often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package credentials
2
3
import (
4
	"bufio"
5
	"errors"
6
	"fmt"
7
	"net/http"
8
	"net/url"
9
	"os"
10
	"strings"
11
	"time"
12
13
	"github.com/alibabacloud-go/debug/debug"
14
	"github.com/alibabacloud-go/tea/tea"
15
	"github.com/aliyun/credentials-go/credentials/internal/utils"
16
	"github.com/aliyun/credentials-go/credentials/providers"
17
	"github.com/aliyun/credentials-go/credentials/request"
18
	"github.com/aliyun/credentials-go/credentials/response"
19
)
20
21
var debuglog = debug.Init("credential")
22
23
var hookParse = func(err error) error {
24
	return err
25
}
26
27
// Credential is an interface for getting actual credential
28
type Credential interface {
29
	// Deprecated: GetAccessKeyId is deprecated, use GetCredential instead of.
30
	GetAccessKeyId() (*string, error)
31
	// Deprecated: GetAccessKeySecret is deprecated, use GetCredential instead of.
32
	GetAccessKeySecret() (*string, error)
33
	// Deprecated: GetSecurityToken is deprecated, use GetCredential instead of.
34
	GetSecurityToken() (*string, error)
35
	GetBearerToken() *string
36
	GetType() *string
37
	GetCredential() (*CredentialModel, error)
38
}
39
40
// Config is important when call NewCredential
41
type Config struct {
42
	// Credential type, including access_key, sts, bearer, ecs_ram_role, ram_role_arn, rsa_key_pair, oidc_role_arn, credentials_uri
43
	Type            *string `json:"type"`
44
	AccessKeyId     *string `json:"access_key_id"`
45
	AccessKeySecret *string `json:"access_key_secret"`
46
	SecurityToken   *string `json:"security_token"`
47
	BearerToken     *string `json:"bearer_token"`
48
49
	// Used when the type is ram_role_arn or oidc_role_arn
50
	OIDCProviderArn       *string `json:"oidc_provider_arn"`
51
	OIDCTokenFilePath     *string `json:"oidc_token"`
52
	RoleArn               *string `json:"role_arn"`
53
	RoleSessionName       *string `json:"role_session_name"`
54
	RoleSessionExpiration *int    `json:"role_session_expiration"`
55
	Policy                *string `json:"policy"`
56
	ExternalId            *string `json:"external_id"`
57
	STSEndpoint           *string `json:"sts_endpoint"`
58
59
	// Used when the type is ecs_ram_role
60
	RoleName *string `json:"role_name"`
61
	// Deprecated
62
	EnableIMDSv2  *bool `json:"enable_imds_v2"`
63
	DisableIMDSv1 *bool `json:"disable_imds_v1"`
64
	// Deprecated
65
	MetadataTokenDuration *int `json:"metadata_token_duration"`
66
67
	// Used when the type is credentials_uri
68
	Url *string `json:"url"`
69
70
	// Deprecated
71
	// Used when the type is rsa_key_pair
72
	SessionExpiration *int    `json:"session_expiration"`
73
	PublicKeyId       *string `json:"public_key_id"`
74
	PrivateKeyFile    *string `json:"private_key_file"`
75
	Host              *string `json:"host"`
76
77
	// Read timeout, in milliseconds.
78
	// The default value for ecs_ram_role is 1000ms, the default value for ram_role_arn is 5000ms, and the default value for oidc_role_arn is 5000ms.
79
	Timeout *int `json:"timeout"`
80
	// Connection timeout, in milliseconds.
81
	// The default value for ecs_ram_role is 1000ms, the default value for ram_role_arn is 10000ms, and the default value for oidc_role_arn is 10000ms.
82
	ConnectTimeout *int `json:"connect_timeout"`
83
84
	Proxy          *string  `json:"proxy"`
85
	InAdvanceScale *float64 `json:"inAdvanceScale"`
86
}
87
88
func (s Config) String() string {
89
	return tea.Prettify(s)
90
}
91
92
func (s Config) GoString() string {
93
	return s.String()
94
}
95
96
func (s *Config) SetAccessKeyId(v string) *Config {
97
	s.AccessKeyId = &v
98
	return s
99
}
100
101
func (s *Config) SetAccessKeySecret(v string) *Config {
102
	s.AccessKeySecret = &v
103
	return s
104
}
105
106
func (s *Config) SetSecurityToken(v string) *Config {
107
	s.SecurityToken = &v
108
	return s
109
}
110
111
func (s *Config) SetRoleArn(v string) *Config {
112
	s.RoleArn = &v
113
	return s
114
}
115
116
func (s *Config) SetRoleSessionName(v string) *Config {
117
	s.RoleSessionName = &v
118
	return s
119
}
120
121
func (s *Config) SetPublicKeyId(v string) *Config {
122
	s.PublicKeyId = &v
123
	return s
124
}
125
126
func (s *Config) SetRoleName(v string) *Config {
127
	s.RoleName = &v
128
	return s
129
}
130
131
func (s *Config) SetEnableIMDSv2(v bool) *Config {
132
	s.EnableIMDSv2 = &v
133
	return s
134
}
135
136
func (s *Config) SetDisableIMDSv1(v bool) *Config {
137
	s.DisableIMDSv1 = &v
138
	return s
139
}
140
141
func (s *Config) SetMetadataTokenDuration(v int) *Config {
142
	s.MetadataTokenDuration = &v
143
	return s
144
}
145
146
func (s *Config) SetSessionExpiration(v int) *Config {
147
	s.SessionExpiration = &v
148
	return s
149
}
150
151
func (s *Config) SetPrivateKeyFile(v string) *Config {
152
	s.PrivateKeyFile = &v
153
	return s
154
}
155
156
func (s *Config) SetBearerToken(v string) *Config {
157
	s.BearerToken = &v
158
	return s
159
}
160
161
func (s *Config) SetRoleSessionExpiration(v int) *Config {
162
	s.RoleSessionExpiration = &v
163
	return s
164
}
165
166
func (s *Config) SetPolicy(v string) *Config {
167
	s.Policy = &v
168
	return s
169
}
170
171
func (s *Config) SetHost(v string) *Config {
172
	s.Host = &v
173
	return s
174
}
175
176
func (s *Config) SetTimeout(v int) *Config {
177
	s.Timeout = &v
178
	return s
179
}
180
181
func (s *Config) SetConnectTimeout(v int) *Config {
182
	s.ConnectTimeout = &v
183
	return s
184
}
185
186
func (s *Config) SetProxy(v string) *Config {
187
	s.Proxy = &v
188
	return s
189
}
190
191
func (s *Config) SetType(v string) *Config {
192
	s.Type = &v
193
	return s
194
}
195
196
func (s *Config) SetOIDCTokenFilePath(v string) *Config {
197
	s.OIDCTokenFilePath = &v
198
	return s
199
}
200
201
func (s *Config) SetOIDCProviderArn(v string) *Config {
202
	s.OIDCProviderArn = &v
203
	return s
204
}
205
206
func (s *Config) SetURLCredential(v string) *Config {
207
	if v == "" {
208
		v = os.Getenv("ALIBABA_CLOUD_CREDENTIALS_URI")
209
	}
210
	s.Url = &v
211
	return s
212
}
213
214
func (s *Config) SetSTSEndpoint(v string) *Config {
215
	s.STSEndpoint = &v
216
	return s
217
}
218
219
func (s *Config) SetExternalId(v string) *Config {
220
	s.ExternalId = &v
221
	return s
222
}
223
224
// NewCredential return a credential according to the type in config.
225
// if config is nil, the function will use default provider chain to get credentials.
226
// please see README.md for detail.
227
func NewCredential(config *Config) (credential Credential, err error) {
228
	if config == nil {
229
		provider := providers.NewDefaultCredentialsProvider()
230
		credential = FromCredentialsProvider("default", provider)
231
		return
232
	}
233
	switch tea.StringValue(config.Type) {
234
	case "credentials_uri":
235
		provider, err := providers.NewURLCredentialsProviderBuilder().
236
			WithUrl(tea.StringValue(config.Url)).
237
			WithHttpOptions(&providers.HttpOptions{
238
				Proxy:          tea.StringValue(config.Proxy),
239
				ReadTimeout:    tea.IntValue(config.Timeout),
240
				ConnectTimeout: tea.IntValue(config.ConnectTimeout),
241
			}).
242
			Build()
243
244
		if err != nil {
245
			return nil, err
246
		}
247
		credential = FromCredentialsProvider("credentials_uri", provider)
248
	case "oidc_role_arn":
249
		provider, err := providers.NewOIDCCredentialsProviderBuilder().
250
			WithRoleArn(tea.StringValue(config.RoleArn)).
251
			WithOIDCTokenFilePath(tea.StringValue(config.OIDCTokenFilePath)).
252
			WithOIDCProviderARN(tea.StringValue(config.OIDCProviderArn)).
253
			WithDurationSeconds(tea.IntValue(config.RoleSessionExpiration)).
254
			WithPolicy(tea.StringValue(config.Policy)).
255
			WithRoleSessionName(tea.StringValue(config.RoleSessionName)).
256
			WithSTSEndpoint(tea.StringValue(config.STSEndpoint)).
257
			WithHttpOptions(&providers.HttpOptions{
258
				Proxy:          tea.StringValue(config.Proxy),
259
				ReadTimeout:    tea.IntValue(config.Timeout),
260
				ConnectTimeout: tea.IntValue(config.ConnectTimeout),
261
			}).
262
			Build()
263
264
		if err != nil {
265
			return nil, err
266
		}
267
		credential = FromCredentialsProvider("oidc_role_arn", provider)
268
	case "access_key":
269
		provider, err := providers.NewStaticAKCredentialsProviderBuilder().
270
			WithAccessKeyId(tea.StringValue(config.AccessKeyId)).
271
			WithAccessKeySecret(tea.StringValue(config.AccessKeySecret)).
272
			Build()
273
		if err != nil {
274
			return nil, err
275
		}
276
277
		credential = FromCredentialsProvider("access_key", provider)
278
	case "sts":
279
		provider, err := providers.NewStaticSTSCredentialsProviderBuilder().
280
			WithAccessKeyId(tea.StringValue(config.AccessKeyId)).
281
			WithAccessKeySecret(tea.StringValue(config.AccessKeySecret)).
282
			WithSecurityToken(tea.StringValue(config.SecurityToken)).
283
			Build()
284
		if err != nil {
285
			return nil, err
286
		}
287
288
		credential = FromCredentialsProvider("sts", provider)
289
	case "ecs_ram_role":
290
		provider, err := providers.NewECSRAMRoleCredentialsProviderBuilder().
291
			WithRoleName(tea.StringValue(config.RoleName)).
292
			WithDisableIMDSv1(tea.BoolValue(config.DisableIMDSv1)).
293
			Build()
294
295
		if err != nil {
296
			return nil, err
297
		}
298
299
		credential = FromCredentialsProvider("ecs_ram_role", provider)
300
	case "ram_role_arn":
301
		var credentialsProvider providers.CredentialsProvider
302
		if config.SecurityToken != nil && *config.SecurityToken != "" {
303
			credentialsProvider, err = providers.NewStaticSTSCredentialsProviderBuilder().
304
				WithAccessKeyId(tea.StringValue(config.AccessKeyId)).
305
				WithAccessKeySecret(tea.StringValue(config.AccessKeySecret)).
306
				WithSecurityToken(tea.StringValue(config.SecurityToken)).
307
				Build()
308
		} else {
309
			credentialsProvider, err = providers.NewStaticAKCredentialsProviderBuilder().
310
				WithAccessKeyId(tea.StringValue(config.AccessKeyId)).
311
				WithAccessKeySecret(tea.StringValue(config.AccessKeySecret)).
312
				Build()
313
		}
314
315
		if err != nil {
316
			return nil, err
317
		}
318
319
		provider, err := providers.NewRAMRoleARNCredentialsProviderBuilder().
320
			WithCredentialsProvider(credentialsProvider).
321
			WithRoleArn(tea.StringValue(config.RoleArn)).
322
			WithRoleSessionName(tea.StringValue(config.RoleSessionName)).
323
			WithPolicy(tea.StringValue(config.Policy)).
324
			WithDurationSeconds(tea.IntValue(config.RoleSessionExpiration)).
325
			WithExternalId(tea.StringValue(config.ExternalId)).
326
			WithStsEndpoint(tea.StringValue(config.STSEndpoint)).
327
			WithHttpOptions(&providers.HttpOptions{
328
				Proxy:          tea.StringValue(config.Proxy),
329
				ReadTimeout:    tea.IntValue(config.Timeout),
330
				ConnectTimeout: tea.IntValue(config.ConnectTimeout),
331
			}).
332
			Build()
333
		if err != nil {
334
			return nil, err
335
		}
336
337
		credential = FromCredentialsProvider("ram_role_arn", provider)
338
	case "rsa_key_pair":
339
		err = checkRSAKeyPair(config)
340
		if err != nil {
341
			return
342
		}
343
		file, err1 := os.Open(tea.StringValue(config.PrivateKeyFile))
344
		if err1 != nil {
345
			err = fmt.Errorf("InvalidPath: Can not open PrivateKeyFile, err is %s", err1.Error())
346
			return
347
		}
348
		defer file.Close()
349
		var privateKey string
350
		scan := bufio.NewScanner(file)
351
		for scan.Scan() {
352
			if strings.HasPrefix(scan.Text(), "----") {
353
				continue
354
			}
355
			privateKey += scan.Text() + "\n"
356
		}
357
		runtime := &utils.Runtime{
358
			Host:           tea.StringValue(config.Host),
359
			Proxy:          tea.StringValue(config.Proxy),
360
			ReadTimeout:    tea.IntValue(config.Timeout),
361
			ConnectTimeout: tea.IntValue(config.ConnectTimeout),
362
			STSEndpoint:    tea.StringValue(config.STSEndpoint),
363
		}
364
		credential = newRsaKeyPairCredential(
365
			privateKey,
366
			tea.StringValue(config.PublicKeyId),
367
			tea.IntValue(config.SessionExpiration),
368
			runtime)
369
	case "bearer":
370
		if tea.StringValue(config.BearerToken) == "" {
371
			err = errors.New("BearerToken cannot be empty")
372
			return
373
		}
374
		credential = newBearerTokenCredential(tea.StringValue(config.BearerToken))
375
	default:
376
		err = errors.New("invalid type option, support: access_key, sts, bearer, ecs_ram_role, ram_role_arn, rsa_key_pair, oidc_role_arn, credentials_uri")
377
		return
378
	}
379
	return credential, nil
380
}
381
382
func checkRSAKeyPair(config *Config) (err error) {
383
	if tea.StringValue(config.PrivateKeyFile) == "" {
384
		err = errors.New("PrivateKeyFile cannot be empty")
385
		return
386
	}
387
	if tea.StringValue(config.PublicKeyId) == "" {
388
		err = errors.New("PublicKeyId cannot be empty")
389
		return
390
	}
391
	return
392
}
393
394
func doAction(request *request.CommonRequest, runtime *utils.Runtime) (content []byte, err error) {
395
	var urlEncoded string
396
	if request.BodyParams != nil {
397
		urlEncoded = utils.GetURLFormedMap(request.BodyParams)
398
	}
399
	httpRequest, err := http.NewRequest(request.Method, request.URL, strings.NewReader(urlEncoded))
400
	if err != nil {
401
		return
402
	}
403
	httpRequest.Proto = "HTTP/1.1"
404
	httpRequest.Host = request.Domain
405
	debuglog("> %s %s %s", httpRequest.Method, httpRequest.URL.RequestURI(), httpRequest.Proto)
406
	debuglog("> Host: %s", httpRequest.Host)
407
	for key, value := range request.Headers {
408
		if value != "" {
409
			debuglog("> %s: %s", key, value)
410
			httpRequest.Header[key] = []string{value}
411
		}
412
	}
413
	debuglog(">")
414
	httpClient := &http.Client{}
415
	httpClient.Timeout = time.Duration(runtime.ReadTimeout) * time.Second
416
	proxy := &url.URL{}
417
	if runtime.Proxy != "" {
418
		proxy, err = url.Parse(runtime.Proxy)
419
		if err != nil {
420
			return
421
		}
422
	}
423
	transport := &http.Transport{}
424
	if proxy != nil && runtime.Proxy != "" {
425
		transport.Proxy = http.ProxyURL(proxy)
426
	}
427
	transport.DialContext = utils.Timeout(time.Duration(runtime.ConnectTimeout) * time.Second)
428
	httpClient.Transport = transport
429
	httpResponse, err := hookDo(httpClient.Do)(httpRequest)
430
	if err != nil {
431
		return
432
	}
433
	debuglog("< %s %s", httpResponse.Proto, httpResponse.Status)
434
	for key, value := range httpResponse.Header {
435
		debuglog("< %s: %v", key, strings.Join(value, ""))
436
	}
437
	debuglog("<")
438
439
	resp := &response.CommonResponse{}
440
	err = hookParse(resp.ParseFromHTTPResponse(httpResponse))
441
	if err != nil {
442
		return
443
	}
444
	debuglog("%s", resp.GetHTTPContentString())
445
	if resp.GetHTTPStatus() != http.StatusOK {
446
		err = fmt.Errorf("httpStatus: %d, message = %s", resp.GetHTTPStatus(), resp.GetHTTPContentString())
447
		return
448
	}
449
	return resp.GetHTTPContentBytes(), nil
450
}
451
452
type credentialsProviderWrap struct {
453
	typeName string
454
	provider providers.CredentialsProvider
455
}
456
457
// Deprecated: use GetCredential() instead of
458
func (cp *credentialsProviderWrap) GetAccessKeyId() (accessKeyId *string, err error) {
459
	cc, err := cp.provider.GetCredentials()
460
	if err != nil {
461
		return
462
	}
463
	accessKeyId = &cc.AccessKeyId
464
	return
465
}
466
467
// Deprecated: use GetCredential() instead of
468
func (cp *credentialsProviderWrap) GetAccessKeySecret() (accessKeySecret *string, err error) {
469
	cc, err := cp.provider.GetCredentials()
470
	if err != nil {
471
		return
472
	}
473
	accessKeySecret = &cc.AccessKeySecret
474
	return
475
}
476
477
// Deprecated: use GetCredential() instead of
478
func (cp *credentialsProviderWrap) GetSecurityToken() (securityToken *string, err error) {
479
	cc, err := cp.provider.GetCredentials()
480
	if err != nil {
481
		return
482
	}
483
	securityToken = &cc.SecurityToken
484
	return
485
}
486
487
// Deprecated: don't use it
488
func (cp *credentialsProviderWrap) GetBearerToken() (bearerToken *string) {
489
	return tea.String("")
490
}
491
492
// Get credentials
493
func (cp *credentialsProviderWrap) GetCredential() (cm *CredentialModel, err error) {
494
	c, err := cp.provider.GetCredentials()
495
	if err != nil {
496
		return
497
	}
498
499
	cm = &CredentialModel{
500
		AccessKeyId:     &c.AccessKeyId,
501
		AccessKeySecret: &c.AccessKeySecret,
502
		SecurityToken:   &c.SecurityToken,
503
		Type:            &cp.typeName,
504
		ProviderName:    &c.ProviderName,
505
	}
506
	return
507
}
508
509
func (cp *credentialsProviderWrap) GetType() *string {
510
	return &cp.typeName
511
}
512
513
func FromCredentialsProvider(typeName string, cp providers.CredentialsProvider) Credential {
514
	return &credentialsProviderWrap{
515
		typeName: typeName,
516
		provider: cp,
517
	}
518
}
519