Class: ClientHelper
- Inherits:
-
Object
- Object
- ClientHelper
- Defined in:
- lib/amazon-pay-api-sdk-ruby/client_helper.rb
Overview
ClientHelper class provides utility functions for API interactions
Instance Attribute Summary collapse
-
#base_url ⇒ Object
readonly
Returns the value of attribute base_url.
Instance Method Summary collapse
-
#authorization_header(signed_headers) ⇒ Object
Build authorization header from signed headers.
-
#build_canonical_request(method, uri, query, canonical_headers, payload) ⇒ Object
Build the canonical request string.
-
#build_uri(url_fragment, query) ⇒ Object
Build the full URI for the API request.
-
#canonicalize_headers(headers) ⇒ Object
Canonicalize headers by converting keys to lowercase and sorting them.
-
#create_request(method, uri, payload) ⇒ Object
AmazonPayClient dependency methods Create a new HTTP request.
-
#determine_environment(config) ⇒ Object
Determine the environment based on the public key or the config setting.
-
#endpoint ⇒ Object
Get endpoint URL based on region.
-
#fetch(key, config) ⇒ Object
Fetch value from config hash.
-
#formatted_timestamp ⇒ Object
Format the current timestamp.
-
#hex_and_hash(data) ⇒ Object
Compute SHA256 hash of the given data.
-
#http_method(method) ⇒ Object
Get HTTP method object based on method string.
-
#initialize(config) ⇒ ClientHelper
constructor
Initialize with configuration settings.
-
#normalize_headers(headers) ⇒ Object
Normalize headers by converting keys to strings and stripping values.
-
#prepare_headers(user_headers, uri, payload) ⇒ Object
Prepare headers for the API request.
-
#send_request(uri, request) ⇒ Object
Send the HTTP request.
-
#set_request_headers(request, signed_headers) ⇒ Object
Set headers for the HTTP request.
-
#sign(string_to_sign) ⇒ Object
Sign the given string using the private key.
-
#sign_headers(canonical_request, canonical_headers) ⇒ Object
Sign the canonical request headers.
-
#signed_headers(method, uri, payload, user_headers, query) ⇒ Object
Generate signed headers for the API request.
-
#to_query(query_params) ⇒ Object
Convert query parameters to URL query string.
-
#url_encode(value) ⇒ Object
URL encode the given value.
-
#validate_config(config) ⇒ Object
This method checks if all required configuration keys are present in the given config.
Constructor Details
#initialize(config) ⇒ ClientHelper
Initialize with configuration settings
13 14 15 16 17 18 19 20 21 22 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 13 def initialize(config) validate_config(config) @region = fetch(:region, config) @public_key_id = fetch(:public_key_id, config) @private_key = fetch(:private_key, config) @amazon_signature_algorithm = Constants::AMAZON_SIGNATURE_ALGORITHM @salt_length = 32 environment = determine_environment(config) @base_url = "https://#{endpoint}/#{environment}/#{Constants::API_VERSION}/" end |
Instance Attribute Details
#base_url ⇒ Object (readonly)
Returns the value of attribute base_url.
10 11 12 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 10 def base_url @base_url end |
Instance Method Details
#authorization_header(signed_headers) ⇒ Object
Build authorization header from signed headers
117 118 119 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 117 def (signed_headers) "#{@amazon_signature_algorithm} PublicKeyId=#{@public_key_id}, #{signed_headers}" end |
#build_canonical_request(method, uri, query, canonical_headers, payload) ⇒ Object
Build the canonical request string
100 101 102 103 104 105 106 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 100 def build_canonical_request(method, uri, query, canonical_headers, payload) headers_string = canonical_headers.map { |k, v| "#{k}:#{v}" }.join("\n") signed_headers = canonical_headers.keys.join(';') hashed_payload = hex_and_hash(payload) "#{method}\n#{uri.path}\n#{query}\n#{headers_string}\n\n#{signed_headers}\n#{hashed_payload}" end |
#build_uri(url_fragment, query) ⇒ Object
Build the full URI for the API request
157 158 159 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 157 def build_uri(url_fragment, query) URI.parse("#{@base_url}#{url_fragment}#{query.empty? ? '' : "?#{query}"}") end |
#canonicalize_headers(headers) ⇒ Object
Canonicalize headers by converting keys to lowercase and sorting them
95 96 97 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 95 def canonicalize_headers(headers) headers.transform_keys(&:downcase).sort.to_h end |
#create_request(method, uri, payload) ⇒ Object
AmazonPayClient dependency methods Create a new HTTP request
138 139 140 141 142 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 138 def create_request(method, uri, payload) request = http_method(method).new(uri) request.body = payload.is_a?(String) ? payload : JSON.generate(payload) request end |
#determine_environment(config) ⇒ Object
Determine the environment based on the public key or the config setting
25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 25 def determine_environment(config) @live = Constants::LIVE[0...-1].downcase @sandbox = Constants::SANDBOX[0...-1].downcase if @public_key_id.start_with?(Constants::LIVE) :live elsif @public_key_id.start_with?(Constants::SANDBOX) :sandbox else fetch(:sandbox, config) ? :sandbox : :live end end |
#endpoint ⇒ Object
Get endpoint URL based on region
43 44 45 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 43 def endpoint Constants::API_ENDPOINTS[@region] || raise(ArgumentError, "Unknown region: '#{@region}'. Valid regions are: #{Constants::API_ENDPOINTS.keys.join(', ')}.") end |
#fetch(key, config) ⇒ Object
Fetch value from config hash
38 39 40 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 38 def fetch(key, config) config[key] || config[key.to_s] end |
#formatted_timestamp ⇒ Object
Format the current timestamp
127 128 129 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 127 def Time.now.utc.iso8601.delete(':-') end |
#hex_and_hash(data) ⇒ Object
Compute SHA256 hash of the given data
122 123 124 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 122 def hex_and_hash(data) Digest::SHA256.hexdigest(data) end |
#http_method(method) ⇒ Object
Get HTTP method object based on method string
48 49 50 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 48 def http_method(method) Constants::METHOD_TYPES[method] || raise(ArgumentError, "Unknown HTTP method: '#{method}'. Valid methods are: #{Constants::METHOD_TYPES.keys.join(', ')}.") end |
#normalize_headers(headers) ⇒ Object
Normalize headers by converting keys to strings and stripping values
90 91 92 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 90 def normalize_headers(headers) headers.transform_keys(&:to_s).transform_values(&:strip) end |
#prepare_headers(user_headers, uri, payload) ⇒ Object
Prepare headers for the API request
77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 77 def prepare_headers(user_headers, uri, payload) headers = normalize_headers(user_headers) headers[Constants::ACCEPT] = headers[Constants::CONTENT_TYPE] = Constants::APPLICATION_JSON headers[Constants::X_AMZ_PAY_REGION] = @region headers[Constants::X_AMZ_PAY_DATE] = headers[Constants::X_AMZ_PAY_HOST] = uri.host headers[Constants::CONTENT_LENGTH] = payload.bytesize.to_s unless payload.empty? headers[Constants::X_AMZ_PAY_SDK_TYPE] = Constants::SDK_TYPE headers[Constants::X_AMZ_PAY_SDK_VERSION] = Constants::SDK_VERSION headers end |
#send_request(uri, request) ⇒ Object
Send the HTTP request
150 151 152 153 154 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 150 def send_request(uri, request) Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == Constants::HTTPS) do |http| http.request(request) end end |
#set_request_headers(request, signed_headers) ⇒ Object
Set headers for the HTTP request
145 146 147 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 145 def set_request_headers(request, signed_headers) signed_headers.each { |k, v| request[k] = v } end |
#sign(string_to_sign) ⇒ Object
Sign the given string using the private key
65 66 67 68 69 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 65 def sign(string_to_sign) hashed_request = "#{@amazon_signature_algorithm}\n#{hex_and_hash(string_to_sign)}" rsa = OpenSSL::PKey::RSA.new(@private_key) Base64.strict_encode64(rsa.sign_pss(Constants::HASH_ALGORITHM, hashed_request, salt_length: @salt_length, mgf1_hash: Constants::HASH_ALGORITHM)) end |
#sign_headers(canonical_request, canonical_headers) ⇒ Object
Sign the canonical request headers
109 110 111 112 113 114 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 109 def sign_headers(canonical_request, canonical_headers) hashed_request = "#{@amazon_signature_algorithm}\n#{hex_and_hash(canonical_request)}" rsa = OpenSSL::PKey::RSA.new(@private_key) signature = Base64.strict_encode64(rsa.sign_pss(Constants::HASH_ALGORITHM, hashed_request, salt_length: @salt_length, mgf1_hash: Constants::HASH_ALGORITHM)) "SignedHeaders=#{canonical_headers.keys.join(';')}, Signature=#{signature}" end |
#signed_headers(method, uri, payload, user_headers, query) ⇒ Object
Generate signed headers for the API request
53 54 55 56 57 58 59 60 61 62 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 53 def signed_headers(method, uri, payload, user_headers, query) headers = prepare_headers(user_headers, uri, payload) canonical_headers = canonicalize_headers(headers) canonical_request = build_canonical_request(method, uri, query, canonical_headers, payload) signed_headers = sign_headers(canonical_request, canonical_headers) # Add authorization header headers[Constants::AUTHORIZATION] = (signed_headers) headers end |
#to_query(query_params) ⇒ Object
Convert query parameters to URL query string
72 73 74 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 72 def to_query(query_params) URI.encode_www_form(query_params.sort.to_h) end |
#url_encode(value) ⇒ Object
URL encode the given value
132 133 134 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 132 def url_encode(value) URI.encode_www_form_component(value).gsub('%7E', '~') end |
#validate_config(config) ⇒ Object
This method checks if all required configuration keys are present in the given config. If any required key is missing, it raises a StandardError with a message listing the missing keys.
163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/amazon-pay-api-sdk-ruby/client_helper.rb', line 163 def validate_config(config) # Define the list of required keys. required_keys = %i[region public_key_id private_key] # Identify which required keys are missing from the config hash. missing_keys = required_keys.select { |key| config[key].nil? } # If there are missing keys, raise an error with a descriptive message. unless missing_keys.empty? raise StandardError, "Missing required config keys: #{missing_keys.join(', ')}" end end |