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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/gem-push.yml +31 -0
  3. data/.github/workflows/ruby.yml +25 -0
  4. data/.rubocop.yml +5 -49
  5. data/.travis.yml +3 -10
  6. data/CHANGELOG.md +28 -0
  7. data/Gemfile +2 -0
  8. data/LICENSE +2 -1
  9. data/README.md +46 -172
  10. data/lib/onfido.rb +4 -4
  11. data/lib/onfido/api.rb +21 -15
  12. data/lib/onfido/errors/connection_error.rb +2 -0
  13. data/lib/onfido/errors/onfido_error.rb +2 -0
  14. data/lib/onfido/errors/request_error.rb +2 -0
  15. data/lib/onfido/errors/server_error.rb +2 -0
  16. data/lib/onfido/options.rb +38 -0
  17. data/lib/onfido/resource.rb +44 -61
  18. data/lib/onfido/resources/address.rb +3 -2
  19. data/lib/onfido/resources/applicant.rb +8 -6
  20. data/lib/onfido/resources/check.rb +15 -19
  21. data/lib/onfido/resources/document.rb +13 -11
  22. data/lib/onfido/resources/extraction.rb +11 -0
  23. data/lib/onfido/resources/live_photo.rb +11 -14
  24. data/lib/onfido/resources/live_video.rb +7 -8
  25. data/lib/onfido/resources/report.rb +10 -9
  26. data/lib/onfido/resources/sdk_token.rb +5 -5
  27. data/lib/onfido/resources/webhook.rb +15 -11
  28. data/lib/onfido/version.rb +3 -1
  29. data/onfido.gemspec +10 -12
  30. data/spec/integrations/address_spec.rb +5 -2
  31. data/spec/integrations/applicant_spec.rb +29 -42
  32. data/spec/integrations/check_spec.rb +28 -69
  33. data/spec/integrations/document_spec.rb +22 -19
  34. data/spec/integrations/extraction_spec.rb +23 -0
  35. data/spec/integrations/live_photo_spec.rb +18 -15
  36. data/spec/integrations/live_video_spec.rb +13 -11
  37. data/spec/integrations/report_spec.rb +16 -13
  38. data/spec/integrations/resource_spec.rb +93 -0
  39. data/spec/integrations/sdk_token_spec.rb +10 -6
  40. data/spec/integrations/webhook_spec.rb +56 -37
  41. data/spec/onfido/api_spec.rb +14 -25
  42. data/spec/onfido/connection_error_spec.rb +4 -2
  43. data/spec/onfido/options_spec.rb +39 -0
  44. data/spec/onfido/request_error_spec.rb +4 -2
  45. data/spec/spec_helper.rb +3 -5
  46. data/spec/support/fake_onfido_api.rb +77 -88
  47. data/spec/support/fixtures/applicant.json +21 -42
  48. data/spec/support/fixtures/check.json +4 -4
  49. data/spec/support/fixtures/checks.json +4 -4
  50. data/spec/support/fixtures/document.json +2 -2
  51. data/spec/support/fixtures/documents.json +8 -8
  52. data/spec/support/fixtures/extraction.json +23 -0
  53. data/spec/support/fixtures/live_photo.json +3 -3
  54. data/spec/support/fixtures/live_photos.json +6 -6
  55. data/spec/support/fixtures/live_video.json +3 -3
  56. data/spec/support/fixtures/live_videos.json +4 -4
  57. data/spec/support/fixtures/report.json +4 -4
  58. data/spec/support/fixtures/reports.json +8 -8
  59. data/spec/support/fixtures/webhook.json +6 -5
  60. data/spec/support/fixtures/webhooks.json +17 -12
  61. metadata +27 -65
  62. data/Rakefile +0 -1
  63. data/lib/onfido/configuration.rb +0 -47
  64. data/lib/onfido/null_logger.rb +0 -5
  65. data/lib/onfido/resources/report_type_group.rb +0 -11
  66. data/spec/integrations/exceptions_spec.rb +0 -74
  67. data/spec/integrations/report_type_group_spec.rb +0 -19
  68. data/spec/onfido/resource_spec.rb +0 -137
  69. data/spec/onfido_spec.rb +0 -84
  70. data/spec/support/fixtures/check_with_expanded_reports.json +0 -30
  71. data/spec/support/fixtures/checks_with_expanded_reports.json +0 -34
  72. data/spec/support/fixtures/report_type_group.json +0 -25
  73. data/spec/support/fixtures/report_type_groups.json +0 -30
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Onfido
4
+ class Extraction < Resource
5
+ def create(document_id:)
6
+ payload = { document_id: document_id }
7
+
8
+ post(path: 'extractions', payload: payload)
9
+ end
10
+ end
11
+ end
@@ -1,30 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Onfido
2
4
  class LivePhoto < Resource
