...

Source file src/github.com/aliyun/credentials-go/credentials/sts_role_arn_credential.go

Documentation: github.com/aliyun/credentials-go/credentials

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

View as plain text