123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- package providers
- import (
- "encoding/json"
- "errors"
- "fmt"
- "net/http"
- "os"
- "time"
- httputil "github.com/aliyun/credentials-go/credentials/internal/http"
- )
- type URLCredentialsProvider struct {
- url string
- // for sts
- sessionCredentials *sessionCredentials
- // for http options
- httpOptions *HttpOptions
- // inner
- expirationTimestamp int64
- }
- type URLCredentialsProviderBuilder struct {
- provider *URLCredentialsProvider
- }
- func NewURLCredentialsProviderBuilder() *URLCredentialsProviderBuilder {
- return &URLCredentialsProviderBuilder{
- provider: &URLCredentialsProvider{},
- }
- }
- func (builder *URLCredentialsProviderBuilder) WithUrl(url string) *URLCredentialsProviderBuilder {
- builder.provider.url = url
- return builder
- }
- func (builder *URLCredentialsProviderBuilder) WithHttpOptions(httpOptions *HttpOptions) *URLCredentialsProviderBuilder {
- builder.provider.httpOptions = httpOptions
- return builder
- }
- func (builder *URLCredentialsProviderBuilder) Build() (provider *URLCredentialsProvider, err error) {
- if builder.provider.url == "" {
- builder.provider.url = os.Getenv("ALIBABA_CLOUD_CREDENTIALS_URI")
- }
- if builder.provider.url == "" {
- err = errors.New("the url is empty")
- return
- }
- provider = builder.provider
- return
- }
- type urlResponse struct {
- AccessKeyId *string `json:"AccessKeyId"`
- AccessKeySecret *string `json:"AccessKeySecret"`
- SecurityToken *string `json:"SecurityToken"`
- Expiration *string `json:"Expiration"`
- }
- func (provider *URLCredentialsProvider) getCredentials() (session *sessionCredentials, err error) {
- req := &httputil.Request{
- Method: "GET",
- URL: provider.url,
- }
- connectTimeout := 5 * time.Second
- readTimeout := 10 * time.Second
- if provider.httpOptions != nil && provider.httpOptions.ConnectTimeout > 0 {
- connectTimeout = time.Duration(provider.httpOptions.ConnectTimeout) * time.Millisecond
- }
- if provider.httpOptions != nil && provider.httpOptions.ReadTimeout > 0 {
- readTimeout = time.Duration(provider.httpOptions.ReadTimeout) * time.Millisecond
- }
- if provider.httpOptions != nil && provider.httpOptions.Proxy != "" {
- req.Proxy = provider.httpOptions.Proxy
- }
- req.ConnectTimeout = connectTimeout
- req.ReadTimeout = readTimeout
- res, err := httpDo(req)
- if err != nil {
- return
- }
- if res.StatusCode != http.StatusOK {
- err = fmt.Errorf("get credentials from %s failed: %s", req.BuildRequestURL(), string(res.Body))
- return
- }
- var resp urlResponse
- err = json.Unmarshal(res.Body, &resp)
- if err != nil {
- err = fmt.Errorf("get credentials from %s failed with error, json unmarshal fail: %s", req.BuildRequestURL(), err.Error())
- return
- }
- if resp.AccessKeyId == nil || resp.AccessKeySecret == nil || resp.SecurityToken == nil || resp.Expiration == nil {
- err = fmt.Errorf("refresh credentials from %s failed: %s", req.BuildRequestURL(), string(res.Body))
- return
- }
- session = &sessionCredentials{
- AccessKeyId: *resp.AccessKeyId,
- AccessKeySecret: *resp.AccessKeySecret,
- SecurityToken: *resp.SecurityToken,
- Expiration: *resp.Expiration,
- }
- return
- }
- func (provider *URLCredentialsProvider) needUpdateCredential() (result bool) {
- if provider.expirationTimestamp == 0 {
- return true
- }
- return provider.expirationTimestamp-time.Now().Unix() <= 180
- }
- func (provider *URLCredentialsProvider) GetCredentials() (cc *Credentials, err error) {
- if provider.sessionCredentials == nil || provider.needUpdateCredential() {
- sessionCredentials, err1 := provider.getCredentials()
- if err1 != nil {
- return nil, err1
- }
- provider.sessionCredentials = sessionCredentials
- expirationTime, err2 := time.Parse("2006-01-02T15:04:05Z", sessionCredentials.Expiration)
- if err2 != nil {
- return nil, err2
- }
- provider.expirationTimestamp = expirationTime.Unix()
- }
- cc = &Credentials{
- AccessKeyId: provider.sessionCredentials.AccessKeyId,
- AccessKeySecret: provider.sessionCredentials.AccessKeySecret,
- SecurityToken: provider.sessionCredentials.SecurityToken,
- ProviderName: provider.GetProviderName(),
- }
- return
- }
- func (provider *URLCredentialsProvider) GetProviderName() string {
- return "credential_uri"
- }
|