3
5
  # with open-uri the file can be a link or an actual file
4
6
 
5
- def create(applicant_id, payload)
6
- validate_file!(payload.fetch(:file))
7
+ def create(applicant_id:, file:, **payload)
8
+ validate_file!(file)
7
9
  payload[:applicant_id] = applicant_id
10
+ payload[:file] = file
8
11
 
9
- post(
10
- url: url_for("/live_photos"),
11
- payload: payload
12
- )
12
+ post(path: 'live_photos', payload: payload)
13
13
  end
14
14
 
15
- def find(applicant_id, live_photo_id)
16
- query_string = "applicant_id=#{applicant_id}"
17
- get(url: url_for("live_photos/#{live_photo_id}?#{query_string}"))
15
+ def find(live_photo_id)
16
+ get(path: "live_photos/#{live_photo_id}")
18
17
  end
19
18
 
20
- def download(applicant_id, live_photo_id)
21
- query_string = "applicant_id=#{applicant_id}"
22
- get(url: url_for("live_photos/#{live_photo_id}/download?#{query_string}"))
19
+ def download(live_photo_id)
20
+ get(path: "live_photos/#{live_photo_id}/download")
23
21
  end
24
22
 
25
23
  def all(applicant_id)
26
- query_string = "applicant_id=#{applicant_id}"
27
- get(url: url_for("live_photos?#{query_string}"))
24
+ get(path: "live_photos?applicant_id=#{applicant_id}")
28
25
  end
29
26
  end
30
27
  end
@@ -1,18 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Onfido
2
4
  class LiveVideo < Resource
3
- def find(applicant_id, live_video_id)
4
- query_string = "applicant_id=#{applicant_id}"
5
- get(url: url_for("live_videos/#{live_video_id}?#{query_string}"))
5
+ def find(live_video_id)
6
+ get(path: "live_videos/#{live_video_id}")
6
7
  end
7
8
 
8
- def download(applicant_id, live_video_id)
9
- query_string = "applicant_id=#{applicant_id}"
10
- get(url: url_for("live_videos/#{live_video_id}/download?#{query_string}"))
9
+ def download(live_video_id)
10
+ get(path: "live_videos/#{live_video_id}/download")
11
11
  end
12
12
 
13
13
  def all(applicant_id)
14
- query_string = "applicant_id=#{applicant_id}"
15
- get(url: url_for("live_videos?#{query_string}"))
14
+ get(path: "live_videos?applicant_id=#{applicant_id}")
16
15
  end
17
16
  end
18
17
  end
@@ -1,20 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Onfido
2
4
  class Report < Resource
3
- def find(check_id, report_id)
4
- get(url: url_for("checks/#{check_id}/reports/#{report_id}"))
5
+ def find(report_id)
6
+ get(path: "reports/#{report_id}")
5
7
  end
6
8
 
