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.
Completed
Pull Request — master (#9)
by zuochao
06:30
created

credentials.*profileProvider.resolve   F

Complexity

Conditions 48

Size

Total Lines 197
Code Lines 147

Duplication

Lines 0
Ratio 0 %

Importance

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