Module: Signifyd

Defined in:
lib/signifyd.rb,
lib/signifyd/case.rb,
lib/signifyd/util.rb,
lib/signifyd/version.rb,
lib/signifyd/api/list.rb,
lib/signifyd/resource.rb,
lib/signifyd/api/create.rb,
lib/signifyd/api/update.rb,
lib/signifyd/signifyd_object.rb,
lib/signifyd/errors/api_error.rb,
lib/signifyd/errors/signifyd_error.rb,
lib/signifyd/errors/api_connection_error.rb,
lib/signifyd/errors/authentication_error.rb,
lib/signifyd/errors/invalid_request_error.rb,
lib/signifyd/errors/not_implemented_error.rb

Defined Under Namespace

Modules: API Classes: APIConnectionError, APIError, AuthenticationError, Case, InvalidRequestError, NotImplementedError, Resource, SignifydError, SignifydObject, Util

Constant Summary collapse

VERSION =
'0.1.5'
@@ssl_bundle_path =

ssl_bundle_path

Path to hold Signifyd.com’s certificate @return: String[path to certificate file]

File.join(File.dirname(__FILE__), 'data/ca-certificates.crt')
@@api_key =

api_key

Default point for where the application will hold the API_KEY for the current instance. If not set, must be passed in all calls as last parameter.

nil
@@api_base =

api_base

Root url where the Signifyd API endpoints will live. This can be changed by setting Signifyd.test_mode = true and will default to staging env. @return: String[url to Signifyd’s API]

'https://api.signifyd.com'
@@api_version =

api_version

Version right now will be the url structure, might change later. For now this is ok. @return: String[url path of our current api version]

'/v2'
@@verify_ssl_certs =

verify_ssl_certs

When this is set to false, any request made will not be a verfied and supported request by Signifyd. This should be set to true and the library will use the Signifyd keys..not for now :/ @return: Boolean

true
@@test_mode =

test_mode

When set to true, will default to Signifyd’s staging environment. This as well should always be set to false. @return: Boolean

false
@@local_mode =

local_mode

When set to true, will default to a local environment of localhost:9000. This as well should always be set to false. @return: Boolean

false

Class Method Summary collapse

Class Method Details

.api_baseObject

api_base

Getter method for the API base that has been set by the application. @return: String[api base]



148
149
150
# File 'lib/signifyd.rb', line 148

def self.api_base
  @@api_base
end

.api_base=(api_base) ⇒ Object

api_base=

Setter method to set the API url base. Set into class variable and used globally on all calls made. @return: String[api base]



140
141
142
# File 'lib/signifyd.rb', line 140

def self.api_base=(api_base)
  @@api_base = api_base
end

.api_keyObject

api_key

Getter method for the API key that has been set by the application. @return: String[api key]



114
115
116
# File 'lib/signifyd.rb', line 114

def self.api_key
  @@api_key
end

.api_key=(api_key) ⇒ Object

api_key=

Setter method to set the API key. Set into class variable and used globally on all calls made. @return: String[api key]



106
107
108
# File 'lib/signifyd.rb', line 106

def self.api_key=(api_key)
  @@api_key = api_key
end

.api_url(url = '') ⇒ Object

@return: String[url for request to be made]



97
98
99
# File 'lib/signifyd.rb', line 97

def self.api_url(url='')
  @@api_base + url
end

.api_versionObject

api_version

Getter method for the API version that has been set by the application. @return: String[api url version]



131
132
133
# File 'lib/signifyd.rb', line 131

def self.api_version
  @@api_version
end

.api_version=(api_version) ⇒ Object

api_version=

Setter method to set the API version. Set into class variable and used globally on all calls made. @return: String[api url version]



123
124
125
# File 'lib/signifyd.rb', line 123

def self.api_version=(api_version)
  @@api_version = api_version
end

.authentication_error(error, rcode, rbody) ⇒ Object



371
372
373
# File 'lib/signifyd.rb', line 371

def self.authentication_error(error, rcode, rbody)
  raise AuthenticationError.new(error[:message], error[:param], rcode, rbody)
end

.execute_request(opts) ⇒ Object

