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 ( 47c2ea...25ec51 )
by
unknown
05:34
created

providers.*OIDCCredentialsProviderBuilder.Build   F

Complexity

Conditions 15

Size

Total Lines 59
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
eloc 36
nop 0
dl 0
loc 59
rs 2.9998
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 providers.*OIDCCredentialsProviderBuilder.Build 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 providers
2
3
import (
4
	"encoding/json"
5
	"errors"
6
	"fmt"
7
	"io/ioutil"
8
	"net/http"
9
	"os"
10
	"strconv"
11
	"strings"
12
	"time"
13
14
	httputil "github.com/aliyun/credentials-go/credentials/internal/http"
15
	"github.com/aliyun/credentials-go/credentials/internal/utils"
16
)
17
18
type OIDCCredentialsProvider struct {
19
	oidcProviderARN   string
20
	oidcTokenFilePath string
21
	roleArn           string
22
	roleSessionName   string
23
	durationSeconds   int
24
	policy            string
25
	// for sts endpoint
26
	stsRegionId string
27
	enableVpc   bool
28
	stsEndpoint string
29
30
	lastUpdateTimestamp int64
31
	expirationTimestamp int64
32
	sessionCredentials  *sessionCredentials
33
	// for http options
34
	httpOptions *HttpOptions
35
}
36
37
type OIDCCredentialsProviderBuilder struct {
38
	provider *OIDCCredentialsProvider
39
}
40
41
func NewOIDCCredentialsProviderBuilder() *OIDCCredentialsProviderBuilder {
42
	return &OIDCCredentialsProviderBuilder{
43
		provider: &OIDCCredentialsProvider{},
44
	}
45
}
46
47
func (b *OIDCCredentialsProviderBuilder) WithOIDCProviderARN(oidcProviderArn string) *OIDCCredentialsProviderBuilder {
48
	b.provider.oidcProviderARN = oidcProviderArn
49
	return b
50
}
51
52
func (b *OIDCCredentialsProviderBuilder) WithOIDCTokenFilePath(oidcTokenFilePath string) *OIDCCredentialsProviderBuilder {
53
	b.provider.oidcTokenFilePath = oidcTokenFilePath
54
	return b
55
}
56
57
func (b *OIDCCredentialsProviderBuilder) WithRoleArn(roleArn string) *OIDCCredentialsProviderBuilder {
58
	b.provider.roleArn = roleArn
59
	return b
60
}
61
62
func (b *OIDCCredentialsProviderBuilder) WithRoleSessionName(roleSessionName string) *OIDCCredentialsProviderBuilder {
63
	b.provider.roleSessionName = roleSessionName
64
	return b
65
}
66
67
func (b *OIDCCredentialsProviderBuilder) WithDurationSeconds(durationSeconds int) *OIDCCredentialsProviderBuilder {
68
	b.provider.durationSeconds = durationSeconds
69
	return b
70
}
71
72
func (b *OIDCCredentialsProviderBuilder) WithStsRegionId(regionId string) *OIDCCredentialsProviderBuilder {
73
	b.provider.stsRegionId = regionId
74
	return b
75
}
76
77
func (b *OIDCCredentialsProviderBuilder) WithEnableVpc(enableVpc bool) *OIDCCredentialsProviderBuilder {
78
	b.provider.enableVpc = enableVpc
79
	return b
80
}
81
82
func (b *OIDCCredentialsProviderBuilder) WithPolicy(policy string) *OIDCCredentialsProviderBuilder {
83
	b.provider.policy = policy
84
	return b
85
}
86
87
func (b *OIDCCredentialsProviderBuilder) WithSTSEndpoint(stsEndpoint string) *OIDCCredentialsProviderBuilder {
88
	b.provider.stsEndpoint = stsEndpoint
89
	return b
90
}
91
92
func (b *OIDCCredentialsProviderBuilder) WithHttpOptions(httpOptions *HttpOptions) *OIDCCredentialsProviderBuilder {
93
	b.provider.httpOptions = httpOptions
94
	return b
95
}
96
97
func (b *OIDCCredentialsProviderBuilder) Build() (provider *OIDCCredentialsProvider, err error) {
98
	if b.provider.roleSessionName == "" {
99
		b.provider.roleSessionName = "credentials-go-" + strconv.FormatInt(time.Now().UnixNano()/1000, 10)
100
	}
101
102
	if b.provider.oidcTokenFilePath == "" {
103
		b.provider.oidcTokenFilePath = os.Getenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE")
104
	}
105
106
	if b.provider.oidcTokenFilePath == "" {
107
		err = errors.New("the OIDCTokenFilePath is empty")
108
		return
109
	}
110
111
	if b.provider.oidcProviderARN == "" {
112
		b.provider.oidcProviderARN = os.Getenv("ALIBABA_CLOUD_OIDC_PROVIDER_ARN")
113
	}
114
115
	if b.provider.oidcProviderARN == "" {
116
		err = errors.New("the OIDCProviderARN is empty")
117
		return
118
	}
119
120
	if b.provider.roleArn == "" {
121
		b.provider.roleArn = os.Getenv("ALIBABA_CLOUD_ROLE_ARN")
122
	}
123
124
	if b.provider.roleArn == "" {
125
		err = errors.New("the RoleArn is empty")
126
		return
127
	}
128
129
	if b.provider.durationSeconds == 0 {
130
		b.provider.durationSeconds = 3600
131
	}
132
133
	if b.provider.durationSeconds < 900 {
134
		err = errors.New("the Assume Role session duration should be in the range of 15min - max duration seconds")
135
	}
136
137
	if b.provider.stsEndpoint == "" {
138
		if !b.provider.enableVpc {
139
			b.provider.enableVpc = strings.ToLower(os.Getenv("ALIBABA_CLOUD_VPC_ENDPOINT_ENABLED")) == "true"
140
		}
141
		prefix := "sts"
142
		if b.provider.enableVpc {
143
			prefix = "sts-vpc"
144
		}
145
		if b.provider.stsRegionId != "" {
146
			b.provider.stsEndpoint = fmt.Sprintf("%s.%s.aliyuncs.com", prefix, b.provider.stsRegionId)
147
		} else if region := os.Getenv("ALIBABA_CLOUD_STS_REGION"); region != "" {
148
			b.provider.stsEndpoint = fmt.Sprintf("%s.%s.aliyuncs.com", prefix, region)
149
		} else {
150
			b.provider.stsEndpoint = "sts.aliyuncs.com"
151
		}
152
	}
153
154
	provider = b.provider
155
	return
156
}
157
158
func (provider *OIDCCredentialsProvider) getCredentials() (session *sessionCredentials, err error) {
159
	req := &httputil.Request{
160
		Method:   "POST",
161
		Protocol: "https",
162
		Host:     provider.stsEndpoint,
163
		Headers:  map[string]string{},
164
	}
165
166
	if provider.httpOptions != nil {
167
		req.ConnectTimeout = time.Duration(provider.httpOptions.ConnectTimeout) * time.Second
168
		req.ReadTimeout = time.Duration(provider.httpOptions.ReadTimeout) * time.Second
169
		req.Proxy = provider.httpOptions.Proxy
170
	}
171
172
	queries := make(map[string]string)
173
	queries["Version"] = "2015-04-01"
174
	queries["Action"] = "AssumeRoleWithOIDC"
175
	queries["Format"] = "JSON"
176
	queries["Timestamp"] = utils.GetTimeInFormatISO8601()
177
	req.Queries = queries
178
179
	bodyForm := make(map[string]string)
180
	bodyForm["RoleArn"] = provider.roleArn
181
	bodyForm["OIDCProviderArn"] = provider.oidcProviderARN
182
	token, err := ioutil.ReadFile(provider.oidcTokenFilePath)
183
	if err != nil {
184
		return
185
	}
186
187
	bodyForm["OIDCToken"] = string(token)
188
	if provider.policy != "" {
189
		bodyForm["Policy"] = provider.policy
190
	}
191
192
	bodyForm["RoleSessionName"] = provider.roleSessionName
193
	bodyForm["DurationSeconds"] = strconv.Itoa(provider.durationSeconds)
194
	req.Form = bodyForm
195
196
	// set headers
197
	req.Headers["Accept-Encoding"] = "identity"
198
	res, err := httpDo(req)
199
	if err != nil {
200
		return
201
	}
202
203
	if res.StatusCode != http.StatusOK {
204
		message := "get session token failed: "
205
		err = errors.New(message + string(res.Body))
206
		return
207
	}
208
	var data assumeRoleResponse
209
	err = json.Unmarshal(res.Body, &data)
210
	if err != nil {
211
		err = fmt.Errorf("get oidc sts token err, json.Unmarshal fail: %s", err.Error())
212
		return
213
	}
214
	if data.Credentials == nil {
215
		err = fmt.Errorf("get oidc sts token err, fail to get credentials")
216
		return
217
	}
218
219
	if data.Credentials.AccessKeyId == nil || data.Credentials.AccessKeySecret == nil || data.Credentials.SecurityToken == nil {
220
		err = fmt.Errorf("refresh RoleArn sts token err, fail to get credentials")
221
		return
222
	}
223
224
	session = &sessionCredentials{
225
		AccessKeyId:     *data.Credentials.AccessKeyId,
226
		AccessKeySecret: *data.Credentials.AccessKeySecret,
227
		SecurityToken:   *data.Credentials.SecurityToken,
228
		Expiration:      *data.Credentials.Expiration,
229
	}
230
	return
231
}
232
233
func (provider *OIDCCredentialsProvider) needUpdateCredential() (result bool) {
234
	if provider.expirationTimestamp == 0 {
235
		return true
236
	}
237
238
	return provider.expirationTimestamp-time.Now().Unix() <= 180
239
}
240
241
func (provider *OIDCCredentialsProvider) GetCredentials() (cc *Credentials, err error) {
242
	if provider.sessionCredentials == nil || provider.needUpdateCredential() {
243
		sessionCredentials, err1 := provider.getCredentials()
244
		if err1 != nil {
245
			return nil, err1
246
		}
247
248
		provider.sessionCredentials = sessionCredentials
249
		expirationTime, err2 := time.Parse("2006-01-02T15:04:05Z", sessionCredentials.Expiration)
250
		if err2 != nil {
251
			return nil, err2
252
		}
253
254
		provider.lastUpdateTimestamp = time.Now().Unix()
255
		provider.expirationTimestamp = expirationTime.Unix()
256
	}
257
258
	cc = &Credentials{
259
		AccessKeyId:     provider.sessionCredentials.AccessKeyId,
260
		AccessKeySecret: provider.sessionCredentials.AccessKeySecret,
261
		SecurityToken:   provider.sessionCredentials.SecurityToken,
262
		ProviderName:    provider.GetProviderName(),
263
	}
264
	return
265
}
266
267
func (provider *OIDCCredentialsProvider) GetProviderName() string {
268
	return "oidc_role_arn"
269
}
270