github.com/aliyun/credentials-go@v1.4.7/credentials/ram_role_arn_credentials_provider.go (about)

     1  package credentials
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"strconv"
     8  	"time"
     9  
    10  	"github.com/alibabacloud-go/tea/tea"
    11  	"github.com/aliyun/credentials-go/credentials/internal/utils"
    12  	"github.com/aliyun/credentials-go/credentials/request"
    13  )
    14  
    15  const defaultDurationSeconds = 3600
    16  
    17  // RAMRoleArnCredentialsProvider is a kind of credentials
    18  type RAMRoleArnCredentialsProvider struct {
    19  	*credentialUpdater
    20  	AccessKeyId           string
    21  	AccessKeySecret       string
    22  	SecurityToken         string
    23  	RoleArn               string
    24  	RoleSessionName       string
    25  	RoleSessionExpiration int
    26  	Policy                string
    27  	ExternalId            string
    28  	sessionCredential     *sessionCredential
    29  	runtime               *utils.Runtime
    30  }
    31  
    32  type ramRoleArnResponse struct {
    33  	Credentials *credentialsInResponse `json:"Credentials" xml:"Credentials"`
    34  }
    35  
    36  type credentialsInResponse struct {
    37  	AccessKeyId     string `json:"AccessKeyId" xml:"AccessKeyId"`
    38  	AccessKeySecret string `json:"AccessKeySecret" xml:"AccessKeySecret"`
    39  	SecurityToken   string `json:"SecurityToken" xml:"SecurityToken"`
    40  	Expiration      string `json:"Expiration" xml:"Expiration"`
    41  }
    42  
    43  func newRAMRoleArnl(accessKeyId, accessKeySecret, securityToken, roleArn, roleSessionName, policy string, roleSessionExpiration int, externalId string, runtime *utils.Runtime) *RAMRoleArnCredentialsProvider {
    44  	return &RAMRoleArnCredentialsProvider{
    45  		AccessKeyId:           accessKeyId,
    46  		AccessKeySecret:       accessKeySecret,
    47  		SecurityToken:         securityToken,
    48  		RoleArn:               roleArn,
    49  		RoleSessionName:       roleSessionName,
    50  		RoleSessionExpiration: roleSessionExpiration,
    51  		Policy:                policy,
    52  		ExternalId:            externalId,
    53  		credentialUpdater:     new(credentialUpdater),
    54  		runtime:               runtime,
    55  	}
    56  }
    57  
    58  func newRAMRoleArnCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string, roleSessionExpiration int, runtime *utils.Runtime) *RAMRoleArnCredentialsProvider {
    59  	return &RAMRoleArnCredentialsProvider{
    60  		AccessKeyId:           accessKeyId,
    61  		AccessKeySecret:       accessKeySecret,
    62  		RoleArn:               roleArn,
    63  		RoleSessionName:       roleSessionName,
    64  		RoleSessionExpiration: roleSessionExpiration,
    65  		Policy:                policy,
    66  		credentialUpdater:     new(credentialUpdater),
    67  		runtime:               runtime,
    68  	}
    69  }
    70  
    71  func newRAMRoleArnWithExternalIdCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string, roleSessionExpiration int, externalId string, runtime *utils.Runtime) *RAMRoleArnCredentialsProvider {
    72  	return &RAMRoleArnCredentialsProvider{
    73  		AccessKeyId:           accessKeyId,
    74  		AccessKeySecret:       accessKeySecret,
    75  		RoleArn:               roleArn,
    76  		RoleSessionName:       roleSessionName,
    77  		RoleSessionExpiration: roleSessionExpiration,
    78  		Policy:                policy,
    79  		ExternalId:            externalId,
    80  		credentialUpdater:     new(credentialUpdater),
    81  		runtime:               runtime,
    82  	}
    83  }
    84  
    85  func (e *RAMRoleArnCredentialsProvider) GetCredential() (*CredentialModel, error) {
    86  	if e.sessionCredential == nil || e.needUpdateCredential() {
    87  		err := e.updateCredential()
    88  		if err != nil {
    89  			return nil, err
    90  		}
    91  	}
    92  	credential := &CredentialModel{
    93  		AccessKeyId:     tea.String(e.sessionCredential.AccessKeyId),
    94  		AccessKeySecret: tea.String(e.sessionCredential.AccessKeySecret),
    95  		SecurityToken:   tea.String(e.sessionCredential.SecurityToken),
    96  		Type:            tea.String("ram_role_arn"),
    97  	}
    98  	return credential, nil
    99  }
   100  
   101  // GetAccessKeyId reutrns RAMRoleArnCredentialsProvider's AccessKeyId
   102  // if AccessKeyId is not exist or out of date, the function will update it.
   103  func (r *RAMRoleArnCredentialsProvider) GetAccessKeyId() (accessKeyId *string, err error) {
   104  	c, err := r.GetCredential()
   105  	if err != nil {
   106  		return
   107  	}
   108  
   109  	accessKeyId = c.AccessKeyId
   110  	return
   111  }
   112  
   113  // GetAccessSecret reutrns RAMRoleArnCredentialsProvider's AccessKeySecret
   114  // if AccessKeySecret is not exist or out of date, the function will update it.
   115  func (r *RAMRoleArnCredentialsProvider) GetAccessKeySecret() (accessKeySecret *string, err error) {
   116  	c, err := r.GetCredential()
   117  	if err != nil {
   118  		return
   119  	}
   120  
   121  	accessKeySecret = c.AccessKeySecret
   122  	return
   123  }
   124  
   125  // GetSecurityToken reutrns RAMRoleArnCredentialsProvider's SecurityToken
   126  // if SecurityToken is not exist or out of date, the function will update it.
   127  func (r *RAMRoleArnCredentialsProvider) GetSecurityToken() (securityToken *string, err error) {
   128  	c, err := r.GetCredential()
   129  	if err != nil {
   130  		return
   131  	}
   132  
   133  	securityToken = c.SecurityToken
   134  	return
   135  }
   136  
   137  // GetBearerToken is useless RAMRoleArnCredentialsProvider
   138  func (r *RAMRoleArnCredentialsProvider) GetBearerToken() *string {
   139  	return tea.String("")
   140  }
   141  
   142  // GetType reutrns RAMRoleArnCredentialsProvider's type
   143  func (r *RAMRoleArnCredentialsProvider) GetType() *string {
   144  	return tea.String("ram_role_arn")
   145  }
   146  
   147  func (r *RAMRoleArnCredentialsProvider) updateCredential() (err error) {
   148  	if r.runtime == nil {
   149  		r.runtime = new(utils.Runtime)
   150  	}
   151  	request := request.NewCommonRequest()
   152  	request.Domain = "sts.aliyuncs.com"
   153  	if r.runtime.STSEndpoint != "" {
   154  		request.Domain = r.runtime.STSEndpoint
   155  	}
   156  	request.Scheme = "HTTPS"
   157  	request.Method = "GET"
   158  	request.QueryParams["AccessKeyId"] = r.AccessKeyId
   159  	if r.SecurityToken != "" {
   160  		request.QueryParams["SecurityToken"] = r.SecurityToken
   161  	}
   162  	request.QueryParams["Action"] = "AssumeRole"
   163  	request.QueryParams["Format"] = "JSON"
   164  	if r.RoleSessionExpiration > 0 {
   165  		if r.RoleSessionExpiration >= 900 && r.RoleSessionExpiration <= 3600 {
   166  			request.QueryParams["DurationSeconds"] = strconv.Itoa(r.RoleSessionExpiration)
   167  		} else {
   168  			err = errors.New("[InvalidParam]:Assume Role session duration should be in the range of 15min - 1Hr")
   169  			return
   170  		}
   171  	} else {
   172  		request.QueryParams["DurationSeconds"] = strconv.Itoa(defaultDurationSeconds)
   173  	}
   174  	request.QueryParams["RoleArn"] = r.RoleArn
   175  	if r.Policy != "" {
   176  		request.QueryParams["Policy"] = r.Policy
   177  	}
   178  	if r.ExternalId != "" {
   179  		request.QueryParams["ExternalId"] = r.ExternalId
   180  	}
   181  	request.QueryParams["RoleSessionName"] = r.RoleSessionName
   182  	request.QueryParams["SignatureMethod"] = "HMAC-SHA1"
   183  	request.QueryParams["SignatureVersion"] = "1.0"
   184  	request.QueryParams["Version"] = "2015-04-01"
   185  	request.QueryParams["Timestamp"] = utils.GetTimeInFormatISO8601()
   186  	request.QueryParams["SignatureNonce"] = utils.GetUUID()
   187  	signature := utils.ShaHmac1(request.BuildStringToSign(), r.AccessKeySecret+"&")
   188  	request.QueryParams["Signature"] = signature
   189  	request.Headers["Host"] = request.Domain
   190  	request.Headers["Accept-Encoding"] = "identity"
   191  	request.URL = request.BuildURL()
   192  	content, err := doAction(request, r.runtime)
   193  	if err != nil {
   194  		return fmt.Errorf("refresh RoleArn sts token err: %s", err.Error())
   195  	}
   196  	var resp *ramRoleArnResponse
   197  	err = json.Unmarshal(content, &resp)
   198  	if err != nil {
   199  		return fmt.Errorf("refresh RoleArn sts token err: Json.Unmarshal fail: %s", err.Error())
   200  	}
   201  	if resp == nil || resp.Credentials == nil {
   202  		return fmt.Errorf("refresh RoleArn sts token err: Credentials is empty")
   203  	}
   204  	respCredentials := resp.Credentials
   205  	if respCredentials.AccessKeyId == "" || respCredentials.AccessKeySecret == "" || respCredentials.SecurityToken == "" || respCredentials.Expiration == "" {
   206  		return fmt.Errorf("refresh RoleArn sts token err: AccessKeyId: %s, AccessKeySecret: %s, SecurityToken: %s, Expiration: %s", respCredentials.AccessKeyId, respCredentials.AccessKeySecret, respCredentials.SecurityToken, respCredentials.Expiration)
   207  	}
   208  
   209  	expirationTime, err := time.Parse("2006-01-02T15:04:05Z", respCredentials.Expiration)
   210  	r.lastUpdateTimestamp = time.Now().Unix()
   211  	r.credentialExpiration = int(expirationTime.Unix() - time.Now().Unix())
   212  	r.sessionCredential = &sessionCredential{
   213  		AccessKeyId:     respCredentials.AccessKeyId,
   214  		AccessKeySecret: respCredentials.AccessKeySecret,
   215  		SecurityToken:   respCredentials.SecurityToken,
   216  	}
   217  
   218  	return
   219  }