7
- def all(check_id, page: 1, per_page: 20)
8
- querystring = "page=#{page}&per_page=#{per_page}"
9
- get(url: url_for("checks/#{check_id}/reports?#{querystring}"))
9
+ def all(check_id)
10
+ get(path: "reports?check_id=#{check_id}")
10
11
  end
11
12
 
12
- def resume(check_id, report_id)
13
- post(url: url_for("checks/#{check_id}/reports/#{report_id}/resume"))
13
+ def resume(report_id)
14
+ post(path: "reports/#{report_id}/resume")
14
15
  end
15
16
 
16
- def cancel(check_id, report_id)
17
- post(url: url_for("checks/#{check_id}/reports/#{report_id}/cancel"))
17
+ def cancel(report_id)
18
+ post(path: "reports/#{report_id}/cancel")
18
19
  end
19
20
  end
20
21
  end
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Onfido
2
4
  class SdkToken < Resource
3
- def create(payload)
4
- post(
5
- url: url_for("sdk_token"),
6
- payload: payload
7
- )
5
+ def create(applicant_id:, **payload)
6
+ payload[:applicant_id] = applicant_id
7
+ post(path: 'sdk_token', payload: payload)
8
8
  end
9
9
  end
10
10
  end
@@ -1,18 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Onfido
2
4
  class Webhook < Resource
3
- def create(payload)
4
- post(
5
- url: url_for('webhooks'),
6
- payload: payload
7
- )
5
+ def create(url:, **payload)
6
+ payload[:url] = url
7
+ post(path: 'webhooks', payload: payload)
8
8
  end
9
9
 
10
10
  def find(webhooks_id)
11
- get(url: url_for("webhooks/#{webhooks_id}"))
11
+ get(path: "webhooks/#{webhooks_id}")
12
+ end
13
+
14
+ def all
15
+ get(path: 'webhooks')
12
16
  end
13
17
 
14
- def all(page: 1, per_page: 20)
15
- get(url: url_for("webhooks?page=#{page}&per_page=#{per_page}"))
18
+ def destroy(webhook_id)
19
+ delete(path: "webhooks/#{webhook_id}")
16
20
  end
17
21
 
18
22
  # As well as being a normal resource, Onfido::Webhook also supports
@@ -20,8 +24,8 @@ module Onfido
20
24
  # request to one computed from the body
21
25
  def self.valid?(request_body, request_signature, token)
22
26
  if [request_body, request_signature, token].any?(&:nil?)
23
- raise ArgumentError, "A request body, request signature and token " \
24
- "must be provided"
27
+ raise ArgumentError, 'A request body, request signature and token ' \
28
+ 'must be provided'
25
29
  end
26
30
 
27
31
  computed_signature = generate_signature(request_body, token)
@@ -29,7 +33,7 @@ module Onfido
29
33
  end
30
34
 
31
35
  def self.generate_signature(request_body, token)
32
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), token, request_body)
36
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), token, request_body)
33
37
  end
34
38
  private_class_method :generate_signature
35
39
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Onfido
2
- VERSION = '0.15.1'.freeze
4
+ VERSION = '2.0.1'
3
5
  end
data/onfido.gemspec CHANGED
@@ -1,4 +1,4 @@
1
- # coding: utf-8
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)
@@ -7,27 +7,25 @@ require 'onfido/version'
7
7
  Gem::Specification.new do |spec|
8
8
  spec.name = 'onfido'
9
9
  spec.version = Onfido::VERSION
10
- spec.authors = ['Pericles Theodorou', 'Grey Baker']
11
- spec.email = ['periclestheo@gmail.com', 'grey@gocardless.com']
10
+ spec.authors = ['Onfido']
11
+ spec.email = ['engineering@onfido.com']
12
12
  spec.summary = 'A wrapper for Onfido API'
