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 ( 25ec51...117080 )
by
unknown
07:44
created

credentials/providers/oidc.go   B

Size/Duplication

Total Lines 277
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 50
eloc 180
dl 0
loc 277
rs 8.4
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A providers.*OIDCCredentialsProviderBuilder.WithStsRegionId 0 3 1
A providers.*OIDCCredentialsProviderBuilder.WithOIDCTokenFilePath 0 3 1
A providers.*OIDCCredentialsProviderBuilder.WithHttpOptions 0 3 1
A providers.*OIDCCredentialsProviderBuilder.WithRoleArn 0 3 1
A providers.NewOIDCCredentialsProviderBuilder 0 3 1
A providers.*OIDCCredentialsProviderBuilder.WithDurationSeconds 0 3 1
F providers.*OIDCCredentialsProviderBuilder.Build 0 59 15
A providers.*OIDCCredentialsProviderBuilder.WithOIDCProviderARN 0 3 1
A providers.*OIDCCredentialsProviderBuilder.WithPolicy 0 3 1
A providers.*OIDCCredentialsProviderBuilder.WithRoleSessionName 0 3 1
A providers.*OIDCCredentialsProviderBuilder.WithEnableVpc 0 3 1
A providers.*OIDCCredentialsProviderBuilder.WithSTSEndpoint 0 3 1
A providers.*OIDCCredentialsProvider.GetCredentials 0 24 5
F providers.*OIDCCredentialsProvider.getCredentials 0 82 16
A providers.*OIDCCredentialsProvider.GetProviderName 0 2 1
A providers.*OIDCCredentialsProvider.needUpdateCredential 0 6 2
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
	connectTimeout := 5 * time.Second
167
	readTimeout := 10 * time.Second
168
169
	if provider.httpOptions != nil && provider.httpOptions.ConnectTimeout > 0 {
170
		connectTimeout = time.Duration(provider.httpOptions.ConnectTimeout) * time.Millisecond
171
	}
172
	if provider.httpOptions != nil && provider.httpOptions.ReadTimeout > 0 {
173
		readTimeout = time.Duration(provider.httpOptions.ReadTimeout) * time.Millisecond
174
	}
175
	if provider.httpOptions != nil && provider.httpOptions.Proxy != "" {
176
		req.Proxy = provider.httpOptions.Proxy
177
	}
178
	req.ConnectTimeout = connectTimeout
179
	req.ReadTimeout = readTimeout
180
181
	queries := make(map[string]string)
182
	queries["Version"] = "2015-04-01"
183
	queries["Action"] = "AssumeRoleWithOIDC"
184
	queries["Format"] = "JSON"
185
	queries["Timestamp"] = utils.GetTimeInFormatISO8601()
186
	req.Queries = queries
187
188
	bodyForm := make(map[string]string)
189
	bodyForm["RoleArn"] = provider.roleArn
190
	bodyForm["OIDCProviderArn"] = provider.oidcProviderARN
191
	token, err := ioutil.ReadFile(provider.oidcTokenFilePath)
192
	if err != nil {
193
		return
194
	}
195
196
	bodyForm["OIDCToken"] = string(token)
197
	if provider.policy != "" {
198
		bodyForm["Policy"] = provider.policy
199
	}
200
201
	bodyForm["RoleSessionName"] = provider.roleSessionName
202
	bodyForm["DurationSeconds"] = strconv.Itoa(provider.durationSeconds)
203
	req.Form = bodyForm
204
205
	// set headers
206
	req.Headers["Accept-Encoding"] = "identity"
207
	res, err := httpDo(req)
208
	if err != nil {
209
		return
210
	}
211
212
	if res.StatusCode != http.StatusOK {
213
		message := "get session token failed: "
214
		err = errors.New(message + string(res.Body))
215
		return
216
	}
217
	var data assumeRoleResponse
218
	err = json.Unmarshal(res.Body, &data)
219
	if err != nil {
220
		err = fmt.Errorf("get oidc sts token err, json.Unmarshal fail: %s", err.Error())
221
		return
222
	}
223
	if data.Credentials == nil {
224
		err = fmt.Errorf("get oidc sts token err, fail to get credentials")
225
		return
226
	}
227
228
	if data.Credentials.AccessKeyId == nil || data.Credentials.AccessKeySecret == nil || data.Credentials.SecurityToken == nil {
229
		err = fmt.Errorf("refresh RoleArn sts token err, fail to get credentials")
230
		return
231
	}
232
233
	session = &sessionCredentials{
234
		AccessKeyId:     *data.Credentials.AccessKeyId,
235
		AccessKeySecret: *data.Credentials.AccessKeySecret,
236
		SecurityToken:   *data.Credentials.SecurityToken,
237
		Expiration:      *data.Credentials.Expiration,
238
	}
239
	return
240
}
241
242
func (provider *OIDCCredentialsProvider) needUpdateCredential() (result bool) {
243
	if provider.expirationTimestamp == 0 {
244
		return true
245
	}
246
247
	return provider.expirationTimestamp-time.Now().Unix() <= 180
248
}
249
250
func (provider *OIDCCredentialsProvider) GetCredentials() (cc *Credentials, err error) {
251
	if provider.sessionCredentials == nil || provider.needUpdateCredential() {
252
		sessionCredentials, err1 := provider.getCredentials()
253
		if err1 != nil {
254
			return nil, err1
255
		}
256
257
		provider.sessionCredentials = sessionCredentials
258
		expirationTime, err2 := time.Parse("2006-01-02T15:04:05Z", sessionCredentials.Expiration)
259
		if err2 != nil {
260
			return nil, err2
261
		}
262
263
		provider.lastUpdateTimestamp = time.Now().Unix()
264
		provider.expirationTimestamp = expirationTime.Unix()
265
	}
266
267
	cc = &Credentials{
268
		AccessKeyId:     provider.sessionCredentials.AccessKeyId,
269
		AccessKeySecret: provider.sessionCredentials.AccessKeySecret,
270
		SecurityToken:   provider.sessionCredentials.SecurityToken,
271
		ProviderName:    provider.GetProviderName(),
272
	}
273
	return
274
}
275
276
func (provider *OIDCCredentialsProvider) GetProviderName() string {
277
	return "oidc_role_arn"
278
}
279