class Mastercard::Common::Connector

Constants

AMP
COLON_2X_BACKSLASH
DELETE
EMPTY_STRING
EQUALS
ERROR_STATUS_BOUNDARY
GET
HTTP_CODE
MESSAGE
NONCE_LENGTH
OAUTH_START_STRING
POST
PUT
SSL_CA_CER_PATH_LOCATION
USER_AGENT
UTF_8
VALID_CHARS

Attributes

auth_header[RW]
signature_base_string[RW]
signed_signature_base_string[RW]

Public Class Methods

new(consumer_key, private_key) click to toggle source
consumer_key = Key provided by MasterCard upon registering
private_key = private key object

end

# File lib/mastercard_api/common/connector.rb, line 45
def initialize(consumer_key, private_key)
  @consumer_key = consumer_key
  @private_key = private_key
  @signature_base_string = ''
  @auth_header = ''
  @signed_signature_base_string = ''
end

Public Instance Methods

add_headers(url, request, request_method, oauth_params, body=nil) click to toggle source
Method to build the OAuth headers.

end

# File lib/mastercard_api/common/connector.rb, line 123
def add_headers(url, request, request_method, oauth_params, body=nil)
  @auth_header = build_auth_header_string(url, request_method, oauth_params)
  request['Authorization'] = auth_header
  request['User-Agent'] = USER_AGENT
  if body != nil
    request['content-type'] = 'application/xml;charset=UTF-8'
    body_length = body.length
    request['content-length'] = body_length.to_s
  end
  request
end
build_auth_header_string(url, request_method, oauth_params) click to toggle source
Method to build the auth header for the HTTP request.
oauth_params - full populated oauth parameters

end

# File lib/mastercard_api/common/connector.rb, line 138
def build_auth_header_string(url, request_method, oauth_params)
  temp_params = Mastercard::Common::OAuthParameters.new
  oauth_params_key_arr = oauth_params.params.keys.sort
  oauth_params_key_arr.each do |p|
    temp_params.add_parameter(p, oauth_params.send(p)) if p != :realm
  end
  generate_signature_base_string(url, request_method, temp_params) 
  sign(oauth_params)
  header = ''
  oauth_params_key_arr = oauth_params.params.keys.sort
  oauth_params_key_arr.each do |p|
    header << p.to_s << '="' << oauth_params.send(p) << '",' if oauth_params.send(p)
  end
  header = '' << OAUTH_START_STRING << header
  #remove trailing comma
  header = header[0...header.length-1]
end
check_response(response) click to toggle source
# File lib/mastercard_api/common/connector.rb, line 206
def check_response(response)
  if response.code.to_i >= ERROR_STATUS_BOUNDARY
    raise 'Response Code: ' << response.code.to_s << "\n" << response.body
  end
end
connect(url, request_method, oauth_params, body=nil) click to toggle source
Method to connect via HTTP. This method subsequesntly builds and signs the Oauth
Header

end

