onfido 0.15.1 → 2.0.1
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/.github/workflows/gem-push.yml +31 -0
- data/.github/workflows/ruby.yml +25 -0
- data/.rubocop.yml +5 -49
- data/.travis.yml +3 -10
- data/CHANGELOG.md +28 -0
- data/Gemfile +2 -0
- data/LICENSE +2 -1
- data/README.md +46 -172
- data/lib/onfido.rb +4 -4
- data/lib/onfido/api.rb +21 -15
- 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 +44 -61
- data/lib/onfido/resources/address.rb +3 -2
- data/lib/onfido/resources/applicant.rb +8 -6
- data/lib/onfido/resources/check.rb +15 -19
- data/lib/onfido/resources/document.rb +13 -11
- data/lib/onfido/resources/extraction.rb +11 -0
- data/lib/onfido/resources/live_photo.rb +11 -14
- data/lib/onfido/resources/live_video.rb +7 -8
- data/lib/onfido/resources/report.rb +10 -9
- data/lib/onfido/resources/sdk_token.rb +5 -5
- data/lib/onfido/resources/webhook.rb +15 -11
- data/lib/onfido/version.rb +3 -1
- data/onfido.gemspec +10 -12
- data/spec/integrations/address_spec.rb +5 -2
- data/spec/integrations/applicant_spec.rb +29 -42
- data/spec/integrations/check_spec.rb +28 -69
- data/spec/integrations/document_spec.rb +22 -19
- data/spec/integrations/extraction_spec.rb +23 -0
- data/spec/integrations/live_photo_spec.rb +18 -15
- data/spec/integrations/live_video_spec.rb +13 -11
- data/spec/integrations/report_spec.rb +16 -13
- data/spec/integrations/resource_spec.rb +93 -0
- data/spec/integrations/sdk_token_spec.rb +10 -6
- data/spec/integrations/webhook_spec.rb +56 -37
- 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 +77 -88
- data/spec/support/fixtures/applicant.json +21 -42
- data/spec/support/fixtures/check.json +4 -4
- data/spec/support/fixtures/checks.json +4 -4
- data/spec/support/fixtures/document.json +2 -2
- data/spec/support/fixtures/documents.json +8 -8
- data/spec/support/fixtures/extraction.json +23 -0
- data/spec/support/fixtures/live_photo.json +3 -3
- data/spec/support/fixtures/live_photos.json +6 -6
- data/spec/support/fixtures/live_video.json +3 -3
- data/spec/support/fixtures/live_videos.json +4 -4
- data/spec/support/fixtures/report.json +4 -4
- data/spec/support/fixtures/reports.json +8 -8
- data/spec/support/fixtures/webhook.json +6 -5
- data/spec/support/fixtures/webhooks.json +17 -12
- metadata +27 -65
- data/Rakefile +0 -1
- data/lib/onfido/configuration.rb +0 -47
- data/lib/onfido/null_logger.rb +0 -5
- data/lib/onfido/resources/report_type_group.rb +0 -11
- data/spec/integrations/exceptions_spec.rb +0 -74
- data/spec/integrations/report_type_group_spec.rb +0 -19
- data/spec/onfido/resource_spec.rb +0 -137
- data/spec/onfido_spec.rb +0 -84
- data/spec/support/fixtures/check_with_expanded_reports.json +0 -30
- data/spec/support/fixtures/checks_with_expanded_reports.json +0 -34
- data/spec/support/fixtures/report_type_group.json +0 -25
- data/spec/support/fixtures/report_type_groups.json +0 -30
data/lib/onfido.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
require 'rack'
|
3
5
|
require 'rest-client'
|
4
6
|
require 'openssl'
|
5
7
|
|
6
8
|
require 'onfido/version'
|
7
|
-
require 'onfido/configuration'
|
8
9
|
require 'onfido/errors/onfido_error'
|
9
10
|
require 'onfido/errors/request_error'
|
10
11
|
require 'onfido/errors/server_error'
|
11
12
|
require 'onfido/errors/connection_error'
|
12
|
-
require 'onfido/null_logger'
|
13
13
|
require 'onfido/api'
|
14
|
+
require 'onfido/options'
|
14
15
|
require 'onfido/resource'
|
15
16
|
require 'onfido/resources/address'
|
16
17
|
require 'onfido/resources/applicant'
|
17
18
|
require 'onfido/resources/check'
|
18
19
|
require 'onfido/resources/document'
|
20
|
+
require 'onfido/resources/extraction'
|
19
21
|
require 'onfido/resources/live_photo'
|
20
22
|
require 'onfido/resources/live_video'
|
21
23
|
require 'onfido/resources/report'
|
22
|
-
require 'onfido/resources/report_type_group'
|
23
24
|
require 'onfido/resources/sdk_token'
|
24
25
|
require 'onfido/resources/webhook'
|
25
26
|
|
26
27
|
module Onfido
|
27
|
-
extend Configuration
|
28
28
|
end
|
data/lib/onfido/api.rb
CHANGED
@@ -1,47 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Onfido
|
2
4
|
class API
|
3
|
-
def initialize(
|
4
|
-
@
|
5
|
+
def initialize(api_key:, region:, **extra_options)
|
6
|
+
@options = Onfido::Options.new(api_key: api_key, region: region, **extra_options)
|
5
7
|
end
|
6
8
|
|
7
9
|
def applicant
|
8
|
-
Onfido::Applicant.new(
|
10
|
+
@applicant ||= Onfido::Applicant.new(options)
|
9
11
|
end
|
10
12
|
|
11
13
|
def check
|
12
|
-
Onfido::Check.new(
|
14
|
+
@check ||= Onfido::Check.new(options)
|
13
15
|
end
|
14
16
|
|
15
17
|
def document
|
16
|
-
Onfido::Document.new(
|
18
|
+
@document ||= Onfido::Document.new(options)
|
17
19
|
end
|
18
20
|
|
19
21
|
def live_photo
|
20
|
-
Onfido::LivePhoto.new(
|
22
|
+
@live_photo ||= Onfido::LivePhoto.new(options)
|
21
23
|
end
|
22
24
|
|
23
25
|
def live_video
|
24
|
-
Onfido::LiveVideo.new(
|
26
|
+
@live_video ||= Onfido::LiveVideo.new(options)
|
25
27
|
end
|
26
28
|
|
27
29
|
def report
|
28
|
-
Onfido::Report.new(
|
29
|
-
end
|
30
|
-
|
31
|
-
def report_type_group
|
32
|
-
Onfido::ReportTypeGroup.new(@api_key)
|
30
|
+
@report ||= Onfido::Report.new(options)
|
33
31
|
end
|
34
32
|
|
35
33
|
def sdk_token
|
36
|
-
Onfido::SdkToken.new(
|
34
|
+
@sdk_token ||= Onfido::SdkToken.new(options)
|
37
35
|
end
|
38
36
|
|
39
37
|
def webhook
|
40
|
-
Onfido::Webhook.new(
|
38
|
+
@webhook ||= Onfido::Webhook.new(options)
|
41
39
|
end
|
42
40
|
|
43
41
|
def address
|
44
|
-
Onfido::Address.new(
|
42
|
+
@address ||= Onfido::Address.new(options)
|
45
43
|
end
|
44
|
+
|
45
|
+
def extraction
|
46
|
+
@extraction ||= Onfido::Extraction.new(options)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
attr_reader :options
|
46
52
|
end
|
47
53
|
end
|
@@ -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,59 +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
|
-
Onfido.endpoint + path
|
12
|
-
end
|
12
|
+
private
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
url: args.first.fetch(:url),
|
19
|
-
payload: build_query(args.first.fetch(:payload, {}))
|
20
|
-
)
|
21
|
-
end
|
14
|
+
attr_reader :rest_client
|
15
|
+
|
16
|
+
def get(path:)
|
17
|
+
handle_request { rest_client[path].get }
|
22
18
|
end
|
23
19
|
|
24
|
-
|
20
|
+
def post(path:, payload: nil)
|
21
|
+
handle_request { rest_client[path].post(payload) }
|
22
|
+
end
|
25
23
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
method = options.fetch(:method)
|
24
|
+
def put(path:, payload: nil)
|
25
|
+
handle_request { rest_client[path].put(payload) }
|
26
|
+
end
|
30
27
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
method: method,
|
35
|
-
headers: headers,
|
36
|
-
open_timeout: Onfido.open_timeout,
|
37
|
-
timeout: Onfido.read_timeout
|
38
|
-
}
|
28
|
+
def delete(path:)
|
29
|
+
handle_request { rest_client[path].delete }
|
30
|
+
end
|
39
31
|
|
40
|
-
|
32
|
+
def handle_request
|
33
|
+
response = yield
|
41
34
|
|
42
35
|
# response should be parsed only when there is a response expected
|
43
36
|
parse(response) unless response.code == 204 # no_content
|
44
|
-
rescue RestClient::ExceptionWithResponse =>
|
45
|
-
if
|
46
|
-
handle_api_error(
|
37
|
+
rescue RestClient::ExceptionWithResponse => e
|
38
|
+
if e.response && !timeout_response?(e.response)
|
39
|
+
handle_api_error(e.response)
|
47
40
|
else
|
48
|
-
handle_restclient_error(
|
41
|
+
handle_restclient_error(e)
|
49
42
|
end
|
50
|
-
rescue RestClient::Exception, Errno::ECONNREFUSED =>
|
51
|
-
handle_restclient_error(
|
43
|
+
rescue RestClient::Exception, Errno::ECONNREFUSED => e
|
44
|
+
handle_restclient_error(e)
|
52
45
|
end
|
53
46
|
|
54
47
|
def parse(response)
|
55
48
|
content_type = response.headers[:content_type]
|
56
|
-
if content_type
|
49
|
+
if content_type&.include?('application/json')
|
57
50
|
JSON.parse(response.body.to_s)
|
58
51
|
else
|
59
52
|
response.body
|
@@ -66,13 +59,6 @@ module Onfido
|
|
66
59
|
response.code.to_i == REQUEST_TIMEOUT_HTTP_CODE
|
67
60
|
end
|
68
61
|
|
69
|
-
def headers
|
70
|
-
{
|
71
|
-
'Authorization' => "Token token=#{@api_key}",
|
72
|
-
'Accept' => "application/json"
|
73
|
-
}
|
74
|
-
end
|
75
|
-
|
76
62
|
# There seems to be a serialization issue with the HTTP client
|
77
63
|
# which does not serialize the payload properly.
|
78
64
|
# Have a look here https://gist.github.com/PericlesTheo/cb35139c57107ab3c84a
|
@@ -88,12 +74,12 @@ module Onfido
|
|
88
74
|
def handle_api_error(response)
|
89
75
|
parsed_response = parse(response)
|
90
76
|
|
91
|
-
general_api_error(response.code, response.body) unless parsed_response[
|
77
|
+
general_api_error(response.code, response.body) unless parsed_response['error']
|
92
78
|
|
93
79
|
error_class = response.code.to_i >= 500 ? ServerError : RequestError
|
94
80
|
|
95
81
|
raise error_class.new(
|
96
|
-
parsed_response[
|
82
|
+
parsed_response['error']['message'],
|
97
83
|
response_code: response.code,
|
98
84
|
response_body: response.body
|
99
85
|
)
|
@@ -110,46 +96,43 @@ module Onfido
|
|
110
96
|
)
|
111
97
|
end
|
112
98
|
|
113
|
-
def handle_restclient_error(error
|
99
|
+
def handle_restclient_error(error) # rubocop:todo Metrics/MethodLength
|
114
100
|
connection_message =
|
115
|
-
|
116
|
-
|
101
|
+
'Please check your internet connection and try again. ' \
|
102
|
+
'If this problem persists, you should let us know at info@onfido.com.'
|
117
103
|
|
118
104
|
message =
|
119
105
|
case error
|
120
106
|
when RestClient::RequestTimeout
|
121
|
-
"Could not connect to Onfido
|
107
|
+
"Could not connect to Onfido . #{connection_message}"
|
122
108
|
|
123
109
|
when RestClient::ServerBrokeConnection
|
124
|
-
"The connection to the server
|
125
|
-
"request completed. #{connection_message}"
|
110
|
+
"The connection to the server broke before the request completed. #{connection_message}"
|
126
111
|
|
127
112
|
when RestClient::SSLCertificateNotVerified
|
128
113
|
"Could not verify Onfido's SSL certificate. Please make sure " \
|
129
|
-
|
130
|
-
"(Try going to #{Onfido.endpoint} in your browser.) " \
|
131
|
-
"If this problem persists, let us know at info@onfido.com."
|
114
|
+
'that your network is not intercepting certificates. '
|
132
115
|
|
133
116
|
when SocketError
|
134
|
-
|
135
|
-
|
117
|
+
'Unexpected error when trying to connect to Onfido. ' \
|
118
|
+
'You may be seeing this message because your DNS is not working. ' \
|
136
119
|
"To check, try running 'host onfido.com' from the command line."
|
137
120
|
|
138
121
|
else
|
139
|
-
|
140
|
-
|
122
|
+
'Unexpected error communicating with Onfido. ' \
|
123
|
+
'If this problem persists, let us know at info@onfido.com.'
|
141
124
|
end
|
142
125
|
|
143
126
|
full_message = message + "\n\n(Network error: #{error.message})"
|
144
127
|
|
145
|
-
raise ConnectionError
|
128
|
+
raise ConnectionError, full_message
|
146
129
|
end
|
147
130
|
|
148
131
|
def validate_file!(file)
|
149
132
|
return if file.respond_to?(:read) && file.respond_to?(:path)
|
150
133
|
|
151
|
-
raise ArgumentError,
|
152
|
-
|
134
|
+
raise ArgumentError, 'File must be a `File`-like object which responds to ' \
|
135
|
+
'`#read` and `#path`'
|
153
136
|
end
|
154
137
|
end
|
155
138
|
end
|
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Onfido
|
2
4
|
class Address < Resource
|
3
5
|
def all(postcode)
|
4
|
-
|
5
|
-
get(url: url_for("addresses/pick?#{query_string}"))
|
6
|
+
get(path: "addresses/pick?postcode=#{postcode.delete(' ')}")
|
6
7
|
end
|
7
8
|
end
|
8
9
|
end
|
@@ -1,27 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Onfido
|
2
4
|
class Applicant < Resource
|
3
5
|
def create(payload)
|
4
|
-
post(
|
6
|
+
post(path: 'applicants', payload: payload)
|
5
7
|
end
|
6
8
|
|
7
9
|
def update(applicant_id, payload)
|
8
|
-
put(
|
10
|
+
put(path: "applicants/#{applicant_id}", payload: payload)
|
9
11
|
end
|
10
12
|
|
11
13
|
def destroy(applicant_id)
|
12
|
-
delete(
|
14
|
+
delete(path: "applicants/#{applicant_id}")
|
13
15
|
end
|
14
16
|
|
15
17
|
def find(applicant_id)
|
16
|
-
get(
|
18
|
+
get(path: "applicants/#{applicant_id}")
|
17
19
|
end
|
18
20
|
|
19
21
|
def all(page: 1, per_page: 20)
|
20
|
-
get(
|
22
|
+
get(path: "applicants?page=#{page}&per_page=#{per_page}")
|
21
23
|
end
|
22
24
|
|
23
25
|
def restore(applicant_id)
|
24
|
-
post(
|
26
|
+
post(path: "applicants/#{applicant_id}/restore")
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
@@ -1,32 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Onfido
|
2
4
|
class Check < Resource
|
3
|
-
def create(applicant_id
|
4
|
-
|
5
|
-
|
6
|
-
payload: payload
|
7
|
-
)
|
8
|
-
end
|
5
|
+
def create(applicant_id:, report_names:, **payload)
|
6
|
+
payload[:applicant_id] = applicant_id
|
7
|
+
payload[:report_names] = report_names
|
9
8
|
|
10
|
-
|
11
|
-
querystring = "&expand=#{expand}" if expand
|
12
|
-
get(url: url_for("applicants/#{applicant_id}/checks/#{check_id}?" \
|
13
|
-
"#{querystring}"))
|
9
|
+
post(path: 'checks', payload: payload)
|
14
10
|
end
|
15
11
|
|
16
|
-
def
|
17
|
-
|
18
|
-
querystring = "&expand=#{expand}" if expand
|
19
|
-
get(url: url_for("#{url_path}?#{querystring}"))
|
12
|
+
def find(check_id)
|
13
|
+
get(path: "checks/#{check_id}")
|
20
14
|
end
|
21
15
|
|
22
|
-
def all(applicant_id
|
23
|
-
|
24
|
-
querystring += "&expand=#{expand}" if expand
|
25
|
-
get(url: url_for("applicants/#{applicant_id}/checks?#{querystring}"))
|
16
|
+
def all(applicant_id)
|
17
|
+
get(path: "checks?applicant_id=#{applicant_id}")
|
26
18
|
end
|
27
19
|
|
28
20
|
def resume(check_id)
|
29
|
-
post(
|
21
|
+
post(path: "checks/#{check_id}/resume")
|
22
|
+
end
|
23
|
+
|
24
|
+
def download(check_id)
|
25
|
+
get(path: "checks/#{check_id}/download")
|
30
26
|
end
|
31
27
|
end
|
32
28
|
end
|
@@ -1,26 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Onfido
|
2
4
|
class Document < Resource
|
3
5
|
# with open-uri the file can be a link or an actual file
|
4
6
|
|
5
|
-
def create(applicant_id
|
6
|
-
validate_file!(
|
7
|
+
def create(applicant_id:, file:, type:, **payload)
|
8
|
+
validate_file!(file)
|
9
|
+
payload[:applicant_id] = applicant_id
|
10
|
+
payload[:file] = file
|
11
|
+
payload[:type] = type
|
7
12
|
|
8
|
-
post(
|
9
|
-
url: url_for("applicants/#{applicant_id}/documents"),
|
10
|
-
payload: payload
|
11
|
-
)
|
13
|
+
post(path: 'documents', payload: payload)
|
12
14
|
end
|
13
15
|
|
14
|
-
def find(
|
15
|
-
get(
|
16
|
+
def find(document_id)
|
17
|
+
get(path: "documents/#{document_id}")
|
16
18
|
end
|
17
19
|
|
18
|
-
def download(
|
19
|
-
get(
|
20
|
+
def download(document_id)
|
21
|
+
get(path: "documents/#{document_id}/download")
|
20
22
|
end
|
21
23
|
|
22
24
|
def all(applicant_id)
|
23
|
-
get(
|
25
|
+
get(path: "documents?applicant_id=#{applicant_id}")
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|