execute_request

Handles the request, pass in opts hash, RestClient makes the call. @param: Hash - Configured options from Signifyd.request method. @return: RestClient::Request - the result of the request.



322
323
324
# File 'lib/signifyd.rb', line 322

def self.execute_request(opts)
  RestClient::Request.execute(opts)
end

.general_api_error(rcode, rbody) ⇒ Object

Raises:



375
376
377
# File 'lib/signifyd.rb', line 375

def self.general_api_error(rcode, rbody)
  raise APIError.new("Invalid response object from API: #{rbody.inspect} (HTTP response code was #{rcode})", rcode, rbody)
end

.handle_api_error(rcode, rbody) ⇒ Object

handle_api_error

@param: String @param: String



349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/signifyd.rb', line 349

def self.handle_api_error(rcode, rbody)
  error = {}
  case rcode
  when 400, 404
    error[:message] = "Invalid request"
    error[:param]  = ""
    raise invalid_request_error error, rcode, rbody
  when 401
    error[:message] = "Authentication error"
    error[:param]  = ""
    raise authentication_error error, rcode, rbody
  else
    error[:message] = "API error"
    error[:param]  = ""
    raise general_api_error rcode, rbody
  end
end

.handle_restclient_error(e) ⇒ Object

handle_restclient_error

@param: RestClient - could be many different types of errors. @return: String[error message]

Raises:



330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/signifyd.rb', line 330

def self.handle_restclient_error(e)
  case e
  when RestClient::ServerBrokeConnection, RestClient::RequestTimeout
    message = "Could not connect to Signifyd (#{@@api_base}).  Please check your internet connection and try again."
  when RestClient::SSLCertificateNotVerified
    message = "Could not verify Signifyd's SSL certificate.  Please make sure that your network is not intercepting certificates.  (Try going to https://api.signifyd.com/v2 in your browser.)  If this problem persists, let us know at [email protected]."
  when SocketError
    message = "Unexpected error communicating when trying to connect to Signifyd.  HINT: You may be seeing this message because your DNS is not working.  To check, try running 'host signifyd.com' from the command line."
  else
    message = "Unexpected error communicating with Signifyd.  If this problem persists, let us know at [email protected]."
  end
  message += "\n\n(Network error: #{e.message})"
  raise APIConnectionError.new(message)
end

.invalid_request_error(error, rcode, rbody) ⇒ Object



367
368
369
# File 'lib/signifyd.rb', line 367

def self.invalid_request_error(error, rcode, rbody)
  raise InvalidRequestError.new(error[:message], error[:param], rcode, rbody)
end

.local_modeObject

local_mode

Getter method for the API test_mode that has been set by the application. @return: Boolean



201
202
203
# File 'lib/signifyd.rb', line 201

def self.local_mode
  @@local_mode
end

.local_mode=(local_mode) ⇒ Object

local_mode=

Setter method to set the API local_mode. Set into class variable and used globally on all calls made. @return: Boolean



192
193
194
195
# File 'lib/signifyd.rb', line 192

def self.local_mode=(local_mode)
  Signifyd.api_base = 'http://localhost:9000' if local_mode && !self.test_mode
  @@local_mode = local_mode
end

.request(method, url, params = {}, api_key = nil, options = {}) ⇒ Object

request

Global method that will use RestClient to make all requests. Everything else is set between Signifyd.setter methods. This method is called from other methods so direct calls won’t be necessary.

@param: String - :get, :post, :put, :delete @param: String - ‘/cases’ @param: Hash - transaction… @param: String - ‘YOUR-API-KEY’ @param: Hash - optional parameters @return: Hash - containing response code, body, and other data



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/signifyd.rb', line 217