# File lib/mastercard_api/common/connector.rb, line 93
def connect(url, request_method, oauth_params, body=nil)
  uri = URI.parse(url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  http.ca_path = SSL_CA_CER_PATH_LOCATION
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE #todo VERIFY_PEER

  if request_method.upcase == 'GET'
    request = Net::HTTP::Get.new(uri.request_uri)
  elsif request_method.upcase == 'PUT'
    request = Net::HTTP::Put.new(uri.request_uri)
  elsif request_method.upcase == 'POST'
    request = Net::HTTP::Post.new(uri.request_uri)
  elsif request_method.upcase == 'DELETE'
    request = Net::HTTP::Delete.new(uri.request_uri)
  else
    raise 'Unsupported HTTP Action.'
  end

  if body != nil
    add_headers(url, request, request_method, oauth_params, body)
    request.body = body
  else
    add_headers(url, request, request_method, oauth_params)
  end
  http.request(request)
end
do_request(url, request_method, body = nil, oauth_params = nil) click to toggle source
Method to perform a request.  Only Connector subclasses should access this method.
url - URL to connect to, includes query string parameters
body - XML body to send to MasterCard for PUT/POST/DELETE
oauth_params - often nil, may be populated for testing

end

# File lib/mastercard_api/common/connector.rb, line 71
def do_request(url, request_method, body = nil, oauth_params = nil)
  if @consumer_key == nil
    raise 'Consumer Key may not be nil.'
  end

  if @private_key == nil
    raise 'Private Key may not be nil.'
  end
  if oauth_params == nil
    oauth_params = oauth_parameters_factory
  end
  if body != nil && body.length > 0
    oauth_params = generate_body_hash(body, oauth_params)
  end
  response = connect(url, request_method, oauth_params, body)
  check_response(response)
  response.body
end
generate_body_hash(body, oauth_params) click to toggle source

if a body is present for sending to server, needs hashed as part of OAuth spec

# File lib/mastercard_api/common/connector.rb, line 213
def generate_body_hash(body, oauth_params)
  if body != nil
    oauth_body_hash = Digest::SHA1.base64digest(body)
    oauth_params.add_parameter(:oauth_body_hash, oauth_body_hash)
  end
  oauth_params
end
generate_nonce() click to toggle source

unique identifier for given timestamp (in seconds)

# File lib/mastercard_api/common/connector.rb, line 222
def generate_nonce
  str = ''
  for i in 1..NONCE_LENGTH
    str << VALID_CHARS[SecureRandom.random_number(VALID_CHARS.length)]
  end
  @oauth_nonce = str
end
generate_signature_base_string(url, request_method, oauth_params) click to toggle source
Method to generate the signature base string from the url, HTTP request method, and oauth_params
url - URL, including query string parameters, to access
request_method - case-insensitive HTTP request method, e.g. GET, POST, PUT, DELETE
oauth_params - populated oauth parameters object

end

# File lib/mastercard_api/common/connector.rb, line 175
def generate_signature_base_string(url, request_method, oauth_params)
  @signature_base_string = CGI.escape(request_method.upcase) << AMP << CGI.escape(normalize_url(url)) << AMP << CGI.escape(normalize_parameters(url, oauth_params))
end
generate_timestamp() click to toggle source

number of seconds since epoch

# File lib/mastercard_api/common/connector.rb, line 230
def generate_timestamp
  @oauth_timestamp = Time.now.to_i.to_s
end
normalize_parameters(url, oauth_params) click to toggle source
The signature base string must be in lexical order prior to signing. This method does that required work.
url - url to access
oauth_params - OAuthParameters object used for building Signature Base String

end

# File lib/mastercard_api/common/connector.rb, line 200
def normalize_parameters(url, oauth_params)
  oauth_params_hash = oauth_params.params
  CGI.parse(URI.parse(url).query).map{|k,v| oauth_params_hash[k.to_sym] = v[0]} if url.include? "?"
  URI.encode(oauth_params_hash.keys.sort.map{|k| "#{k.to_s}=#{oauth_params_hash[k]}"}.join("&"))
end
normalize_url(url) click to toggle source
Method to return "core" URL for signature base string generation.  http://somesite.com:8080?blah becomes http://somesite.com, for example
url - URL to normalize

end

# File lib/mastercard_api/common/connector.rb, line 182
def normalize_url(url)
  tmp = url.clone
  # strip query string section
  idx = tmp.index('?')
  if idx != nil
    tmp = tmp[0..idx-1]
  end
  # strip port
  if tmp.rindex(':') != nil && tmp.rindex(':') > 5 # implies port is given
    tmp = tmp[0..tmp.rindex(':')-1]
  end
  tmp
end
oauth_parameters_factory() click to toggle source
Method to generate base OAuth params

end

# File lib/mastercard_api/common/connector.rb, line 55
def oauth_parameters_factory
  oparams = Mastercard::Common::OAuthParameters.new
  oparams.add_parameter(OAUTH_CONSUMER_KEY, @consumer_key)
  oparams.add_parameter(OAUTH_NONCE, generate_nonce)
  oparams.add_parameter(OAUTH_TIMESTAMP, generate_timestamp)
  oparams.add_parameter(OAUTH_SIGNATURE_METHOD, "RSA-SHA1")
  oparams.add_parameter(OAUTH_VERSION, "1.0")
  oparams
end
sign(oauth_params) click to toggle source
Method to sign the signature base string using the private key.

end

# File lib/mastercard_api/common/connector.rb, line 158
def sign(oauth_params)
  if @signature_base_string == nil || @signature_base_string.length == 0
    raise 'Signature Base String May Not Be Null.'
  end
  digest = OpenSSL::Digest::SHA1.new
  @signed_signature_base_string =  CGI.escape(Base64.encode64(@private_key.sign(digest,@signature_base_string)))
  @signed_signature_base_string.gsub!('+','%20')
  @signed_signature_base_string.gsub!('*','%2A')
  @signed_signature_base_string.gsub!('~','%7E')
  oauth_params.add_parameter("oauth_signature" , @signed_signature_base_string)
end