Skip to content

Commit

Permalink
feat: OIDC support (#19)
Browse files Browse the repository at this point in the history
* feat: oidc

* Update oidc_credential.rb
  • Loading branch information
sesky4 authored Feb 11, 2025
1 parent 49715f8 commit 645579b
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 6 deletions.
1 change: 1 addition & 0 deletions tencentcloud-sdk-common/lib/tencentcloud-sdk-common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
require_relative 'tencentcloud-sdk-common/sign'
require_relative 'tencentcloud-sdk-common/http/request'
require_relative 'tencentcloud-sdk-common/client'
require_relative 'tencentcloud-sdk-common/oidc_credential'

module TencentCloud
# sdk common module
Expand Down
15 changes: 9 additions & 6 deletions tencentcloud-sdk-common/lib/tencentcloud-sdk-common/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ class AbstractClient
include Log

def initialize(credential, region, api_version, api_endpoint, sdk_version, profile = nil)
raise TencentCloudSDKException.new('InvalidCredential', 'Credential is None or invalid') unless credential

@credential = credential
@region = region
@api_version = api_version
Expand Down Expand Up @@ -85,7 +83,6 @@ def build_req_with_v3_signature(action, params, req, options = {})
req.header['X-TC-Version'] = @api_version
req.header['X-TC-Region'] = @region
req.header['X-TC-Language'] = @profile.language
req.header['X-TC-Token'] = @credential.token if @credential.token
req.header['X-TC-Content-SHA256'] = 'UNSIGNED-PAYLOAD' if @profile.unsigned_payload
req.header['X-TC-TraceId'] = SecureRandom.uuid
if req.method == 'GET'
Expand Down Expand Up @@ -128,9 +125,15 @@ def build_req_with_v3_signature(action, params, req, options = {})
payload = 'UNSIGNED-PAYLOAD' if @profile.unsigned_payload
hashed_payload = Digest::SHA256.hexdigest(payload)

authorization = Sign.sign_v3(content_type, endpoint, @profile.http_profile.req_method, req.uri,
canonical_querystring, hashed_payload, req.header['X-TC-Timestamp'],
@credential.secret_id, @credential.secret_key)
if @credential.nil?
authorization = "SKIP"
else
secret_id, secret_key, token = @credential.credential
authorization = Sign.sign_v3(content_type, endpoint, @profile.http_profile.req_method, req.uri,
canonical_querystring, hashed_payload, req.header['X-TC-Timestamp'],
secret_id, secret_key)
req.header['X-TC-Token'] = token if token
end
req.header['Authorization'] = authorization
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ def initialize(secret_id, secret_key, token = nil)
@secret_key = secret_key
@token = token
end

def credential
[@secret_id, @secret_key, @token]
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# frozen_string_literal: true
require 'time'

module TencentCloud
module Common
class OIDCCredential
SES_NAME = 'tencentcloud-ruby-sdk-'
SES_DUR = 7200
API_VERSION = '2018-08-13'
API_ENDPOINT = 'sts.tencentcloudapi.com'
API_ACTION = 'AssumeRoleWithWebIdentity'
SDK_VERSION = 'CLB_' + File.read(File.expand_path('../VERSION', __dir__)).strip

attr_accessor :secret_id, :secret_key, :token

def initialize
@expire_t = 0
initialize_args
end

def credential
refresh
[@secret_id, @secret_key, @token]
end

def initialize_args
@region = ENV['TKE_REGION']
@provider_id = ENV['TKE_PROVIDER_ID']
token_file = ENV['TKE_WEB_IDENTITY_TOKEN_FILE']
@role_arn = ENV['TKE_ROLE_ARN']
@ses_name = SES_NAME + (Time.now.to_r * 1_000).to_i.to_s
@ses_dur = SES_DUR

if @region.nil? || @provider_id.nil? || token_file.nil? || @role_arn.nil? || @ses_name.nil? || @ses_dur.nil?
raise TencentCloudSDKException.new('InvalidCredential', 'env TKE_REGION, TKE_PROVIDER_ID, TKE_WEB_IDENTITY_TOKEN_FILE, TKE_ROLE_ARN not exist')
end

@token = File.read(token_file).strip
end

def refresh
if @expire_t - Time.now.to_i > SES_DUR / 10
return
end

initialize_args

client = AbstractClient.new(nil, @region, API_VERSION, API_ENDPOINT, SDK_VERSION, nil)

req = {
'ProviderId': @provider_id,
'WebIdentityToken': @token,
'RoleArn': @role_arn,
'RoleSessionName': @ses_name,
'DurationSeconds': @ses_dur,
}
response = JSON.parse(client.send_request(API_ACTION, req))
if response['Response'].key?('Error')
code = response['Response']['Error']['Code']
message = response['Response']['Error']['Message']
reqid = response['Response']['RequestId']
raise TencentCloud::Common::TencentCloudSDKException.new(code, message, reqid)
end

@secret_id = response['Response']['Credentials']['TmpSecretId']
@secret_key = response['Response']['Credentials']['TmpSecretKey']
@token = response['Response']['Credentials']['Token']
@expire_t = response['Response']['ExpiredTime']
end
end
end
end

0 comments on commit 645579b

Please sign in to comment.