def self.request(method, url, params={}, api_key=nil, options={})
  api_key = api_key.nil? ? @@api_key : api_key
  raise AuthenticationError.new('No API key provided. Fix: Signifyd.api_key = \'Your API KEY\'') unless api_key

  uname = (@@uname ||= RUBY_PLATFORM =~ /linux|darwin/i ? `uname -a 2>/dev/null`.strip : nil)
  lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
  ua = {
    :bindings_version => Signifyd::VERSION,
    :lang => 'ruby',
    :lang_version => lang_version,
    :platform => RUBY_PLATFORM,
    :publisher => 'signifyd',
    :uname => uname
  }

  if @@verify_ssl_certs
    ssl_opts = {
      :verify_ssl  => OpenSSL::SSL::VERIFY_PEER,
      :ssl_ca_file => @@ssl_bundle_path
    }
  else
    ssl_opts = {
      :verify_ssl => OpenSSL::SSL::VERIFY_NONE
    }
  end

  # Determine how to send the data and encode it based on what method we are sending. Some
  # are necessary, some are not.
  case method.to_s
  when 'get'
    if options.has_key?(:order_id)
      url = url.gsub('cases', "orders/#{options[:order_id]}/case")
    end
  when 'post'

  when 'put'
    # we need to eject out the case_id from the params hash and append it to the url
    if params.has_key?(:case_id) || params.has_key?('case_id')
      case_id = params.delete(:case_id)
      params.reject! { |k| k == :case_id || k == 'case_id' }
      url << "/#{case_id}"
    end
  when 'delete'

  end

  # Create the full url here
  url = self.api_url(url)

  # Parse into valid json
  payload = JSON.dump(params)

  # Convert the key
  authkey = api_key == {} || api_key == nil ? '' : Base64.encode64(api_key)

  # Headers must contain these keys
  headers = {
    "Content-Length"  => payload.size,
    "Content-Type"    => "application/json",
    "Authorization"   => "Basic #{authkey}",
    'User-Agent'      => "Signifyd Ruby #{@@api_version.gsub('/', '')}"
  }

  # All necessary options must be set
  opts = {
    :method => method,
    :url => url,
    :headers => headers,
    :open_timeout => 30,
    :payload => payload,
    :timeout => 80
  }.merge(ssl_opts)

  # Make the request
  begin
    response = execute_request(opts)
  rescue SocketError => e
    self.handle_restclient_error(e)
  rescue NoMethodError => e
    if e.message =~ /\WRequestFailed\W/
      e = APIConnectionError.new('Unexpected HTTP response code')
      self.handle_restclient_error(e)
    else
      raise
    end
  rescue RestClient::ExceptionWithResponse => e
    if rcode = e.http_code and rbody = e.http_body
      self.handle_api_error(rcode, rbody)
    else
      self.handle_restclient_error(e)
    end
  rescue RestClient::Exception, Errno::ECONNREFUSED => e
    self.handle_restclient_error(e)
  end

  rbody = response.body
  rcode = response.code
  return {code: rcode, body: JSON.parse(rbody)}
end

.ssl_bundle_pathObject

ssl_bundle_path

Returns the path to the certificate store location



86
87
88
# File 'lib/signifyd.rb', line 86

def self.ssl_bundle_path
  @@ssl_bundle_path
end

.test_modeObject

test_mode

Getter method for the API test_mode that has been set by the application. @return: Boolean



183
184
185
# File 'lib/signifyd.rb', line 183

def self.test_mode
  @@test_mode
end

.test_mode=(test_mode) ⇒ Object

test_mode=

Setter method to set the API test_mode. Set into class variable and used globally on all calls made. @return: Boolean



174
175
176
177
# File 'lib/signifyd.rb', line 174

def self.test_mode=(test_mode)
  Signifyd.api_base = 'https://staging.signifyd.com' if test_mode && !self.local_mode
  @@test_mode = test_mode
end

.verify_ssl_certsObject

verify_ssl_certs

Getter method for the API verify_ssl_certs that has been set by the application. @return: Boolean



165
166
167
# File 'lib/signifyd.rb', line 165

def self.verify_ssl_certs
  @@verify_ssl_certs
end

.verify_ssl_certs=(verify) ⇒ Object

verify_ssl_certs=

Setter method to set the API verify_ssl_certs. Set into class variable and used globally on all calls made. @return: Boolean



157
158
159
# File 'lib/signifyd.rb', line 157

def self.verify_ssl_certs=(verify)
  @@verify_ssl_certs = verify
end