13
- spec.description = "A thin wrapper for Onfido's API. This gem supports "\
14
- "both v1 and v2 of the Onfido API. Refer to Onfido's "\
15
- "API documentation for details of the expected "\
16
- "requests and responses for both."
17
- spec.homepage = 'http://github.com/hvssle/onfido'
13
+ spec.description = "A thin wrapper for Onfido's API. This gem only supports "\
14
+ "v3 of the Onfido API. Refer to Onfido's "\
15
+ 'API documentation for details of the expected '\
16
+ 'requests and responses.'
17
+ spec.homepage = 'http://github.com/onfido/onfido-ruby'
18
18
  spec.license = 'MIT'
19
19
 
20
20
  spec.files = `git ls-files -z`.split("\x0")
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 = ">= 2.2.0"
24
+ spec.required_ruby_version = '>= 2.4.0'
25
25
 
26
- spec.add_development_dependency 'bundler', '~> 2.0'
27
- spec.add_development_dependency 'rake', '~> 12.0'
28
26
  spec.add_development_dependency 'rspec', '~> 3.1'
29
27
  spec.add_development_dependency 'rspec-its', '~> 1.2'
30
- spec.add_development_dependency 'rubocop', '~> 0.57.0'
28
+ spec.add_development_dependency 'rubocop', '~> 1.11'
31
29
  spec.add_development_dependency 'sinatra', '~> 1.4'
32
30
  spec.add_development_dependency 'webmock', '~> 3.0'
33
31
 
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::Address do
2
- subject(:api) { Onfido::API.new }
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 = api.address.all('SW1 4NG')
8
+ response = onfido.address.all('SW1 4NG')
9
+
7
10
  expect(response['addresses'].count).to eq(2)
8
11
  end
9
12
  end
@@ -1,38 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::Applicant do
2
- subject(:applicant) { described_class.new }
4
+ include_context 'fake onfido api'
5
+
6
+ subject(:applicant) { onfido.applicant }
7
+
8
+ let(:applicant_id) { '61f659cb-c90b-4067-808a-6136b5c01351' }
3
9
  let(:params) do
4
10
  {
5
11
  'title' => 'Mr',
6
12
  'first_name' => 'Chandler',
7
13
  'last_name' => 'Bing',
8
- 'gender' => 'male',
9
14
  'middle_name' => 'Muriel',
10
15
  'dob' => '1968-04-08',
11
- 'telephone' => '555555555',
12
- 'mobile' => '77777777',
13
16
  'email' => 'chandler_bing_6@friends.com',
14
- 'addresses' => [
15
- {
16
- 'flat_number' => '4',
17
- 'building_number' => '100',
18
- 'building_name' => 'Awesome Building',
19
- 'street' => 'Main Street',
20
- 'sub_street' => 'A sub street',
21
- 'town' => 'London',
22
- 'postcode' => 'SW4 6EH',
23
- 'country' => 'GBR'
24
- },
25
- {
26
- 'flat_number' => '1',
27
- 'building_number' => '10',
28
- 'building_name' => 'Great Building',
29
- 'street' => 'Old Street',
30
- 'sub_street' => 'Sub Street',
31
- 'town' => 'London',
32
- 'postcode' => 'SW1 4NG',
33
- 'country' => 'GBR'
34
- }
35
- ]
17
+ 'address' => {
18
+ 'flat_number' => '4',
19
+ 'building_number' => '100',
20
+ 'building_name' => 'Awesome Building',
21
+ 'street' => 'Main Street',
22
+ 'sub_street' => 'A sub street',
23
+ 'town' => 'London',
24
+ 'postcode' => 'SW4 6EH',
25
+ 'country' => 'GBR'
26
+ }
36
27
  }
37
28
  end
38
29
 
@@ -43,9 +34,9 @@ describe Onfido::Applicant do
43
34
 
44
35
  it 'serializes the payload correctly' do
45
36
  WebMock.after_request do |request_signature, _response|
46
- if request_signature.uri.path == 'v2/applicants'
47
- expect(Rack::Utils.parse_nested_query(request_signature.body)).
48
- 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)
49
40
  end
