class Ingenico::Direct::SDK::DefaultImpl::DefaultAuthenticator
Authenticates requests made to the Ingenico
ePayments platform using the HMAC algorithm.
Constants
- CONTENT_TYPE
- DATE
- HMAC_ALGOR
HMAC algorithm used to generate the signature
- XGCS
Public Class Methods
Construct a new DefaultAuthenticator
instance that can sign requests with the provided api_key_id and secret_api_key.
@param api_key_id [String] identifier for the secret key used in authentication. @param secret_api_key [String] the secret key that is used to generate the authentication signature. @param authorization_type [String] the authorization protocol to use for authentication.
# File lib/ingenico/direct/sdk/defaultimpl/default_authenticator.rb, line 22 def initialize(api_key_id, secret_api_key, authorization_type = AuthorizationType::V1HMAC) raise ArgumentError unless api_key_id && !api_key_id.strip.empty? raise ArgumentError unless secret_api_key && !secret_api_key.strip.empty? raise ArgumentError unless authorization_type && !authorization_type.strip.empty? @api_key_id = api_key_id @secret_api_key = secret_api_key @authorization_type = authorization_type end
Public Instance Methods
Creates a signature to authenticate a request.
@param http_method [String] 'GET', 'PUT', 'POST' or 'DELETE' indicating which HTTP method will be used with the request @param resource_uri [URI::HTTP] URI object that includes path and query of the URL that will be used, query may be nil @param http_headers [Array<Ingenico::Direct::SDK::RequestHeader>] list that contains all headers used by the request @return [String] the created signature
# File lib/ingenico/direct/sdk/defaultimpl/default_authenticator.rb, line 38 def create_simple_authentication_signature(http_method, resource_uri, http_headers) raise ArgumentError unless http_method && !http_method.strip.empty? raise ArgumentError unless resource_uri data_to_sign = to_data_to_sign(http_method, resource_uri, http_headers) "GCS #{@authorization_type}:#{@api_key_id}:#{create_auth_signature(data_to_sign)}" end
Protected Instance Methods
Applies the HMAC algorithm to the canonicalized data to obtain an HMAC digest. Afterwards the HMAC digest is encoded using base64 encoding.
# File lib/ingenico/direct/sdk/defaultimpl/default_authenticator.rb, line 83 def create_auth_signature(data_to_sign) digest = OpenSSL::Digest.new(HMAC_ALGOR) hmac = OpenSSL::HMAC.digest(digest, @secret_api_key, data_to_sign) Base64.strict_encode64(hmac).strip end
Canonizes the http_method, resource_uri and http_headers so a unique signature can be generated. Canonical form is as follows:
-
http_method in upper case
-
Content-Type
-
Date header
-
X-GCS headers sorted alphabetically. Names are in lowercase and values are stripped of excess whitespace
-
path and query portion of the uri, separated by a question mark
# File lib/ingenico/direct/sdk/defaultimpl/default_authenticator.rb, line 55 def to_data_to_sign(http_method, resource_uri, http_headers) content_type = '' date = '' canonical_resource = to_canonical_resource(resource_uri) xgc_http_headers = [] http_headers&.each do |header| name = header.name value = header.value case when name.casecmp(CONTENT_TYPE).zero? content_type = value when name.casecmp(DATE).zero? date = value when to_canonical_header_name(name).start_with?("x-gcs") xgc_http_headers << [to_canonical_header_name(name), to_canonical_header_value(value)] end end xgc_http_headers.sort! { |(h1, v1), (h2, v2)| h1 <=> h2 } unless xgc_http_headers.empty? data = "#{http_method.upcase}\n#{content_type}\n#{date}\n" data << xgc_http_headers.inject('') { |s, (k, v)| "#{s}#{k}:#{v}\n" } unless xgc_http_headers.empty? data << "#{canonical_resource}\n" if canonical_resource end
Private Instance Methods
# File lib/ingenico/direct/sdk/defaultimpl/default_authenticator.rb, line 97 def to_canonical_header_name(original_name) original_name ? original_name.downcase : original_name end
Strips a header value of excess whitespace to produce a canonical value
# File lib/ingenico/direct/sdk/defaultimpl/default_authenticator.rb, line 102 def to_canonical_header_value(original_value) return '' unless original_value original_value.gsub(/\r?\n[\s&&[^\r\n]]*/, ' ').strip end
Returns the encoded URI path without the HTTP method and including all decoded query parameters.
# File lib/ingenico/direct/sdk/defaultimpl/default_authenticator.rb, line 92 def to_canonical_resource(resource_uri) return "#{resource_uri.path}?#{resource_uri.query}" if resource_uri.query resource_uri.path end