Class: Mastercard::Common::Connector
- Inherits:
-
Object
- Object
- Mastercard::Common::Connector
- Defined in:
- lib/mastercard_api/common/connector.rb
Constant Summary collapse
- NONCE_LENGTH =
8- VALID_CHARS =
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'- OAUTH_START_STRING =
'OAuth '- ERROR_STATUS_BOUNDARY =
300- EMPTY_STRING =
""- POST =
"POST"- GET =
"GET"- DELETE =
"DELETE"- PUT =
"PUT"- UTF_8 =
"UTF-8"- EQUALS =
"="- AMP =
'&'- COLON_2X_BACKSLASH =
"://"- MESSAGE =
"Message"- HTTP_CODE =
"HttpCode"- SSL_CA_CER_PATH_LOCATION =
'data/Certs/EnTrust/cacert.pem'- USER_AGENT =
'MC Open API OAuth Framework v1.0-Ruby'
Instance Attribute Summary collapse
-
#auth_header ⇒ Object
Returns the value of attribute auth_header.
-
#signature_base_string ⇒ Object
Returns the value of attribute signature_base_string.
-
#signed_signature_base_string ⇒ Object
Returns the value of attribute signed_signature_base_string.
Instance Method Summary collapse
-
#add_headers(url, request, request_method, oauth_params, body = nil) ⇒ Object
Method to build the OAuth headers.
-
#build_auth_header_string(url, request_method, oauth_params) ⇒ Object
Method to build the auth header for the HTTP request.
- #check_response(response) ⇒ Object
-
#connect(url, request_method, oauth_params, body = nil) ⇒ Object
Method to connect via HTTP.
-
#do_request(url, request_method, body = nil, oauth_params = nil) ⇒ Object
Method to perform a request.
-
#generate_body_hash(body, oauth_params) ⇒ Object
if a body is present for sending to server, needs hashed as part of OAuth spec.
-
#generate_nonce ⇒ Object
unique identifier for given timestamp (in seconds).
-
#generate_signature_base_string(url, request_method, oauth_params) ⇒ Object
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.
-
#generate_timestamp ⇒ Object
number of seconds since epoch.
-
#initialize(consumer_key, private_key) ⇒ Connector
constructor
consumer_key = Key provided by MasterCard upon registering private_key = private key object.
-
#normalize_parameters(url, oauth_params) ⇒ Object
The signature base string must be in lexical order prior to signing.
-
#normalize_url(url) ⇒ Object
Method to return “core” URL for signature base string generation.
-
#oauth_parameters_factory ⇒ Object
Method to generate base OAuth params.
-
#sign(oauth_params) ⇒ Object
Method to sign the signature base string using the private key.
Constructor Details
#initialize(consumer_key, private_key) ⇒ Connector
consumer_key = Key provided by MasterCard upon registering
private_key = private key object
45 46 47 48 49 50 51 |
# 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 |
Instance Attribute Details
#auth_header ⇒ Object
Returns the value of attribute auth_header.
17 18 19 |
# File 'lib/mastercard_api/common/connector.rb', line 17 def auth_header @auth_header end |
#signature_base_string ⇒ Object
Returns the value of attribute signature_base_string.
16 17 18 |
# File 'lib/mastercard_api/common/connector.rb', line 16 def signature_base_string @signature_base_string end |
#signed_signature_base_string ⇒ Object
Returns the value of attribute signed_signature_base_string.
18 19 20 |
# File 'lib/mastercard_api/common/connector.rb', line 18 def signed_signature_base_string @signed_signature_base_string end |
Instance Method Details
#add_headers(url, request, request_method, oauth_params, body = nil) ⇒ Object
Method to build the OAuth headers.
123 124 125 126 127 128 129 130 131 132 133 |
# 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) ⇒ Object
Method to build the auth header for the HTTP request.
oauth_params - full populated oauth parameters
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# 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) ⇒ Object
206 207 208 209 210 |
# 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) ⇒ Object
Method to connect via HTTP. This method subsequesntly builds and signs the Oauth
Header
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# 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) ⇒ Object
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
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# 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) ⇒ Object
if a body is present for sending to server, needs hashed as part of OAuth spec
213 214 215 216 217 218 219 |
# 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 ⇒ Object
unique identifier for given timestamp (in seconds)
222 223 224 225 226 227 228 |
# 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) ⇒ Object
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
175 176 177 |
# 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 ⇒ Object
number of seconds since epoch
230 231 232 |
# File 'lib/mastercard_api/common/connector.rb', line 230 def @oauth_timestamp = Time.now.to_i.to_s end |
#normalize_parameters(url, oauth_params) ⇒ Object
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
200 201 202 203 204 |
# 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) ⇒ Object
Method to return “core” URL for signature base string generation. somesite.com:8080?blah becomes somesite.com, for example
url - URL to normalize
182 183 184 185 186 187 188 189 190 191 192 193 194 |
# 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 ⇒ Object
Method to generate base OAuth params
55 56 57 58 59 60 61 62 63 |
# 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, ) oparams.add_parameter(OAUTH_SIGNATURE_METHOD, "RSA-SHA1") oparams.add_parameter(OAUTH_VERSION, "1.0") oparams end |
#sign(oauth_params) ⇒ Object
Method to sign the signature base string using the private key.
158 159 160 161 162 163 164 165 166 167 168 |
# 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 |