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.*profileProvider.resolve   F
last analyzed

Complexity

Conditions 19

Size

Total Lines 58
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 19
eloc 47
nop 0
dl 0
loc 58
rs 0.5999
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.*profileProvider.resolve 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
	"errors"
5
	"fmt"
6
	"os"
7
	"strings"
8
9
	"github.com/alibabacloud-go/tea/tea"
10
	"github.com/aliyun/credentials-go/credentials/internal/utils"
11
	ini "gopkg.in/ini.v1"
12
)
13
14
type profileProvider struct {
15
	Profile string
16
}
17
18
var providerProfile = newProfileProvider()
19
20
var hookState = func(info os.FileInfo, err error) (os.FileInfo, error) {
21
	return info, err
22
}
23
24
// NewProfileProvider receive zero or more parameters,
25
// when length of name is 0, the value of field Profile will be "default",
26
// and when there are multiple inputs, the function will take the
27
// first one and  discard the other values.
28
func newProfileProvider(name ...string) Provider {
29
	p := new(profileProvider)
30
	if len(name) == 0 {
31
		p.Profile = "default"
32
	} else {
33
		p.Profile = name[0]
34
	}
35
	return p
36
}
37
38
// resolve implements the Provider interface
39
// when credential type is rsa_key_pair, the content of private_key file
40
// must be able to be parsed directly into the required string
41
// that NewRsaKeyPairCredential function needed
42
func (p *profileProvider) resolve() (*Config, error) {
43
	path, ok := os.LookupEnv(ENVCredentialFile)
44
	if !ok {
45
		defaultPath, err := checkDefaultPath()
46
		if err != nil {
47
			return nil, err
48
		}
49
		path = defaultPath
50
		if path == "" {
51
			return nil, nil
52
		}
53
	} else if path == "" {
54
		return nil, errors.New(ENVCredentialFile + " cannot be empty")
55
	}
56
57
	value, section, err := getType(path, p.Profile)
58
	if err != nil {
59
		return nil, err
60
	}
61
	switch value.String() {
62
	case "access_key":
63
		config, err := getAccessKey(section)
64
		if err != nil {
65
			return nil, err
66
		}
67
		return config, nil
68
	case "sts":
69
		config, err := getSTS(section)
70
		if err != nil {
71
			return nil, err
72
		}
73
		return config, nil
74
	case "bearer":
75
		config, err := getBearerToken(section)
76
		if err != nil {
77
			return nil, err
78
		}
79
		return config, nil
80
	case "ecs_ram_role":
81
		config, err := getEcsRAMRole(section)
82
		if err != nil {
83
			return nil, err
84
		}
85
		return config, nil
86
	case "ram_role_arn":
87
		config, err := getRAMRoleArn(section)
88
		if err != nil {
89
			return nil, err
90
		}
91
		return config, nil
92
	case "rsa_key_pair":
93
		config, err := getRSAKeyPair(section)
94
		if err != nil {
95
			return nil, err
96
		}
97
		return config, nil
98
	default:
99
		return nil, errors.New("invalid type option, support: access_key, sts, ecs_ram_role, ram_role_arn, rsa_key_pair")
100
	}
101
}
102
103
func getRSAKeyPair(section *ini.Section) (*Config, error) {
104
	publicKeyId, err := section.GetKey("public_key_id")
105
	if err != nil {
106
		return nil, errors.New("missing required public_key_id option in profile for rsa_key_pair")
107
	}
108
	if publicKeyId.String() == "" {
109
		return nil, errors.New("public_key_id cannot be empty")
110
	}
111
	privateKeyFile, err := section.GetKey("private_key_file")
112
	if err != nil {
113
		return nil, errors.New("missing required private_key_file option in profile for rsa_key_pair")
114
	}
115
	if privateKeyFile.String() == "" {
116
		return nil, errors.New("private_key_file cannot be empty")
117
	}
118
	sessionExpiration, _ := section.GetKey("session_expiration")
119
	expiration := 0
120
	if sessionExpiration != nil {
121
		expiration, err = sessionExpiration.Int()
122
		if err != nil {
123
			return nil, errors.New("session_expiration must be an int")
124
		}
125
	}
126
	config := &Config{
127
		Type:              tea.String("rsa_key_pair"),
128
		PublicKeyId:       tea.String(publicKeyId.String()),
129
		PrivateKeyFile:    tea.String(privateKeyFile.String()),
130
		SessionExpiration: tea.Int(expiration),
131
	}
132
	err = setRuntimeToConfig(config, section)
133
	if err != nil {
134
		return nil, err
135
	}
136
	return config, nil
137
}
138
139
func getRAMRoleArn(section *ini.Section) (*Config, error) {
140
	accessKeyId, err := section.GetKey("access_key_id")
141
	if err != nil {
142
		return nil, errors.New("missing required access_key_id option in profile for ram_role_arn")
143
	}
144
	if accessKeyId.String() == "" {
145
		return nil, errors.New("access_key_id cannot be empty")
146
	}
147
	accessKeySecret, err := section.GetKey("access_key_secret")
148
	if err != nil {
149
		return nil, errors.New("missing required access_key_secret option in profile for ram_role_arn")
150
	}
151
	if accessKeySecret.String() == "" {
152
		return nil, errors.New("access_key_secret cannot be empty")
153
	}
154
	roleArn, err := section.GetKey("role_arn")
155
	if err != nil {
156
		return nil, errors.New("missing required role_arn option in profile for ram_role_arn")
157
	}
158
	if roleArn.String() == "" {
159
		return nil, errors.New("role_arn cannot be empty")
160
	}
161
	roleSessionName, err := section.GetKey("role_session_name")
162
	if err != nil {
163
		return nil, errors.New("missing required role_session_name option in profile for ram_role_arn")
164
	}
165
	if roleSessionName.String() == "" {
166
		return nil, errors.New("role_session_name cannot be empty")
167
	}
168
	roleSessionExpiration, _ := section.GetKey("role_session_expiration")
169
	expiration := 0
170
	if roleSessionExpiration != nil {
171
		expiration, err = roleSessionExpiration.Int()
172
		if err != nil {
173
			return nil, errors.New("role_session_expiration must be an int")
174
		}
175
	}
176
	config := &Config{
177
		Type:                  tea.String("ram_role_arn"),
178
		AccessKeyId:           tea.String(accessKeyId.String()),
179
		AccessKeySecret:       tea.String(accessKeySecret.String()),
180
		RoleArn:               tea.String(roleArn.String()),
181
		RoleSessionName:       tea.String(roleSessionName.String()),
182
		RoleSessionExpiration: tea.Int(expiration),
183
	}
184
	err = setRuntimeToConfig(config, section)
185
	if err != nil {
186
		return nil, err
187
	}
188
	return config, nil
189
}
190
191
func getEcsRAMRole(section *ini.Section) (*Config, error) {
192
	roleName, _ := section.GetKey("role_name")
193
	config := &Config{
194
		Type: tea.String("ecs_ram_role"),
195
	}
196
	if roleName != nil {
197
		config.RoleName = tea.String(roleName.String())
198
	}
199
	err := setRuntimeToConfig(config, section)
200
	if err != nil {
201
		return nil, err
202
	}
203
	return config, nil
204
}
205
206
func getBearerToken(section *ini.Section) (*Config, error) {
207
	bearerToken, err := section.GetKey("bearer_token")
208
	if err != nil {
209
		return nil, errors.New("missing required bearer_token option in profile for bearer")
210
	}
211
	if bearerToken.String() == "" {
212
		return nil, errors.New("bearer_token cannot be empty")
213
	}
214
	config := &Config{
215
		Type:        tea.String("bearer"),
216
		BearerToken: tea.String(bearerToken.String()),
217
	}
218
	return config, nil
219
}
220
221
func getSTS(section *ini.Section) (*Config, error) {
222
	accesskeyid, err := section.GetKey("access_key_id")
223
	if err != nil {
224
		return nil, errors.New("missing required access_key_id option in profile for sts")
225
	}
226
	if accesskeyid.String() == "" {
227
		return nil, errors.New("access_key_id cannot be empty")
228
	}
229
	accessKeySecret, err := section.GetKey("access_key_secret")
230
	if err != nil {
231
		return nil, errors.New("missing required access_key_secret option in profile for sts")
232
	}
233
	if accessKeySecret.String() == "" {
234
		return nil, errors.New("access_key_secret cannot be empty")
235
	}
236
	securityToken, err := section.GetKey("security_token")
237
	if err != nil {
238
		return nil, errors.New("missing required security_token option in profile for sts")
239
	}
240
	if securityToken.String() == "" {
241
		return nil, errors.New("security_token cannot be empty")
242
	}
243
	config := &Config{
244
		Type:            tea.String("sts"),
245
		AccessKeyId:     tea.String(accesskeyid.String()),
246
		AccessKeySecret: tea.String(accessKeySecret.String()),
247
		SecurityToken:   tea.String(securityToken.String()),
248
	}
249
	return config, nil
250
}
251
252
func getAccessKey(section *ini.Section) (*Config, error) {
253
	accesskeyid, err := section.GetKey("access_key_id")
254
	if err != nil {
255
		return nil, errors.New("missing required access_key_id option in profile for access_key")
256
	}
257
	if accesskeyid.String() == "" {
258
		return nil, errors.New("access_key_id cannot be empty")
259
	}
260
	accessKeySecret, err := section.GetKey("access_key_secret")
261
	if err != nil {
262
		return nil, errors.New("missing required access_key_secret option in profile for access_key")
263
	}
264
	if accessKeySecret.String() == "" {
265
		return nil, errors.New("access_key_secret cannot be empty")
266
	}
267
	config := &Config{
268
		Type:            tea.String("access_key"),
269
		AccessKeyId:     tea.String(accesskeyid.String()),
270
		AccessKeySecret: tea.String(accessKeySecret.String()),
271
	}
272
	return config, nil
273
}
274
275
func getType(path, profile string) (*ini.Key, *ini.Section, error) {
276
	ini, err := ini.Load(path)
277
	if err != nil {
278
		return nil, nil, errors.New("ERROR: Can not open file " + err.Error())
279
	}
280
281
	section, err := ini.GetSection(profile)
282
	if err != nil {
283
		return nil, nil, errors.New("ERROR: Can not load section " + err.Error())
284
	}
285
286
	value, err := section.GetKey("type")
287
	if err != nil {
288
		return nil, nil, errors.New("missing required type option " + err.Error())
289
	}
290
	return value, section, nil
291
}
292
293
func checkDefaultPath() (path string, err error) {
294
	path = utils.GetHomePath()
295
	if path == "" {
296
		return "", errors.New("the default credential file path is invalid")
297
	}
298
	path = strings.Replace("~/.alibabacloud/credentials", "~", path, 1)
299
	_, err = hookState(os.Stat(path))
300
	if err != nil {
301
		return "", nil
302
	}
303
	return path, nil
304
}
305
306
func setRuntimeToConfig(config *Config, section *ini.Section) error {
307
	rawTimeout, _ := section.GetKey("timeout")
308
	rawConnectTimeout, _ := section.GetKey("connect_timeout")
309
	rawProxy, _ := section.GetKey("proxy")
310
	rawHost, _ := section.GetKey("host")
311
	if rawProxy != nil {
312
		config.Proxy = tea.String(rawProxy.String())
313
	}
314
	if rawConnectTimeout != nil {
315
		connectTimeout, err := rawConnectTimeout.Int()
316
		if err != nil {
317
			return fmt.Errorf("please set connect_timeout with an int value")
318
		}
319
		config.ConnectTimeout = tea.Int(connectTimeout)
320
	}
321
	if rawTimeout != nil {
322
		timeout, err := rawTimeout.Int()
323
		if err != nil {
324
			return fmt.Errorf("please set timeout with an int value")
325
		}
326
		config.Timeout = tea.Int(timeout)
327
	}
328
	if rawHost != nil {
329
		config.Host = tea.String(rawHost.String())
330
	}
331
	return nil
332
}
333