onfido 1.1.1 → 2.0.0
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 +4 -4
- data/.rubocop.yml +5 -49
- data/.travis.yml +2 -8
- data/CHANGELOG.md +7 -0
- data/Gemfile +2 -0
- data/README.md +37 -148
- data/lib/onfido.rb +3 -2
- data/lib/onfido/api.rb +18 -12
- data/lib/onfido/errors/connection_error.rb +2 -0
- data/lib/onfido/errors/onfido_error.rb +2 -0
- data/lib/onfido/errors/request_error.rb +2 -0
- data/lib/onfido/errors/server_error.rb +2 -0
- data/lib/onfido/options.rb +38 -0
- data/lib/onfido/resource.rb +45 -59
- data/lib/onfido/resources/address.rb +2 -0
- data/lib/onfido/resources/applicant.rb +2 -0
- data/lib/onfido/resources/check.rb +6 -0
- data/lib/onfido/resources/document.rb +2 -0
- data/lib/onfido/resources/extraction.rb +2 -0
- data/lib/onfido/resources/live_photo.rb +2 -0
- data/lib/onfido/resources/live_video.rb +2 -0
- data/lib/onfido/resources/report.rb +2 -0
- data/lib/onfido/resources/sdk_token.rb +2 -0
- data/lib/onfido/resources/webhook.rb +4 -2
- data/lib/onfido/version.rb +3 -1
- data/onfido.gemspec +5 -6
- data/spec/integrations/address_spec.rb +4 -2
- data/spec/integrations/applicant_spec.rb +12 -7
- data/spec/integrations/check_spec.rb +17 -4
- data/spec/integrations/document_spec.rb +7 -3
- data/spec/integrations/extraction_spec.rb +6 -2
- data/spec/integrations/live_photo_spec.rb +7 -3
- data/spec/integrations/live_video_spec.rb +6 -1
- data/spec/integrations/report_spec.rb +6 -1
- data/spec/integrations/resource_spec.rb +93 -0
- data/spec/integrations/sdk_token_spec.rb +5 -1
- data/spec/integrations/webhook_spec.rb +28 -24
- data/spec/onfido/api_spec.rb +14 -25
- data/spec/onfido/connection_error_spec.rb +4 -2
- data/spec/onfido/options_spec.rb +39 -0
- data/spec/onfido/request_error_spec.rb +4 -2
- data/spec/spec_helper.rb +3 -5
- data/spec/support/fake_onfido_api.rb +63 -49
- data/spec/support/fixtures/applicant.json +1 -1
- data/spec/support/fixtures/check.json +1 -1
- data/spec/support/fixtures/checks.json +1 -1
- data/spec/support/fixtures/document.json +1 -1
- data/spec/support/fixtures/documents.json +2 -2
- data/spec/support/fixtures/live_photo.json +2 -2
- data/spec/support/fixtures/live_photos.json +4 -4
- data/spec/support/fixtures/live_video.json +2 -2
- data/spec/support/fixtures/live_videos.json +2 -2
- data/spec/support/fixtures/report.json +1 -1
- data/spec/support/fixtures/reports.json +2 -2
- data/spec/support/fixtures/webhook.json +1 -1
- data/spec/support/fixtures/webhooks.json +2 -2
- metadata +11 -29
- data/Rakefile +0 -1
- data/lib/onfido/configuration.rb +0 -47
- data/lib/onfido/null_logger.rb +0 -5
- data/spec/integrations/exceptions_spec.rb +0 -72
- data/spec/onfido/resource_spec.rb +0 -133
- data/spec/onfido_spec.rb +0 -83
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Onfido
|
4
|
+
class Options
|
5
|
+
REGIONS = %w[eu us ca].freeze
|
6
|
+
|
7
|
+
def initialize(api_key:, region:, open_timeout: 10, read_timeout: 30, unknown_api_url: nil)
|
8
|
+
@api_key = api_key
|
9
|
+
@region = region.to_s.downcase
|
10
|
+
@open_timeout = open_timeout
|
11
|
+
@read_timeout = read_timeout
|
12
|
+
@unknown_api_url = unknown_api_url
|
13
|
+
|
14
|
+
raise "Unknown region #{@region}" unless REGIONS.include?(@region)
|
15
|
+
end
|
16
|
+
|
17
|
+
def rest_client
|
18
|
+
@rest_client ||= RestClient::Resource.new(
|
19
|
+
base_url,
|
20
|
+
read_timeout: read_timeout,
|
21
|
+
open_timeout: open_timeout,
|
22
|
+
headers: {
|
23
|
+
'Authorization' => "Token token=#{api_key}",
|
24
|
+
'Accept' => 'application/json',
|
25
|
+
'User-Agent' => "onfido-ruby/#{Onfido::VERSION}"
|
26
|
+
}
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :api_key, :open_timeout, :read_timeout
|
33
|
+
|
34
|
+
def base_url
|
35
|
+
@unknown_api_url || "https://api.#{@region}.onfido.com/v3.1/"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/onfido/resource.rb
CHANGED
@@ -1,55 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Onfido
|
2
|
-
class Resource
|
3
|
-
VALID_HTTP_METHODS = %i
|
4
|
+
class Resource # rubocop:todo Metrics/ClassLength
|
5
|
+
VALID_HTTP_METHODS = %i[get post put delete].freeze
|
4
6
|
REQUEST_TIMEOUT_HTTP_CODE = 408
|
5
7
|
|
6
|
-
def initialize(
|
7
|
-
@
|
8
|
+
def initialize(options)
|
9
|
+
@rest_client = options.rest_client
|
8
10
|
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
)
|
17
|
-
end
|
12
|
+
private
|
13
|
+
|
14
|
+
attr_reader :rest_client
|
15
|
+
|
16
|
+
def get(path:)
|
17
|
+
handle_request { rest_client[path].get }
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
def post(path:, payload: nil)
|
21
|
+
handle_request { rest_client[path].post(payload) }
|
22
|
+
end
|
21
23
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
method = options.fetch(:method)
|
24
|
+
def put(path:, payload: nil)
|
25
|
+
handle_request { rest_client[path].put(payload) }
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
method: method,
|
31
|
-
headers: headers,
|
32
|
-
open_timeout: Onfido.open_timeout,
|
33
|
-
timeout: Onfido.read_timeout
|
34
|
-
}
|
28
|
+
def delete(path:)
|
29
|
+
handle_request { rest_client[path].delete }
|
30
|
+
end
|
35
31
|
|
36
|
-
|
32
|
+
def handle_request
|
33
|
+
response = yield
|
37
34
|
|
38
35
|
# response should be parsed only when there is a response expected
|
39
36
|
parse(response) unless response.code == 204 # no_content
|
40
|
-
rescue RestClient::ExceptionWithResponse =>
|
41
|
-
if
|
42
|
-
handle_api_error(
|
37
|
+
rescue RestClient::ExceptionWithResponse => e
|
38
|
+
if e.response && !timeout_response?(e.response)
|
39
|
+
handle_api_error(e.response)
|
43
40
|
else
|
44
|
-
handle_restclient_error(
|
41
|
+
handle_restclient_error(e)
|
45
42
|
end
|
46
|
-
rescue RestClient::Exception, Errno::ECONNREFUSED =>
|
47
|
-
handle_restclient_error(
|
43
|
+
rescue RestClient::Exception, Errno::ECONNREFUSED => e
|
44
|
+
handle_restclient_error(e)
|
48
45
|
end
|
49
46
|
|
50
47
|
def parse(response)
|
51
48
|
content_type = response.headers[:content_type]
|
52
|
-
if content_type
|
49
|
+
if content_type&.include?('application/json')
|
53
50
|
JSON.parse(response.body.to_s)
|
54
51
|
else
|
55
52
|
response.body
|
@@ -62,14 +59,6 @@ module Onfido
|
|
62
59
|
response.code.to_i == REQUEST_TIMEOUT_HTTP_CODE
|
63
60
|
end
|
64
61
|
|
65
|
-
def headers
|
66
|
-
{
|
67
|
-
'Authorization' => "Token token=#{@api_key}",
|
68
|
-
'Accept' => "application/json",
|
69
|
-
'User-Agent' => "onfido-ruby/#{Onfido::VERSION}"
|
70
|
-
}
|
71
|
-
end
|
72
|
-
|
73
62
|
# There seems to be a serialization issue with the HTTP client
|
74
63
|
# which does not serialize the payload properly.
|
75
64
|
# Have a look here https://gist.github.com/PericlesTheo/cb35139c57107ab3c84a
|
@@ -85,12 +74,12 @@ module Onfido
|
|
85
74
|
def handle_api_error(response)
|
86
75
|
parsed_response = parse(response)
|
87
76
|
|
88
|
-
general_api_error(response.code, response.body) unless parsed_response[
|
77
|
+
general_api_error(response.code, response.body) unless parsed_response['error']
|
89
78
|
|
90
79
|
error_class = response.code.to_i >= 500 ? ServerError : RequestError
|
91
80
|
|
92
81
|
raise error_class.new(
|
93
|
-
parsed_response[
|
82
|
+
parsed_response['error']['message'],
|
94
83
|
response_code: response.code,
|
95
84
|
response_body: response.body
|
96
85
|
)
|
@@ -107,46 +96,43 @@ module Onfido
|
|
107
96
|
)
|
108
97
|
end
|
109
98
|
|
110
|
-
def handle_restclient_error(error
|
99
|
+
def handle_restclient_error(error) # rubocop:todo Metrics/MethodLength
|
111
100
|
connection_message =
|
112
|
-
|
113
|
-
|
101
|
+
'Please check your internet connection and try again. ' \
|
102
|
+
'If this problem persists, you should let us know at info@onfido.com.'
|
114
103
|
|
115
104
|
message =
|
116
105
|
case error
|
117
106
|
when RestClient::RequestTimeout
|
118
|
-
"Could not connect to Onfido
|
107
|
+
"Could not connect to Onfido . #{connection_message}"
|
119
108
|
|
120
109
|
when RestClient::ServerBrokeConnection
|
121
|
-
"The connection to the server
|
122
|
-
"request completed. #{connection_message}"
|
110
|
+
"The connection to the server broke before the request completed. #{connection_message}"
|
123
111
|
|
124
112
|
when RestClient::SSLCertificateNotVerified
|
125
113
|
"Could not verify Onfido's SSL certificate. Please make sure " \
|
126
|
-
|
127
|
-
"(Try going to #{Onfido.endpoint} in your browser.) " \
|
128
|
-
"If this problem persists, let us know at info@onfido.com."
|
114
|
+
'that your network is not intercepting certificates. '
|
129
115
|
|
130
116
|
when SocketError
|
131
|
-
|
132
|
-
|
117
|
+
'Unexpected error when trying to connect to Onfido. ' \
|
118
|
+
'You may be seeing this message because your DNS is not working. ' \
|
133
119
|
"To check, try running 'host onfido.com' from the command line."
|
134
120
|
|
135
121
|
else
|
136
|
-
|
137
|
-
|
122
|
+
'Unexpected error communicating with Onfido. ' \
|
123
|
+
'If this problem persists, let us know at info@onfido.com.'
|
138
124
|
end
|
139
125
|
|
140
126
|
full_message = message + "\n\n(Network error: #{error.message})"
|
141
127
|
|
142
|
-
raise ConnectionError
|
128
|
+
raise ConnectionError, full_message
|
143
129
|
end
|
144
130
|
|
145
131
|
def validate_file!(file)
|
146
132
|
return if file.respond_to?(:read) && file.respond_to?(:path)
|
147
133
|
|
148
|
-
raise ArgumentError,
|
149
|
-
|
134
|
+
raise ArgumentError, 'File must be a `File`-like object which responds to ' \
|
135
|
+
'`#read` and `#path`'
|
150
136
|
end
|
151
137
|
end
|
152
138
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Onfido
|
2
4
|
class Check < Resource
|
3
5
|
def create(applicant_id:, report_names:, **payload)
|
@@ -18,5 +20,9 @@ module Onfido
|
|
18
20
|
def resume(check_id)
|
19
21
|
post(path: "checks/#{check_id}/resume")
|
20
22
|
end
|
23
|
+
|
24
|
+
def download(check_id)
|
25
|
+
get(path: "checks/#{check_id}/download")
|
26
|
+
end
|
21
27
|
end
|
22
28
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Onfido
|
2
4
|
class Webhook < Resource
|
3
5
|
def create(url:, **payload)
|
@@ -22,8 +24,8 @@ module Onfido
|
|
22
24
|
# request to one computed from the body
|
23
25
|
def self.valid?(request_body, request_signature, token)
|
24
26
|
if [request_body, request_signature, token].any?(&:nil?)
|
25
|
-
raise ArgumentError,
|
26
|
-
|
27
|
+
raise ArgumentError, 'A request body, request signature and token ' \
|
28
|
+
'must be provided'
|
27
29
|
end
|
28
30
|
|
29
31
|
computed_signature = generate_signature(request_body, token)
|
data/lib/onfido/version.rb
CHANGED
data/onfido.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
lib = File.expand_path('lib', __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
@@ -12,8 +12,8 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.summary = 'A wrapper for Onfido API'
|
13
13
|
spec.description = "A thin wrapper for Onfido's API. This gem only supports "\
|
14
14
|
"v3 of the Onfido API. Refer to Onfido's "\
|
15
|
-
|
16
|
-
|
15
|
+
'API documentation for details of the expected '\
|
16
|
+
'requests and responses.'
|
17
17
|
spec.homepage = 'http://github.com/onfido/onfido-ruby'
|
18
18
|
spec.license = 'MIT'
|
19
19
|
|
@@ -21,12 +21,11 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
22
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
23
23
|
spec.require_paths = ['lib']
|
24
|
-
spec.required_ruby_version =
|
24
|
+
spec.required_ruby_version = '>= 2.4.0'
|
25
25
|
|
26
|
-
spec.add_development_dependency 'rake', '~> 12.0'
|
27
26
|
spec.add_development_dependency 'rspec', '~> 3.1'
|
28
27
|
spec.add_development_dependency 'rspec-its', '~> 1.2'
|
29
|
-
spec.add_development_dependency 'rubocop', '~>
|
28
|
+
spec.add_development_dependency 'rubocop', '~> 1.11'
|
30
29
|
spec.add_development_dependency 'sinatra', '~> 1.4'
|
31
30
|
spec.add_development_dependency 'webmock', '~> 3.0'
|
32
31
|
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
describe Onfido::Address do
|
2
|
-
|
4
|
+
include_context 'fake onfido api'
|
3
5
|
|
4
6
|
describe '#all' do
|
5
7
|
it 'returns the addresses matching the postcode' do
|
6
|
-
response =
|
8
|
+
response = onfido.address.all('SW1 4NG')
|
7
9
|
|
8
10
|
expect(response['addresses'].count).to eq(2)
|
9
11
|
end
|
@@ -1,5 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
describe Onfido::Applicant do
|
2
|
-
|
4
|
+
include_context 'fake onfido api'
|
5
|
+
|
6
|
+
subject(:applicant) { onfido.applicant }
|
7
|
+
|
3
8
|
let(:applicant_id) { '61f659cb-c90b-4067-808a-6136b5c01351' }
|
4
9
|
let(:params) do
|
5
10
|
{
|
@@ -29,9 +34,9 @@ describe Onfido::Applicant do
|
|
29
34
|
|
30
35
|
it 'serializes the payload correctly' do
|
31
36
|
WebMock.after_request do |request_signature, _response|
|
32
|
-
if request_signature.uri.path == 'v3/applicants'
|
33
|
-
expect(Rack::Utils.parse_nested_query(request_signature.body))
|
34
|
-
to eq(params)
|
37
|
+
if request_signature.uri.path == 'v3.1/applicants'
|
38
|
+
expect(Rack::Utils.parse_nested_query(request_signature.body))
|
39
|
+
.to eq(params)
|
35
40
|
end
|
36
41
|
end
|
37
42
|
end
|
@@ -93,13 +98,13 @@ describe Onfido::Applicant do
|
|
93
98
|
it 'returns an error' do
|
94
99
|
applicant_id = 'a2fb9c62-ab10-4898-a8ec-342c4b552ad5'
|
95
100
|
|
96
|
-
expect { applicant.restore(applicant_id) }.to raise_error
|
101
|
+
expect { applicant.restore(applicant_id) }.to raise_error do |error|
|
97
102
|
expect(error).to be_a(Onfido::RequestError)
|
98
103
|
expect(error.message).to eq('There was a validation error on this request')
|
99
104
|
expect(error.fields).to eq(
|
100
|
-
|
105
|
+
'Applicant a2fb9c62-ab10-4898-a8ec-342c4b552ad5 is not scheduled for deletion'
|
101
106
|
)
|
102
|
-
|
107
|
+
end
|
103
108
|
end
|
104
109
|
end
|
105
110
|
end
|
@@ -1,5 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
describe Onfido::Check do
|
2
|
-
|
4
|
+
include_context 'fake onfido api'
|
5
|
+
|
6
|
+
subject(:check) { onfido.check }
|
7
|
+
|
3
8
|
let(:applicant_id) { '61f659cb-c90b-4067-808a-6136b5c01351' }
|
4
9
|
let(:check_id) { '8546921-123123-123123' }
|
5
10
|
|
@@ -20,7 +25,7 @@ describe Onfido::Check do
|
|
20
25
|
expect(response['id']).to eq(check_id)
|
21
26
|
end
|
22
27
|
|
23
|
-
it
|
28
|
+
it 'returns report_ids' do
|
24
29
|
response = check.find(check_id)
|
25
30
|
|
26
31
|
expect(response['report_ids'].first).to be_a(String)
|
@@ -36,16 +41,24 @@ describe Onfido::Check do
|
|
36
41
|
end
|
37
42
|
end
|
38
43
|
|
39
|
-
it
|
44
|
+
it 'returns report_ids' do
|
40
45
|
response = check.all(applicant_id)
|
41
46
|
|
42
47
|
expect(response['checks'].first['report_ids'].first).to be_a(String)
|
43
48
|
end
|
44
49
|
end
|
45
50
|
|
46
|
-
describe
|
51
|
+
describe '#resume' do
|
47
52
|
it 'returns success response' do
|
48
53
|
expect { check.resume(check_id) }.not_to raise_error
|
49
54
|
end
|
50
55
|
end
|
56
|
+
|
57
|
+
describe '#download' do
|
58
|
+
it 'returns the file data' do
|
59
|
+
response = check.download(check_id)
|
60
|
+
|
61
|
+
expect(response).not_to be_nil
|
62
|
+
end
|
63
|
+
end
|
51
64
|
end
|