onfido 1.0.0 → 2.0.2
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 +27 -0
- data/Gemfile +2 -0
- data/README.md +44 -156
- data/lib/onfido.rb +4 -3
- data/lib/onfido/api.rb +21 -11
- 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 +48 -58
- data/lib/onfido/resources/address.rb +3 -4
- 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 +11 -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 +8 -2
- data/lib/onfido/version.rb +3 -1
- data/onfido.gemspec +5 -7
- 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 +8 -4
- data/spec/integrations/extraction_spec.rb +23 -0
- data/spec/integrations/live_photo_spec.rb +8 -4
- data/spec/integrations/live_video_spec.rb +6 -1
- data/spec/integrations/report_spec.rb +6 -1
- data/spec/integrations/resource_spec.rb +106 -0
- data/spec/integrations/sdk_token_spec.rb +5 -1
- data/spec/integrations/webhook_spec.rb +35 -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 +69 -46
- 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/extraction.json +23 -0
- 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 +18 -43
- data/Rakefile +0 -1
- data/lib/onfido/configuration.rb +0 -46
- data/lib/onfido/null_logger.rb +0 -5
- data/spec/integrations/exceptions_spec.rb +0 -73
- data/spec/onfido/resource_spec.rb +0 -131
- data/spec/onfido_spec.rb +0 -76
data/lib/onfido.rb
CHANGED
@@ -1,21 +1,23 @@
|
|
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'
|
@@ -23,5 +25,4 @@ require 'onfido/resources/sdk_token'
|
|
23
25
|
require 'onfido/resources/webhook'
|
24
26
|
|
25
27
|
module Onfido
|
26
|
-
extend Configuration
|
27
28
|
end
|
data/lib/onfido/api.rb
CHANGED
@@ -1,43 +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(
|
30
|
+
@report ||= Onfido::Report.new(options)
|
29
31
|
end
|
30
32
|
|
31
33
|
def sdk_token
|
32
|
-
Onfido::SdkToken.new(
|
34
|
+
@sdk_token ||= Onfido::SdkToken.new(options)
|
33
35
|
end
|
34
36
|
|
35
37
|
def webhook
|
36
|
-
Onfido::Webhook.new(
|
38
|
+
@webhook ||= Onfido::Webhook.new(options)
|
37
39
|
end
|
38
40
|
|
39
41
|
def address
|
40
|
-
Onfido::Address.new(
|
42
|
+
@address ||= Onfido::Address.new(options)
|
43
|
+
end
|
44
|
+
|
45
|
+
def extraction
|
46
|
+
@extraction ||= Onfido::Extraction.new(options)
|
41
47
|
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
attr_reader :options
|
42
52
|
end
|
43
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,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,13 +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
|
-
}
|
70
|
-
end
|
71
|
-
|
72
62
|
# There seems to be a serialization issue with the HTTP client
|
73
63
|
# which does not serialize the payload properly.
|
74
64
|
# Have a look here https://gist.github.com/PericlesTheo/cb35139c57107ab3c84a
|
@@ -84,12 +74,12 @@ module Onfido
|
|
84
74
|
def handle_api_error(response)
|
85
75
|
parsed_response = parse(response)
|
86
76
|
|
87
|
-
general_api_error(response.code, response.body) unless parsed_response[
|
77
|
+
general_api_error(response.code, response.body) unless parsed_response['error']
|
88
78
|
|
89
79
|
error_class = response.code.to_i >= 500 ? ServerError : RequestError
|
90
80
|
|
91
81
|
raise error_class.new(
|
92
|
-
parsed_response[
|
82
|
+
parsed_response['error']['message'],
|
93
83
|
response_code: response.code,
|
94
84
|
response_body: response.body
|
95
85
|
)
|
@@ -106,46 +96,46 @@ module Onfido
|
|
106
96
|
)
|
107
97
|
end
|
108
98
|
|
109
|
-
def handle_restclient_error(error
|
99
|
+
def handle_restclient_error(error) # rubocop:todo Metrics/MethodLength
|
110
100
|
connection_message =
|
111
|
-
|
112
|
-
|
101
|
+
'Please check your internet connection and try again. ' \
|
102
|
+
'If this problem persists, you should let us know at info@onfido.com.'
|
113
103
|
|
114
104
|
message =
|
115
105
|
case error
|
116
106
|
when RestClient::RequestTimeout
|
117
|
-
"Could not connect to Onfido
|
107
|
+
"Could not connect to Onfido . #{connection_message}"
|
118
108
|
|
119
109
|
when RestClient::ServerBrokeConnection
|
120
|
-
"The connection to the server
|
121
|
-
"request completed. #{connection_message}"
|
110
|
+
"The connection to the server broke before the request completed. #{connection_message}"
|
122
111
|
|
123
112
|
when RestClient::SSLCertificateNotVerified
|
124
113
|
"Could not verify Onfido's SSL certificate. Please make sure " \
|
125
|
-
|
126
|
-
|
127
|
-
|
114
|
+
'that your network is not intercepting certificates. '
|
115
|
+
|
116
|
+
when RestClient::BadGateway
|
117
|
+
"Could not connect to Onfido. Server may be overloaded." \
|
128
118
|
|
129
119
|
when SocketError
|
130
|
-
|
131
|
-
|
120
|
+
'Unexpected error when trying to connect to Onfido. ' \
|
121
|
+
'You may be seeing this message because your DNS is not working. ' \
|
132
122
|
"To check, try running 'host onfido.com' from the command line."
|
133
123
|
|
134
124
|
else
|
135
|
-
|
136
|
-
|
125
|
+
'Unexpected error communicating with Onfido. ' \
|
126
|
+
'If this problem persists, let us know at info@onfido.com.'
|
137
127
|
end
|
138
128
|
|
139
129
|
full_message = message + "\n\n(Network error: #{error.message})"
|
140
130
|
|
141
|
-
raise ConnectionError
|
131
|
+
raise ConnectionError, full_message
|
142
132
|
end
|
143
133
|
|
144
134
|
def validate_file!(file)
|
145
135
|
return if file.respond_to?(:read) && file.respond_to?(:path)
|
146
136
|
|
147
|
-
raise ArgumentError,
|
148
|
-
|
137
|
+
raise ArgumentError, 'File must be a `File`-like object which responds to ' \
|
138
|
+
'`#read` and `#path`'
|
149
139
|
end
|
150
140
|
end
|
151
141
|
end
|
@@ -1,10 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Onfido
|
2
4
|
class Address < Resource
|
3
5
|
def all(postcode)
|
4
|
-
get(
|
5
|
-
path: 'addresses/pick',
|
6
|
-
payload: { postcode: postcode.delete(' ') }
|
7
|
-
)
|
6
|
+
get(path: "addresses/pick?postcode=#{postcode.delete(' ')}")
|
8
7
|
end
|
9
8
|
end
|
10
9
|
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)
|
@@ -13,13 +15,17 @@ module Onfido
|
|
13
15
|
get(path: 'webhooks')
|
14
16
|
end
|
15
17
|
|
18
|
+
def destroy(webhook_id)
|
19
|
+
delete(path: "webhooks/#{webhook_id}")
|
20
|
+
end
|
21
|
+
|
16
22
|
# As well as being a normal resource, Onfido::Webhook also supports
|
17
23
|
# verifying the authenticity of a webhook by comparing the signature on the
|
18
24
|
# request to one computed from the body
|
19
25
|
def self.valid?(request_body, request_signature, token)
|
20
26
|
if [request_body, request_signature, token].any?(&:nil?)
|
21
|
-
raise ArgumentError,
|
22
|
-
|
27
|
+
raise ArgumentError, 'A request body, request signature and token ' \
|
28
|
+
'must be provided'
|
23
29
|
end
|
24
30
|
|
25
31
|
computed_signature = generate_signature(request_body, token)
|