module Eligible
Constants
- VERSION
Public Class Methods
Source
# File lib/eligible.rb, line 101 def self.add_fingerprint(digest) $stderr.puts 'The embedded certificate fingerprint was modified. This should only be done if instructed to by eligible support staff' @@fingerprints << digest end
Source
# File lib/eligible.rb, line 77 def self.api_base=(api_base) @@api_base = api_base end
Source
# File lib/eligible.rb, line 299 def self.api_error(error_msg, rcode, rbody, error_obj) APIError.new(error_msg, rcode, rbody, error_obj) end
Source
# File lib/eligible.rb, line 69 def self.api_key=(api_key) @@api_key = api_key end
Source
# File lib/eligible.rb, line 114 def self.api_key?(params) Util.key?(params, :api_key) end
Source
# File lib/eligible.rb, line 61 def self.api_url(url = '') @@api_base + url.to_s end
Source
# File lib/eligible.rb, line 89 def self.api_version=(version) @@api_version = version end
Source
# File lib/eligible.rb, line 295 def self.authentication_error(error_msg, rcode, rbody, error_obj) AuthenticationError.new(error_msg, rcode, rbody, error_obj) end
Source
# File lib/eligible.rb, line 262 def self.compose_message_from_error(error) return error.to_s unless error.is_a?(Hash) result = error[:details] || error[:reject_reason_description] || error return result.to_s end
Source
# File lib/eligible.rb, line 255 def self.compose_message_from_errors(errors) return unless errors.is_a?(Array) return errors.first[:message] if errors.size == 1 return errors.each_with_index.map { |error, index| "#{index + 1}. #{error[:message]}" }.join("\n") end
Source
# File lib/eligible.rb, line 106 def self.direct_response?(params) params[:format].is_a?(String) && params[:format].downcase == 'x12' end
Source
# File lib/eligible.rb, line 248 def self.error_message(error, errors) message = compose_message_from_errors(errors) return message if message return compose_message_from_error(error) end
Source
# File lib/eligible.rb, line 244 def self.execute_request(opts) RestClient::Request.execute(opts) end
Source
# File lib/eligible.rb, line 268 def self.handle_api_error(rcode, rbody) begin error_obj = Util.symbolize_names(Eligible::JSON.load(rbody)) fail EligibleError unless error_obj.keys.any? { |k| [:error, :errors].include? k } error = error_obj[:error] errors = error_obj[:errors] rescue MultiJson::DecodeError, EligibleError raise APIError.new("Invalid response object from API: #{rbody.inspect} (HTTP response code was #{rcode})", rcode, rbody) end error_msg = error_message(error, errors) case rcode when 400, 404 then raise invalid_request_error(error_msg, rcode, rbody, error_obj) when 401 raise authentication_error(error_msg, rcode, rbody, error_obj) else raise api_error(error_msg, rcode, rbody, error_obj) end end
Source
# File lib/eligible.rb, line 303 def self.handle_restclient_error(e) case e when RestClient::ServerBrokeConnection, RestClient::RequestTimeout message = "Could not connect to Eligible (#{@@api_base}). Please check your internet connection and try again." when RestClient::SSLCertificateNotVerified message = "Could not verify Eligible's SSL certificate." when SocketError message = 'Unexpected error communicating when trying to connect to Eligible.' else message = 'Unexpected error communicating with Eligible. If this problem persists, let us know at support@eligible.com.' end fail APIConnectionError, "#{message}\n\n(Network error: #{e.message})" end
Source
# File lib/eligible.rb, line 291 def self.invalid_request_error(error_msg, rcode, rbody, error_obj) InvalidRequestError.new(error_msg, rcode, rbody, error_obj) end
Source
# File lib/eligible.rb, line 118 def self.request(method, url, api_key, params = {}, headers = {}) session_token = Util.value(params, :session_token) api_key ||= @@api_key unless session_token test = self.test api_key = Util.value(params, :api_key) if api_key?(params) test = Util.value(params, :test) if test_key?(params) fail AuthenticationError, 'No API key provided. (HINT: set your API key using "Eligible.api_key = <API-KEY>".' unless api_key || session_token lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})" debug_info = { bindings_version: Eligible::VERSION, lang: 'ruby', lang_version: lang_version, platform: RUBY_PLATFORM, publisher: 'eligible', uname: uname } # GET requests, parameters on the query string # POST requests, parameters as json in the body url = api_url(url) case method.to_s.downcase.to_sym when :get, :head, :delete url += "?api_key=#{api_key}" if params && params.count > 0 query_string = Util.flatten_params(params).collect { |key, value| "#{key}=#{Util.url_encode(value)}" }.join('&') url += "&#{query_string}" end url += "&test=#{test}" payload = nil else params.merge!('api_key' => api_key, 'test' => test) payload = Util.key?(params, :file) ? params : Eligible::JSON.dump(params) end begin headers = { x_eligible_debuginfo: Eligible::JSON.dump(debug_info) }.merge(headers) rescue => e headers = { x_eligible_client_raw_user_agent: debug_info.inspect, error: "#{e} (#{e.class})" }.merge(headers) end headers = { user_agent: "eligible-ruby/#{Eligible::VERSION}", authorization: "Bearer #{api_key}", content_type: 'application/json' }.merge(headers) headers[:eligible_version] = api_version if api_version opts = { method: method, url: url, headers: headers, open_timeout: 30, payload: payload, timeout: 80, ssl_verify_callback: verify_certificate, ssl_verify_callback_warnings: false } begin response = execute_request(opts) rescue SocketError => e handle_restclient_error(e) rescue NoMethodError => e # Work around RestClient bug raise unless e.message =~ /\WRequestFailed\W/ e = APIConnectionError.new('Unexpected HTTP response code') handle_restclient_error(e) rescue RestClient::ExceptionWithResponse => e err_rcode = e.http_code err_rbody = e.http_body if err_rcode && err_rbody handle_api_error(err_rcode, err_rbody) else handle_restclient_error(e) end rescue RestClient::Exception, Errno::ECONNREFUSED => e handle_restclient_error(e) end rbody = response.body rcode = response.code begin # Would use :symbolize_names => true, but apparently there is # some library out there that makes symbolize_names not work. resp = direct_response?(params) ? rbody : Eligible::JSON.load(rbody) rescue MultiJson::DecodeError raise APIError.new("Invalid response object from API: #{rbody.inspect} (HTTP response code was #{rcode})", rcode, rbody) end resp = Util.symbolize_names(resp) return [ resp, api_key ] end
Source
# File lib/eligible.rb, line 110 def self.test_key?(params) Util.key?(params, :test) end
Source
# File lib/eligible.rb, line 240 def self.uname @@uname ||= RUBY_PLATFORM =~ /linux|darwin/i ? `uname -a 2>/dev/null`.strip : nil end
Source
# File lib/eligible.rb, line 234 def self.valid_fingerprint?(received) fingerprints.include?(OpenSSL::Digest::SHA1.hexdigest(received.to_der)) end
Source
# File lib/eligible.rb, line 224 def self.verify_certificate lambda do |preverify_ok, certificate_store| return true if test == 'true' return false unless preverify_ok received = certificate_store.chain.first return true unless received.to_der == certificate_store.current_cert.to_der valid_fingerprint?(received) end end