eligible 1.0 → 3.0.0.beta17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.circleci/config.yml +76 -0
- data/.codeclimate.yml +23 -0
- data/.gitignore +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +1158 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +170 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +66 -0
- data/LICENSE +1 -1
- data/README.md +700 -93
- data/Rakefile +12 -2
- data/eligible.gemspec +14 -16
- data/lib/eligible/api_resource.rb +49 -5
- data/lib/eligible/calculator_deploy_url.rb +7 -0
- data/lib/eligible/claim.rb +22 -6
- data/lib/eligible/coverage.rb +19 -0
- data/lib/eligible/coverage_resource.rb +23 -0
- data/lib/eligible/customer.rb +19 -0
- data/lib/eligible/demographic.rb +6 -35
- data/lib/eligible/eligible_object.rb +12 -15
- data/lib/eligible/encryptor.rb +121 -0
- data/lib/eligible/enrollment.rb +23 -0
- data/lib/eligible/errors/eligible_error.rb +6 -3
- data/lib/eligible/errors/invalid_request_error.rb +4 -0
- data/lib/eligible/icd.rb +16 -0
- data/lib/eligible/json.rb +5 -15
- data/lib/eligible/lockbox.rb +39 -0
- data/lib/eligible/medicare.rb +11 -0
- data/lib/eligible/oauth_token.rb +9 -0
- data/lib/eligible/ocr.rb +15 -0
- data/lib/eligible/original_signature_pdf.rb +45 -0
- data/lib/eligible/payer.rb +17 -0
- data/lib/eligible/payer_mapping.rb +37 -0
- data/lib/eligible/payment.rb +11 -0
- data/lib/eligible/preauth_resource.rb +11 -0
- data/lib/eligible/precert.rb +15 -0
- data/lib/eligible/provider_model.rb +7 -0
- data/lib/eligible/public_key.rb +27 -0
- data/lib/eligible/received_pdf.rb +26 -0
- data/lib/eligible/referral.rb +11 -0
- data/lib/eligible/risk_assessment.rb +15 -0
- data/lib/eligible/session_token.rb +11 -0
- data/lib/eligible/ticket.rb +40 -0
- data/lib/eligible/util.rb +29 -38
- data/lib/eligible/v1_0/action.rb +9 -0
- data/lib/eligible/v1_0/attribute.rb +9 -0
- data/lib/eligible/v1_0/charge.rb +13 -0
- data/lib/eligible/v1_0/claim.rb +25 -0
- data/lib/eligible/v1_0/claim_service_line.rb +9 -0
- data/lib/eligible/v1_0/contract.rb +9 -0
- data/lib/eligible/v1_0/device.rb +9 -0
- data/lib/eligible/v1_0/discount.rb +9 -0
- data/lib/eligible/v1_0/enrollment.rb +17 -0
- data/lib/eligible/v1_0/estimate.rb +29 -0
- data/lib/eligible/v1_0/estimate_service_line.rb +17 -0
- data/lib/eligible/v1_0/fee.rb +21 -0
- data/lib/eligible/v1_0/fee_refund.rb +29 -0
- data/lib/eligible/v1_0/file.rb +17 -0
- data/lib/eligible/v1_0/file_link.rb +13 -0
- data/lib/eligible/v1_0/insurance_company.rb +21 -0
- data/lib/eligible/v1_0/insurance_company_alias.rb +9 -0
- data/lib/eligible/v1_0/insurance_policy.rb +9 -0
- data/lib/eligible/v1_0/patient_question.rb +9 -0
- data/lib/eligible/v1_0/patient_questionnaire.rb +9 -0
- data/lib/eligible/v1_0/patient_record.rb +9 -0
- data/lib/eligible/v1_0/patient_statement.rb +54 -0
- data/lib/eligible/v1_0/patient_statement_service_line.rb +13 -0
- data/lib/eligible/v1_0/payment_report.rb +21 -0
- data/lib/eligible/v1_0/product.rb +9 -0
- data/lib/eligible/v1_0/provider.rb +9 -0
- data/lib/eligible/v1_0/remark.rb +21 -0
- data/lib/eligible/v1_0/reports/accuracy_stats.rb +23 -0
- data/lib/eligible/v1_0/reports/estimate_friction.rb +23 -0
- data/lib/eligible/v1_0/reports/in_scope_distribution.rb +23 -0
- data/lib/eligible/v1_0/rest_api_base.rb +44 -0
- data/lib/eligible/v1_0/rule.rb +13 -0
- data/lib/eligible/v1_0/session.rb +21 -0
- data/lib/eligible/v1_0/transaction.rb +21 -0
- data/lib/eligible/v1_0/treatment.rb +9 -0
- data/lib/eligible/v1_0/value_list.rb +9 -0
- data/lib/eligible/v1_0/value_list_item.rb +9 -0
- data/lib/eligible/v1_0/verification.rb +17 -0
- data/lib/eligible/version.rb +1 -1
- data/lib/eligible/visit_type.rb +11 -0
- data/lib/eligible/x12.rb +8 -0
- data/lib/eligible.rb +320 -110
- metadata +148 -67
- data/CONTRIBUTORS +0 -1
- data/lib/eligible/plan.rb +0 -42
- data/lib/eligible/service.rb +0 -39
- data/test/test_eligible.rb +0 -279
- data/test/test_helper.rb +0 -67
data/lib/eligible.rb
CHANGED
@@ -2,34 +2,123 @@ require 'cgi'
|
|
2
2
|
require 'set'
|
3
3
|
require 'rubygems'
|
4
4
|
require 'openssl'
|
5
|
+
require 'net/https'
|
5
6
|
|
6
|
-
gem 'rest-client', '~> 1.4'
|
7
7
|
require 'rest_client'
|
8
8
|
require 'multi_json'
|
9
9
|
|
10
10
|
require 'eligible/version'
|
11
|
+
require 'eligible/encryptor'
|
11
12
|
require 'eligible/util'
|
12
13
|
require 'eligible/json'
|
13
14
|
require 'eligible/eligible_object'
|
14
15
|
require 'eligible/api_resource'
|
15
|
-
require 'eligible/
|
16
|
-
require 'eligible/service'
|
16
|
+
require 'eligible/coverage_resource'
|
17
17
|
require 'eligible/demographic'
|
18
18
|
require 'eligible/claim'
|
19
|
+
require 'eligible/enrollment'
|
20
|
+
require 'eligible/coverage'
|
21
|
+
require 'eligible/payment'
|
22
|
+
require 'eligible/x12'
|
23
|
+
require 'eligible/medicare'
|
24
|
+
require 'eligible/ticket'
|
25
|
+
require 'eligible/customer'
|
26
|
+
require 'eligible/ocr'
|
27
|
+
require 'eligible/original_signature_pdf'
|
28
|
+
require 'eligible/oauth_token'
|
29
|
+
require 'eligible/received_pdf'
|
30
|
+
require 'eligible/payer'
|
31
|
+
require 'eligible/payer_mapping'
|
32
|
+
require 'eligible/preauth_resource'
|
33
|
+
require 'eligible/precert'
|
34
|
+
require 'eligible/referral'
|
35
|
+
require 'eligible/public_key'
|
36
|
+
require 'eligible/lockbox'
|
37
|
+
require 'eligible/session_token'
|
38
|
+
require 'eligible/visit_type'
|
39
|
+
require 'eligible/provider_model'
|
40
|
+
require 'eligible/calculator_deploy_url'
|
41
|
+
require 'eligible/risk_assessment'
|
42
|
+
require 'eligible/icd'
|
43
|
+
|
44
|
+
# New REST API Endpoints
|
45
|
+
require 'eligible/v1_0/rest_api_base'
|
46
|
+
require 'eligible/v1_0/action'
|
47
|
+
require 'eligible/v1_0/attribute'
|
48
|
+
require 'eligible/v1_0/charge'
|
49
|
+
require 'eligible/v1_0/claim'
|
50
|
+
require 'eligible/v1_0/claim_service_line'
|
51
|
+
require 'eligible/v1_0/contract'
|
52
|
+
require 'eligible/v1_0/device'
|
53
|
+
require 'eligible/v1_0/discount'
|
54
|
+
require 'eligible/v1_0/enrollment'
|
55
|
+
require 'eligible/v1_0/estimate'
|
56
|
+
require 'eligible/v1_0/estimate_service_line'
|
57
|
+
require 'eligible/v1_0/fee'
|
58
|
+
require 'eligible/v1_0/fee_refund'
|
59
|
+
require 'eligible/v1_0/file'
|
60
|
+
require 'eligible/v1_0/file_link'
|
61
|
+
require 'eligible/v1_0/insurance_company'
|
62
|
+
require 'eligible/v1_0/insurance_company_alias'
|
63
|
+
require 'eligible/v1_0/insurance_policy'
|
64
|
+
require 'eligible/v1_0/patient_record'
|
65
|
+
require 'eligible/v1_0/patient_statement'
|
66
|
+
require 'eligible/v1_0/patient_statement_service_line'
|
67
|
+
require 'eligible/v1_0/payment_report'
|
68
|
+
require 'eligible/v1_0/patient_question'
|
69
|
+
require 'eligible/v1_0/patient_questionnaire'
|
70
|
+
require 'eligible/v1_0/product'
|
71
|
+
require 'eligible/v1_0/provider'
|
72
|
+
require 'eligible/v1_0/remark'
|
73
|
+
require 'eligible/v1_0/rule'
|
74
|
+
require 'eligible/v1_0/session'
|
75
|
+
require 'eligible/v1_0/transaction'
|
76
|
+
require 'eligible/v1_0/treatment'
|
77
|
+
require 'eligible/v1_0/value_list'
|
78
|
+
require 'eligible/v1_0/value_list_item'
|
79
|
+
require 'eligible/v1_0/verification'
|
80
|
+
require 'eligible/v1_0/reports/accuracy_stats'
|
81
|
+
require 'eligible/v1_0/reports/estimate_friction'
|
82
|
+
require 'eligible/v1_0/reports/in_scope_distribution'
|
19
83
|
|
20
84
|
# Errors
|
21
85
|
require 'eligible/errors/eligible_error'
|
22
86
|
require 'eligible/errors/api_connection_error'
|
23
87
|
require 'eligible/errors/authentication_error'
|
24
88
|
require 'eligible/errors/api_error'
|
89
|
+
require 'eligible/errors/invalid_request_error'
|
25
90
|
|
26
91
|
module Eligible
|
27
|
-
@@api_key
|
28
|
-
@@
|
29
|
-
@@api_version = 1
|
92
|
+
@@api_key = nil
|
93
|
+
@@test = false
|
94
|
+
@@api_version = '1.5'
|
95
|
+
@@api_base = "https://gds.eligibleapi.com/v#{@@api_version}"
|
96
|
+
@@fingerprints = %w(a1cd762a9f4be0f3b6bdd6300e52c6ce8d7d67f5
|
97
|
+
36d6b6f98a2b9bcdf4321d1978553e23cf044b53
|
98
|
+
d93b7697100fe978ae0f78fbf2a2443cc1958ca3
|
99
|
+
896ce24f7a83eb656c040985fdb50ce39f90b813)
|
100
|
+
@@eligible_account = nil
|
101
|
+
@@eligible_account_id = nil
|
102
|
+
|
103
|
+
def self.api_url(url = '', rest_api_version = nil)
|
104
|
+
api_base = rest_api_version ? @@api_base.gsub(/v(\d).(\d)/, "v#{rest_api_version}") : @@api_base
|
105
|
+
api_base + url.to_s
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.eligible_account
|
109
|
+
@@eligible_account
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.eligible_account_id
|
113
|
+
@@eligible_account_id
|
114
|
+
end
|
30
115
|
|
31
|
-
def self.
|
32
|
-
@@
|
116
|
+
def self.eligible_account=(eligible_account)
|
117
|
+
@@eligible_account = eligible_account
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.eligible_account_id=(eligible_account_id)
|
121
|
+
@@eligible_account_id = eligible_account_id
|
33
122
|
end
|
34
123
|
|
35
124
|
def self.api_key
|
@@ -40,161 +129,284 @@ module Eligible
|
|
40
129
|
@@api_key = api_key
|
41
130
|
end
|
42
131
|
|
132
|
+
def self.api_base
|
133
|
+
@@api_base
|
134
|
+
end
|
135
|
+
|
136
|
+
def self.api_base=(api_base)
|
137
|
+
@@api_base = api_base
|
138
|
+
end
|
139
|
+
|
140
|
+
def self.test
|
141
|
+
@@test ? 'true' : 'false'
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.test=(is_test)
|
145
|
+
@@test = is_test
|
146
|
+
end
|
147
|
+
|
43
148
|
def self.api_version=(version)
|
44
149
|
@@api_version = version
|
45
150
|
end
|
46
151
|
|
47
152
|
def self.api_version
|
48
153
|
@@api_version
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.request(method, url, api_key, params={}, headers={})
|
52
|
-
api_key ||= @@api_key
|
53
|
-
raise AuthenticationError.new('No API key provided. (HINT: set your API key using "Eligible.api_key = <API-KEY>".') unless api_key
|
54
|
-
|
55
|
-
# if !verify_ssl_certs
|
56
|
-
# unless @no_verify
|
57
|
-
# $stderr.puts "WARNING: Running without SSL cert verification. Execute 'Eligible.verify_ssl_certs = true' to enable verification."
|
58
|
-
# @no_verify = true
|
59
|
-
# end
|
60
|
-
# ssl_opts = { :verify_ssl => false }
|
61
|
-
# elsif !Util.file_readable(@@ssl_bundle_path)
|
62
|
-
# unless @no_bundle
|
63
|
-
# $stderr.puts "WARNING: Running without SSL cert verification because #{@@ssl_bundle_path} isn't readable"
|
64
|
-
# @no_bundle = true
|
65
|
-
# end
|
66
|
-
# ssl_opts = { :verify_ssl => false }
|
67
|
-
# else
|
68
|
-
# ssl_opts = {
|
69
|
-
# :verify_ssl => OpenSSL::SSL::VERIFY_PEER,
|
70
|
-
# :ssl_ca_file => @@ssl_bundle_path
|
71
|
-
# }
|
72
|
-
# end
|
73
|
-
uname = (@@uname ||= RUBY_PLATFORM =~ /linux|darwin/i ? `uname -a 2>/dev/null`.strip : nil)
|
74
|
-
lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
|
75
|
-
ua = {
|
76
|
-
:bindings_version => Eligible::VERSION,
|
77
|
-
:lang => 'ruby',
|
78
|
-
:lang_version => lang_version,
|
79
|
-
:platform => RUBY_PLATFORM,
|
80
|
-
:publisher => 'eligible',
|
81
|
-
:uname => uname
|
82
|
-
}
|
154
|
+
end
|
83
155
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
when :get, :head, :delete
|
88
|
-
# Make params into GET parameters
|
89
|
-
url += "?api_key=#{api_key}"
|
90
|
-
if params && params.count > 0
|
91
|
-
query_string = Util.flatten_params(params).collect{|key, value| "#{key}=#{Util.url_encode(value)}"}.join('&')
|
92
|
-
url += "&#{query_string}"
|
93
|
-
end
|
94
|
-
payload = nil
|
95
|
-
else
|
96
|
-
payload = Util.flatten_params(params).collect{|(key, value)| "#{key}=#{Util.url_encode(value)}"}.join('&')
|
97
|
-
end
|
156
|
+
def self.fingerprints
|
157
|
+
@@fingerprints
|
158
|
+
end
|
98
159
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
:x_eligible_client_raw_user_agent => ua.inspect,
|
104
|
-
:error => "#{e} (#{e.class})"
|
105
|
-
}.merge(headers)
|
106
|
-
end
|
160
|
+
def self.add_fingerprint(digest)
|
161
|
+
$stderr.puts 'The embedded certificate fingerprint was modified. This should only be done if instructed to by eligible support staff'
|
162
|
+
@@fingerprints << digest
|
163
|
+
end
|
107
164
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
:content_type => 'application/x-www-form-urlencoded'
|
112
|
-
}.merge(headers)
|
165
|
+
def self.direct_response?(params)
|
166
|
+
params[:format].is_a?(String) && params[:format].downcase == 'x12'
|
167
|
+
end
|
113
168
|
|
114
|
-
|
115
|
-
|
116
|
-
|
169
|
+
def self.test_key?(params)
|
170
|
+
Util.key?(params, :test)
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.api_key?(params)
|
174
|
+
Util.key?(params, :api_key)
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.rest_api_version?(params)
|
178
|
+
Util.key?(params, :rest_api_version)
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.request(method, url, api_key, params = {}, headers = {})
|
182
|
+
session_token = Util.value(params, :session_token)
|
183
|
+
api_key ||= @@api_key unless session_token
|
184
|
+
test = self.test
|
185
|
+
api_key = Util.value(params, :api_key) if api_key?(params)
|
186
|
+
test = Util.value(params, :test) if test_key?(params)
|
187
|
+
rest_api_version = Util.value(params, :rest_api_version) if rest_api_version?(params)
|
188
|
+
basic_auth = true if rest_api_version?(params)
|
189
|
+
|
190
|
+
fail AuthenticationError, 'No API key provided. (HINT: set your API key using "Eligible.api_key = <API-KEY>".' unless api_key || session_token
|
191
|
+
|
192
|
+
lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
|
193
|
+
debug_info = {
|
194
|
+
bindings_version: Eligible::VERSION,
|
195
|
+
lang: 'ruby',
|
196
|
+
lang_version: lang_version,
|
197
|
+
platform: RUBY_PLATFORM,
|
198
|
+
publisher: 'eligible',
|
199
|
+
uname: uname
|
200
|
+
}
|
201
|
+
|
202
|
+
# Set request URL and Payload based on new and old endpoints version
|
203
|
+
url, payload = generate_request_url_and_payload(
|
204
|
+
method, url, params, { test: test, rest_api_version: rest_api_version, api_key: api_key, basic_auth: basic_auth },
|
205
|
+
)
|
206
|
+
|
207
|
+
# Set request Headers and Authorization based on new and old endpoints version
|
208
|
+
headers = generate_request_headers(headers, debug_info, basic_auth, { api_key: api_key, session_token: session_token })
|
117
209
|
|
118
210
|
opts = {
|
119
|
-
:
|
120
|
-
:
|
121
|
-
:
|
122
|
-
:
|
123
|
-
:
|
124
|
-
:
|
125
|
-
|
126
|
-
|
211
|
+
method: method,
|
212
|
+
url: url,
|
213
|
+
headers: headers,
|
214
|
+
open_timeout: 30,
|
215
|
+
payload: payload,
|
216
|
+
timeout: 80,
|
217
|
+
ssl_verify_callback: verify_certificate,
|
218
|
+
ssl_verify_callback_warnings: false
|
219
|
+
}
|
220
|
+
|
127
221
|
begin
|
128
222
|
response = execute_request(opts)
|
223
|
+
|
129
224
|
rescue SocketError => e
|
130
|
-
|
225
|
+
handle_restclient_error(e)
|
226
|
+
|
131
227
|
rescue NoMethodError => e
|
132
228
|
# Work around RestClient bug
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
end
|
229
|
+
raise unless e.message =~ /\WRequestFailed\W/
|
230
|
+
|
231
|
+
e = APIConnectionError.new('Unexpected HTTP response code')
|
232
|
+
handle_restclient_error(e)
|
233
|
+
|
139
234
|
rescue RestClient::ExceptionWithResponse => e
|
140
|
-
|
141
|
-
|
235
|
+
err_rcode = e.http_code
|
236
|
+
err_rbody = e.http_body
|
237
|
+
|
238
|
+
if err_rcode && err_rbody
|
239
|
+
handle_api_error(err_rcode, err_rbody)
|
142
240
|
else
|
143
|
-
|
241
|
+
handle_restclient_error(e)
|
144
242
|
end
|
243
|
+
|
145
244
|
rescue RestClient::Exception, Errno::ECONNREFUSED => e
|
146
|
-
|
245
|
+
handle_restclient_error(e)
|
147
246
|
end
|
148
247
|
|
149
248
|
rbody = response.body
|
150
249
|
rcode = response.code
|
250
|
+
|
151
251
|
begin
|
152
252
|
# Would use :symbolize_names => true, but apparently there is
|
153
253
|
# some library out there that makes symbolize_names not work.
|
154
|
-
resp = Eligible::JSON.load(rbody)
|
254
|
+
resp = direct_response?(params) ? rbody : Eligible::JSON.load(rbody)
|
155
255
|
rescue MultiJson::DecodeError
|
156
256
|
raise APIError.new("Invalid response object from API: #{rbody.inspect} (HTTP response code was #{rcode})", rcode, rbody)
|
157
257
|
end
|
158
258
|
|
159
259
|
resp = Util.symbolize_names(resp)
|
160
|
-
[resp, api_key]
|
260
|
+
return [ resp, api_key ]
|
261
|
+
end
|
262
|
+
|
263
|
+
def self.generate_request_url_and_payload(method, url, params, options)
|
264
|
+
# GET requests, parameters on the query string
|
265
|
+
# POST requests, parameters as json in the body
|
266
|
+
url = api_url(url, options[:rest_api_version])
|
267
|
+
# Used rest_api_version param only to identify new REST API version, and is not required to make calls for new REST api endpoints
|
268
|
+
params.delete(:rest_api_version)
|
269
|
+
case method.to_s.downcase.to_sym
|
270
|
+
when :get, :head, :delete
|
271
|
+
url = fetch_url_with_query_string(params, url, options)
|
272
|
+
payload = nil
|
273
|
+
else
|
274
|
+
payload = request_payload(options, params)
|
275
|
+
end
|
276
|
+
|
277
|
+
[url, payload]
|
278
|
+
end
|
279
|
+
|
280
|
+
def self.fetch_url_with_query_string(params, url, options)
|
281
|
+
url += options_query_string(options)
|
282
|
+
return url unless params || params.count == 0
|
283
|
+
|
284
|
+
query_string = params_query_string(params)
|
285
|
+
url += options[:basic_auth] ? "?#{query_string}" : "&#{query_string}"
|
286
|
+
url
|
287
|
+
end
|
288
|
+
|
289
|
+
def self.options_query_string(options)
|
290
|
+
options[:basic_auth] ? '' : "?test=#{options[:test]}&api_key=#{options[:api_key]}"
|
291
|
+
end
|
292
|
+
|
293
|
+
def self.params_query_string(params)
|
294
|
+
Util.flatten_params(params).collect { |key, value| "#{key}=#{Util.url_encode(value)}" }.join('&')
|
295
|
+
end
|
296
|
+
|
297
|
+
def self.request_payload(options, params)
|
298
|
+
params.merge!('test' => options[:test], 'api_key' => options[:api_key]) unless options[:basic_auth]
|
299
|
+
Util.key?(params, :file) ? params : Eligible::JSON.dump(params)
|
300
|
+
end
|
301
|
+
|
302
|
+
def self.generate_request_headers(headers, debug_info, basic_auth, auth_options)
|
303
|
+
begin
|
304
|
+
headers = { x_eligible_debuginfo: Eligible::JSON.dump(debug_info) }.merge(headers)
|
305
|
+
rescue => e
|
306
|
+
headers = {
|
307
|
+
x_eligible_client_raw_user_agent: debug_info.inspect,
|
308
|
+
error: "#{e} (#{e.class})"
|
309
|
+
}.merge(headers)
|
310
|
+
end
|
311
|
+
|
312
|
+
headers = {
|
313
|
+
user_agent: "eligible-ruby/#{Eligible::VERSION}",
|
314
|
+
content_type: 'application/json'
|
315
|
+
}.merge(headers)
|
316
|
+
|
317
|
+
headers[:authorization] = authorization_header(basic_auth, auth_options)
|
318
|
+
headers[:eligible_version] = api_version if api_version
|
319
|
+
headers[:eligible_account] = eligible_account if eligible_account
|
320
|
+
headers[:eligible_account_id] = eligible_account_id if eligible_account_id
|
321
|
+
headers
|
322
|
+
end
|
323
|
+
|
324
|
+
def self.authorization_header(basic_auth, auth_options)
|
325
|
+
# Using Bearer scheme for Session Token Auth for new REST API endpoints (v1.0)
|
326
|
+
return "Bearer #{auth_options[:session_token]}" if basic_auth && auth_options[:session_token]
|
327
|
+
|
328
|
+
# Using Basic Auth for new REST API endpoints (v1.0)
|
329
|
+
basic_auth_token = Base64.strict_encode64("#{auth_options[:api_key]}:")
|
330
|
+
"Basic #{basic_auth_token}" if basic_auth
|
331
|
+
end
|
332
|
+
|
333
|
+
def self.verify_certificate
|
334
|
+
lambda do |preverify_ok, certificate_store|
|
335
|
+
return true if test == 'true'
|
336
|
+
return false unless preverify_ok
|
337
|
+
received = certificate_store.chain.first
|
338
|
+
return true unless received.to_der == certificate_store.current_cert.to_der
|
339
|
+
valid_fingerprint?(received)
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
def self.valid_fingerprint?(received)
|
344
|
+
fingerprints.include?(OpenSSL::Digest::SHA1.hexdigest(received.to_der))
|
161
345
|
end
|
162
346
|
|
163
347
|
private
|
164
348
|
|
349
|
+
def self.uname
|
350
|
+
@@uname ||= RUBY_PLATFORM =~ /linux|darwin/i ? `uname -a 2>/dev/null`.strip : nil
|
351
|
+
end
|
352
|
+
|
165
353
|
def self.execute_request(opts)
|
166
354
|
RestClient::Request.execute(opts)
|
167
355
|
end
|
168
356
|
|
357
|
+
def self.error_message(error, errors)
|
358
|
+
message = compose_message_from_errors(errors)
|
359
|
+
return message if message
|
360
|
+
|
361
|
+
return compose_message_from_error(error)
|
362
|
+
end
|
363
|
+
|
364
|
+
def self.compose_message_from_errors(errors)
|
365
|
+
return unless errors.is_a?(Array)
|
366
|
+
|
367
|
+
return errors.first[:message] if errors.size == 1
|
368
|
+
return errors.each_with_index.map { |error, index| "#{index + 1}. #{error[:message]}" }.join("\n")
|
369
|
+
end
|
370
|
+
|
371
|
+
def self.compose_message_from_error(error)
|
372
|
+
return error.to_s unless error.is_a?(Hash)
|
373
|
+
result = error[:details] || error[:reject_reason_description] || error
|
374
|
+
return result.to_s
|
375
|
+
end
|
376
|
+
|
169
377
|
def self.handle_api_error(rcode, rbody)
|
170
378
|
begin
|
171
|
-
error_obj = Eligible::JSON.load(rbody)
|
172
|
-
error_obj
|
173
|
-
error = error_obj[:error]
|
379
|
+
error_obj = Util.symbolize_names(Eligible::JSON.load(rbody))
|
380
|
+
fail EligibleError unless error_obj.keys.any? { |k| [:error, :errors].include? k }
|
381
|
+
error = error_obj[:error]
|
382
|
+
errors = error_obj[:errors]
|
383
|
+
|
174
384
|
rescue MultiJson::DecodeError, EligibleError
|
175
385
|
raise APIError.new("Invalid response object from API: #{rbody.inspect} (HTTP response code was #{rcode})", rcode, rbody)
|
176
386
|
end
|
177
387
|
|
388
|
+
error_msg = error_message(error, errors)
|
389
|
+
|
178
390
|
case rcode
|
179
391
|
when 400, 404 then
|
180
|
-
raise invalid_request_error(
|
392
|
+
raise invalid_request_error(error_msg, rcode, rbody, error_obj)
|
181
393
|
when 401
|
182
|
-
raise authentication_error(
|
394
|
+
raise authentication_error(error_msg, rcode, rbody, error_obj)
|
183
395
|
else
|
184
|
-
raise api_error(
|
396
|
+
raise api_error(error_msg, rcode, rbody, error_obj)
|
185
397
|
end
|
186
398
|
end
|
187
399
|
|
188
|
-
def self.invalid_request_error(
|
189
|
-
InvalidRequestError.new(
|
400
|
+
def self.invalid_request_error(error_msg, rcode, rbody, error_obj)
|
401
|
+
InvalidRequestError.new(error_msg, rcode, rbody, error_obj)
|
190
402
|
end
|
191
403
|
|
192
|
-
def self.authentication_error(
|
193
|
-
AuthenticationError.new(
|
404
|
+
def self.authentication_error(error_msg, rcode, rbody, error_obj)
|
405
|
+
AuthenticationError.new(error_msg, rcode, rbody, error_obj)
|
194
406
|
end
|
195
407
|
|
196
|
-
def self.api_error(
|
197
|
-
APIError.new(
|
408
|
+
def self.api_error(error_msg, rcode, rbody, error_obj)
|
409
|
+
APIError.new(error_msg, rcode, rbody, error_obj)
|
198
410
|
end
|
199
411
|
|
200
412
|
def self.handle_restclient_error(e)
|
@@ -204,12 +416,10 @@ module Eligible
|
|
204
416
|
when RestClient::SSLCertificateNotVerified
|
205
417
|
message = "Could not verify Eligible's SSL certificate."
|
206
418
|
when SocketError
|
207
|
-
message =
|
419
|
+
message = 'Unexpected error communicating when trying to connect to Eligible.'
|
208
420
|
else
|
209
|
-
message =
|
421
|
+
message = 'Unexpected error communicating with Eligible. If this problem persists, let us know at support@eligible.com.'
|
210
422
|
end
|
211
|
-
|
212
|
-
raise APIConnectionError.new(message)
|
423
|
+
fail APIConnectionError, "#{message}\n\n(Network error: #{e.message})"
|
213
424
|
end
|
214
|
-
|
215
425
|
end
|