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.NewCredential   F

Complexity

Conditions 26

Size

Total Lines 110
Code Lines 88

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 26
eloc 88
dl 0
loc 110
rs 0
c 0
b 0
f 0
nop 1

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/aliyun/credentials-go/credentials/request"
15
	"github.com/aliyun/credentials-go/credentials/response"
16
	"github.com/aliyun/credentials-go/credentials/utils"
17
)
18
19
var debuglog = debug.Init("credential")
20
21
var hookParse = func(err error) error {
22
	return err
23
}
24
25
// Credential is an interface for getting actual credential
26
type Credential interface {
27
	GetAccessKeyID() (string, error)
28
	GetAccessSecret() (string, error)
29
	GetSecurityToken() (string, error)
30
	GetBearerToken() string
31
	GetType() string
32
}
33
34
// Configuration is important when call NewCredential
35
type Configuration struct {
36
	Type                  string `json:"type"`
37
	AccessKeyID           string `json:"access_key_id"`
38
	AccessKeySecret       string `json:"access_key_secret"`
39
	RoleArn               string `json:"role_arn"`
40
	RoleSessionName       string `json:"role_session_name"`
41
	PublicKeyID           string `json:"public_key_id"`
42
	RoleName              string `json:"role_name"`
43
	SessionExpiration     int    `json:"session_expiration"`
44
	PrivateKeyFile        string `json:"private_key_file"`
45
	BearerToken           string `json:"bearer_token"`
46
	SecurityToken         string `json:"security_token"`
47
	RoleSessionExpiration int    `json:"role_session_expiratioon"`
48
	Policy                string `json:"policy"`
49
	Host                  string `json:"host"`
50
	Timeout               int    `json:"timeout"`
51
	ConnectTimeout        int    `json:"connect_timeout"`
52
	Proxy                 string `json:"proxy"`
53
}
54
55
// NewCredential return a credential according to the type in config.
56
// if config is nil, the function will use default provider chain to get credential.
57
// please see README.md for detail.
58
func NewCredential(config *Configuration) (credential Credential, err error) {
59
	if config == nil {
60
		config, err = defaultChain.resolve()
61
		if err != nil {
62
			return
63
		}
64
		return NewCredential(config)
65
	}
66
	switch config.Type {
67
	case "access_key":
68
		if config.AccessKeyID == "" {
69
			err = errors.New("AccessKeyID cannot be empty")
70
			return
71
		}
72
		if config.AccessKeySecret == "" {
73
			err = errors.New("AccessKeySecret cannot be empty")
74
			return
75
		}
76
		credential = newAccessKeyCredential(config.AccessKeyID, config.AccessKeySecret)
77
	case "sts":
78
		if config.AccessKeyID == "" {
79
			err = errors.New("AccessKeyID cannot be empty")
80
			return
81
		}
82
		if config.AccessKeySecret == "" {
83
			err = errors.New("AccessKeySecret cannot be empty")
84
			return
85
		}
86
		if config.SecurityToken == "" {
87
			err = errors.New("SecurityToken cannot be empty")
88
			return
89
		}
90
		credential = newStsTokenCredential(config.AccessKeyID, config.AccessKeySecret, config.SecurityToken)
91
	case "ecs_ram_role":
92
		if config.RoleName == "" {
93
			err = errors.New("RoleName cannot be empty")
94
			return
95
		}
96
		runtime := &utils.Runtime{
97
			Host:           config.Host,
98
			Proxy:          config.Proxy,
99
			ReadTimeout:    config.Timeout,
100
			ConnectTimeout: config.ConnectTimeout,
101
		}
102
		credential = newEcsRAMRoleCredential(config.RoleName, runtime)
103
	case "ram_role_arn":
104
		if config.AccessKeySecret == "" {
105
			err = errors.New("AccessKeySecret cannot be empty")
106
			return
107
		}
108
		if config.RoleArn == "" {
109
			err = errors.New("RoleArn cannot be empty")
110
			return
111
		}
112
		if config.RoleSessionName == "" {
113
			err = errors.New("RoleSessionName cannot be empty")
114
			return
115
		}
116
		if config.AccessKeyID == "" {
117
			err = errors.New("AccessKeyID cannot be empty")
118
			return
119
		}
120
		runtime := &utils.Runtime{
121
			Host:           config.Host,
122
			Proxy:          config.Proxy,
123
			ReadTimeout:    config.Timeout,
124
			ConnectTimeout: config.ConnectTimeout,
125
		}
126
		credential = newRAMRoleArnCredential(config.AccessKeyID, config.AccessKeySecret, config.RoleArn, config.RoleSessionName, config.Policy, config.RoleSessionExpiration, runtime)
127
	case "rsa_key_pair":
128
		if config.PrivateKeyFile == "" {
129
			err = errors.New("PrivateKeyFile cannot be empty")
130
			return
131
		}
132
		if config.PublicKeyID == "" {
133
			err = errors.New("PublicKeyID cannot be empty")
134
			return
135
		}
136
		file, err1 := os.Open(config.PrivateKeyFile)
137
		if err1 != nil {
138
			err = fmt.Errorf("InvalidPath: Can not open PrivateKeyFile, err is %s", err1.Error())
139
			return
140
		}
141
		defer file.Close()
142
		var privateKey string
143
		scan := bufio.NewScanner(file)
144
		for scan.Scan() {
145
			if strings.HasPrefix(scan.Text(), "----") {
146
				continue
147
			}
148
			privateKey += scan.Text() + "\n"
149
		}
150
		runtime := &utils.Runtime{
151
			Host:           config.Host,
152
			Proxy:          config.Proxy,
153
			ReadTimeout:    config.Timeout,
154
			ConnectTimeout: config.ConnectTimeout,
155
		}
156
		credential = newRsaKeyPairCredential(privateKey, config.PublicKeyID, config.SessionExpiration, runtime)
157
	case "bearer":
158
		if config.BearerToken == "" {
159
			err = errors.New("BearerToken cannot be empty")
160
			return
161
		}
162
		credential = newBearerTokenCredential(config.BearerToken)
163
	default:
164
		err = errors.New("Invalid type option, support: access_key, sts, ecs_ram_role, ram_role_arn, rsa_key_pair")
165
		return
166
	}
167
	return credential, nil
168
}
169
170
func doAction(request *request.CommonRequest, runtime *utils.Runtime) (content []byte, err error) {
171
	httpRequest, err := http.NewRequest(request.Method, request.URL, strings.NewReader(""))
172
	if err != nil {
173
		return
174
	}
175
	httpRequest.Proto = "HTTP/1.1"
176
	httpRequest.Host = request.Domain
177
	debuglog("> %s %s %s", httpRequest.Method, httpRequest.URL.RequestURI(), httpRequest.Proto)
178
	debuglog("> Host: %s", httpRequest.Host)
179
	for key, value := range request.Headers {
180
		if value != "" {
181
			debuglog("> %s: %s", key, value)
182
			httpRequest.Header[key] = []string{value}
183
		}
184
	}
185
	debuglog(">")
186
	httpClient := &http.Client{}
187
	httpClient.Timeout = time.Duration(runtime.ReadTimeout) * time.Second
188
	proxy := &url.URL{}
189
	if runtime.Proxy != "" {
190
		proxy, err = url.Parse(runtime.Proxy)
191
		if err != nil {
192
			return
193
		}
194
	}
195
	trans := &http.Transport{}
196
	if proxy != nil && runtime.Proxy != "" {
197
		trans.Proxy = http.ProxyURL(proxy)
198
	}
199
	trans.DialContext = utils.Timeout(time.Duration(runtime.ConnectTimeout) * time.Second)
200
	httpClient.Transport = trans
201
	httpResponse, err := hookDo(httpClient.Do)(httpRequest)
202
	if err != nil {
203
		return
204
	}
205
	debuglog("< %s %s", httpResponse.Proto, httpResponse.Status)
206
	for key, value := range httpResponse.Header {
207
		debuglog("< %s: %v", key, strings.Join(value, ""))
208
	}
209
	debuglog("<")
210
211
	resp := &response.CommonResponse{}
212
	err = hookParse(resp.ParseFromHTTPResponse(httpResponse))
213
	if err != nil {
214
		return
215
	}
216
	debuglog("%s", resp.GetHTTPContentString())
217
	if resp.GetHTTPStatus() != http.StatusOK {
218
		err = fmt.Errorf("httpStatus: %d, message = %s", resp.GetHTTPStatus(), resp.GetHTTPContentString())
219
		return
220
	}
221
	return resp.GetHTTPContentBytes(), nil
222
}
223