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 ( 3bd38f...cde461 )
by
unknown
07:17
created

der.WithOIDCProviderARN   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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