50
41
  end
51
42
  end
@@ -57,26 +48,22 @@ describe Onfido::Applicant do
57
48
  end
58
49
 
59
50
  describe '#update' do
60
- let(:applicant_id) { '61f659cb-c90b-4067-808a-6136b5c01351' }
61
-
62
51
  it 'updates an applicant' do
63
52
  response = applicant.update(applicant_id, params)
53
+
64
54
  expect(response['id']).to eq(applicant_id)
65
55
  end
66
56
  end
67
57
 
68
58
  describe '#find' do
69
- let(:applicant_id) { '61f659cb-c90b-4067-808a-6136b5c01351' }
70
-
71
59
  it 'returns the applicant' do
72
60
  response = applicant.find(applicant_id)
61
+
73
62
  expect(response['id']).to eq(applicant_id)
74
63
  end
75
64
  end
76
65
 
77
66
  describe '#destroy' do
78
- let(:applicant_id) { '61f659cb-c90b-4067-808a-6136b5c01351' }
79
-
80
67
  it 'returns success code' do
81
68
  expect { applicant.destroy(applicant_id) }.not_to raise_error
82
69
  end
@@ -86,6 +73,7 @@ describe Onfido::Applicant do
86
73
  context 'with the default page and per page params' do
87
74
  it 'returns all the applicants' do
88
75
  response = applicant.all
76
+
89
77
  expect(response['applicants'].size).to eq(2)
90
78
  end
91
79
  end
@@ -93,6 +81,7 @@ describe Onfido::Applicant do
93
81
  context 'with specific range of results for a page' do
94
82
  it 'returns the specified applicants' do
95
83
  response = applicant.all(page: 1, per_page: 1)
84
+
96
85
  expect(response['applicants'].size).to eq(1)
97
86
  end
98
87
  end
@@ -100,24 +89,22 @@ describe Onfido::Applicant do
100
89
 
101
90
  describe '#restore' do
102
91
  context 'an applicant scheduled for deletion' do
103
- let(:applicant_id) { '61f659cb-c90b-4067-808a-6136b5c01351' }
104
-
105
92
  it 'returns nil' do
106
93
  expect(applicant.restore(applicant_id)).to be_nil
107
94
  end
108
95
  end
109
96
 
110
97
  context 'an applicant not scheduled for deletion' do
111
- let(:applicant_id) { 'a2fb9c62-ab10-4898-a8ec-342c4b552ad5' }
112
-
113
98
  it 'returns an error' do
114
- expect { applicant.restore(applicant_id) }.to raise_error { |error|
99
+ applicant_id = 'a2fb9c62-ab10-4898-a8ec-342c4b552ad5'
100
+
101
+ expect { applicant.restore(applicant_id) }.to raise_error do |error|
115
102
  expect(error).to be_a(Onfido::RequestError)
116
103
  expect(error.message).to eq('There was a validation error on this request')
117
104
  expect(error.fields).to eq(
118
- "Applicant a2fb9c62-ab10-4898-a8ec-342c4b552ad5 is not scheduled for deletion"
105
+ 'Applicant a2fb9c62-ab10-4898-a8ec-342c4b552ad5 is not scheduled for deletion'
119
106
  )
120
- }
107
+ end
121
108
  end
122
109
  end
123
110
  end
@@ -1,105 +1,64 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::Check do
2
- subject(:check) { described_class.new }
4
+ include_context 'fake onfido api'
5
+
6
+ subject(:check) { onfido.check }
7
+
3
8
  let(:applicant_id) { '61f659cb-c90b-4067-808a-6136b5c01351' }
9
+ let(:check_id) { '8546921-123123-123123' }
4
10
 
5
11
  describe '#create' do
6
- let(:params) { { type: 'express', reports: [{ name: 'identity' }] } }
7
-
8
12
  it 'creates a new check for an applicant' do
9
- response = check.create(applicant_id, params)
13
+ response = check.create(
14
+ applicant_id: applicant_id,
15
+ report_names: ['identity_enhanced']
16
+ )
10
17
  expect(response['id']).not_to be_nil
11
18
  end
12
19
  end
13
20
 
14
21
  describe '#find' do
15
- let(:check_id) { '8546921-123123-123123' }
16
-
17
22
  it 'returns an existing check for the applicant' do
18
- response = check.find(applicant_id, check_id)
19
- expect(response['id']).to eq(check_id)
20
- end
21
-
22
- it "returns unexpanded reports" do
23
- response = check.find(applicant_id, check_id)
24
- expect(response['reports'].first).to be_a(String)
25
- end
26
-
27
- it 'allows you to expand the reports' do
28
- response = check.find(applicant_id, check_id, expand: "reports")
29
- expect(response['reports'].first).to be_a(Hash)
30
- end
31
- end
32
-
33
- describe '#find_by_url' do
34
- let(:check_id) { '8546921-123123-123123' }
35
-
36
- context 'partial url' do
37
- let(:url) { "applicants/#{applicant_id}/checks/#{check_id}" }
38
-
39
- it 'returns an existing check for the applicant with the partial url' do
40
- response = check.find_by_url(url)
41
- expect(response['id']).to eq(check_id)
42
- end
43
-
44
- it "returns unexpanded reports" do
45
- response = check.find_by_url(url)
46
- expect(response['reports'].first).to be_a(String)
47
- end
23
+ response = check.find(check_id)
48
24
 
49
- it 'allows you to expand the reports' do
50
- response = check.find_by_url(url, expand: "reports")
51
- expect(response['reports'].first).to be_a(Hash)
52
- end
25
+ expect(response['id']).to eq(check_id)
53
26
  end
54
27
 
55
- context 'full url' do
56
- let(:url) do
57
- "https://api.onfido.com/v2/applicants/#{applicant_id}/checks/#{check_id}"
58
- end
28
+ it 'returns report_ids' do
29
+ response = check.find(check_id)
59
30
 
60
- it 'returns an existing check for the applicant with the partial url' do
61
- response = check.find_by_url(url)
62
- expect(response['id']).to eq(check_id)
63
- end
64
-
65
- it "returns unexpanded reports" do
66
- response = check.find_by_url(url)
67
- expect(response['reports'].first).to be_a(String)
68
- end
69
-
70
- it 'allows you to expand the reports' do
71
- response = check.find_by_url(url, expand: "reports")
72
- expect(response['reports'].first).to be_a(Hash)
73
- end
31
+ expect(response['report_ids'].first).to be_a(String)
74
32
  end
75
33
  end
76
34
 
77
35
  describe '#all' do
78
- let(:check_id) { '8546921-123123-123123' }
79
-
80
36
  context 'with the default page and per page params' do
81
37
  it 'returns all existing checks for the applicant' do
82
38
  response = check.all(applicant_id)
39
+
83
40
  expect(response['checks'].size).to eq(1)
84
41
  end
85
42
  end
86
43
 
87
- it "returns unexpanded reports" do
44
+ it 'returns report_ids' do
88
45
  response = check.all(applicant_id)
89
- expect(response['checks'].first['reports'].first).to be_a(String)
90
- end
91
46
 
92
- it 'allows you to expand the reports' do
93
- response = check.all(applicant_id, expand: "reports")
94
- expect(response['checks'].first['reports'].first).to be_a(Hash)
47
+ expect(response['checks'].first['report_ids'].first).to be_a(String)
95
48
  end
96
49
  end
97
50
 
98
- describe "#resume" do
99
- let(:check_id) { '8546921-123123-123123' }
100
-
51
+ describe '#resume' do
101
52
  it 'returns success response' do
102
53
  expect { check.resume(check_id) }.not_to raise_error
103
54
  end
104
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
105
64
  end