yoti_sandbox 1.0.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/README.md +8 -1
  4. data/lib/yoti_sandbox.rb +1 -0
  5. data/lib/yoti_sandbox/doc_scan.rb +25 -0
  6. data/lib/yoti_sandbox/doc_scan/client.rb +59 -0
  7. data/lib/yoti_sandbox/doc_scan/errors.rb +83 -0
  8. data/lib/yoti_sandbox/doc_scan/request/check/check.rb +115 -0
  9. data/lib/yoti_sandbox/doc_scan/request/check/document_authenticity_check.rb +29 -0
  10. data/lib/yoti_sandbox/doc_scan/request/check/document_check.rb +48 -0
  11. data/lib/yoti_sandbox/doc_scan/request/check/document_face_match_check.rb +29 -0
  12. data/lib/yoti_sandbox/doc_scan/request/check/document_text_data_check.rb +78 -0
  13. data/lib/yoti_sandbox/doc_scan/request/check/id_document_comparison_check.rb +56 -0
  14. data/lib/yoti_sandbox/doc_scan/request/check/liveness_check.rb +34 -0
  15. data/lib/yoti_sandbox/doc_scan/request/check/report/breakdown.rb +97 -0
  16. data/lib/yoti_sandbox/doc_scan/request/check/report/detail.rb +34 -0
  17. data/lib/yoti_sandbox/doc_scan/request/check/report/recommendation.rb +88 -0
  18. data/lib/yoti_sandbox/doc_scan/request/check/supplementary_document_text_data_check.rb +78 -0
  19. data/lib/yoti_sandbox/doc_scan/request/check/zoom_liveness_check.rb +36 -0
  20. data/lib/yoti_sandbox/doc_scan/request/check_reports.rb +182 -0
  21. data/lib/yoti_sandbox/doc_scan/request/document_filter.rb +77 -0
  22. data/lib/yoti_sandbox/doc_scan/request/response_config.rb +75 -0
  23. data/lib/yoti_sandbox/doc_scan/request/task/document_id_photo.rb +35 -0
  24. data/lib/yoti_sandbox/doc_scan/request/task/document_text_data_extraction_task.rb +170 -0
  25. data/lib/yoti_sandbox/doc_scan/request/task/supplementary_document_text_data_extraction_task.rb +152 -0
  26. data/lib/yoti_sandbox/doc_scan/request/task/text_data_extraction_reason.rb +78 -0
  27. data/lib/yoti_sandbox/doc_scan/request/task/text_data_extraction_recommendation.rb +86 -0
  28. data/lib/yoti_sandbox/doc_scan/request/task_results.rb +96 -0
  29. data/lib/yoti_sandbox/profile.rb +5 -0
  30. data/lib/yoti_sandbox/profile/age_verification.rb +7 -0
  31. data/lib/yoti_sandbox/profile/client.rb +8 -26
  32. data/lib/yoti_sandbox/profile/document_images.rb +69 -0
  33. data/lib/yoti_sandbox/profile/extra_data.rb +92 -0
  34. data/lib/yoti_sandbox/profile/third_party.rb +158 -0
  35. data/lib/yoti_sandbox/profile/token_request.rb +47 -6
  36. data/yoti_sandbox.gemspec +18 -5
  37. metadata +38 -18
  38. data/.github/ISSUE_TEMPLATE.md +0 -17
  39. data/.gitignore +0 -56
  40. data/CONTRIBUTING.md +0 -30
  41. data/Guardfile +0 -11
  42. data/Rakefile +0 -41
  43. data/rubocop.yml +0 -44
  44. data/yardstick.yml +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ee3b93e52cfe923f7311c9fb4e426c82f543d335d77986afce33a156020ebd49
4
- data.tar.gz: c364243f9462bce1e2d115b4d538353b34c764412109e5fdbde6587e90e07ad3
3
+ metadata.gz: 50664707d70da0ad9d28f183b68074c795f74ef59c05dbf4fbd1a0cef280d819
4
+ data.tar.gz: 6bae10a1f1675592f178d9ae1f47fdf3992196f1480a03e6a736b177a7638ea9
5
5
  SHA512:
6
- metadata.gz: 942ea35d3fb25a5d7b7cf9dc70c8bef7e61b15109295de0c56fabbb5ae15d8cf10fbb202a54b879cda88980ef940ceed2293fe0c0db3506a2318dce9c213f58d
7
- data.tar.gz: 965241d45bb97c05cd45c3d2a88c5ac843655ce427787c76b5a4b84c57fd4d9d2501f8a8f7a8317e7a55e81c780a768dd172e167e38623346acfb2522d20990d
6
+ metadata.gz: fe42559fa4b25d2a3f5d239471bfe86a0f1b59e00cb6c4bcb52cd895b52f2e2a4bf8087ce710d50be5514cf745e804204e245dac7f8bdf1dccf6157c9092efa1
7
+ data.tar.gz: 8de1edf888b5ede3604532ed62dd4210f7a55aa3de899c79062fefa980c37bd7d1ebf4045a40e9d879b5c87e83b3f2331d79985d7ecc447c1224a28f836afef7
data/Gemfile CHANGED
@@ -2,7 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  gem 'guard'
4
4
  gem 'guard-rspec'
5
- gem 'rubocop'
5
+ gem 'rubocop', '~> 1.1', require: false
6
6
  gem 'rubocop-performance'
7
7
 
8
8
  gemspec
data/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Yoti Ruby Sandbox SDK
2
2
 
3
+ [![Build Status](https://travis-ci.com/getyoti/yoti-ruby-sdk-sandbox.svg?branch=master)](https://travis-ci.com/getyoti/yoti-ruby-sdk-sandbox)
4
+ [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=getyoti%3Aruby-sandbox&metric=coverage)](https://sonarcloud.io/dashboard?id=getyoti%3Aruby-sandbox)
5
+ [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=getyoti%3Aruby-sandbox&metric=bugs)](https://sonarcloud.io/dashboard?id=getyoti%3Aruby-sandbox)
6
+ [![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=getyoti%3Aruby-sandbox&metric=code_smells)](https://sonarcloud.io/dashboard?id=getyoti%3Aruby-sandbox)
7
+ [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=getyoti%3Aruby-sandbox&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=getyoti%3Aruby-sandbox)
8
+
3
9
  This repository contains the tools you need to test your Yoti integration.
4
10
 
5
11
  ## Installing the Sandbox
@@ -42,4 +48,5 @@ end
42
48
 
43
49
  ## Examples
44
50
 
45
- - See [examples/profile](examples/profile) for a general example of how to use the Profile Sandbox in your tests.
51
+ - [Profile Sandbox](examples/profile)
52
+ - [Doc Scan Sandbox](examples/doc_scan)
@@ -1 +1,2 @@
1
1
  require_relative 'yoti_sandbox/profile'
2
+ require_relative 'yoti_sandbox/doc_scan'
@@ -0,0 +1,25 @@
1
+ require 'yoti'
2
+
3
+ require_relative 'doc_scan/client'
4
+ require_relative 'doc_scan/errors'
5
+ require_relative 'doc_scan/request/task_results'
6
+ require_relative 'doc_scan/request/check_reports'
7
+ require_relative 'doc_scan/request/response_config'
8
+ require_relative 'doc_scan/request/document_filter'
9
+ require_relative 'doc_scan/request/check/check'
10
+ require_relative 'doc_scan/request/check/document_check'
11
+ require_relative 'doc_scan/request/check/document_authenticity_check'
12
+ require_relative 'doc_scan/request/check/id_document_comparison_check'
13
+ require_relative 'doc_scan/request/check/document_face_match_check'
14
+ require_relative 'doc_scan/request/check/document_text_data_check'
15
+ require_relative 'doc_scan/request/check/supplementary_document_text_data_check'
16
+ require_relative 'doc_scan/request/check/liveness_check'
17
+ require_relative 'doc_scan/request/check/zoom_liveness_check'
18
+ require_relative 'doc_scan/request/check/report/breakdown'
19
+ require_relative 'doc_scan/request/check/report/recommendation'
20
+ require_relative 'doc_scan/request/check/report/detail'
21
+ require_relative 'doc_scan/request/task/document_text_data_extraction_task'
22
+ require_relative 'doc_scan/request/task/supplementary_document_text_data_extraction_task'
23
+ require_relative 'doc_scan/request/task/document_id_photo'
24
+ require_relative 'doc_scan/request/task/text_data_extraction_recommendation'
25
+ require_relative 'doc_scan/request/task/text_data_extraction_reason'
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module Sandbox
5
+ module DocScan
6
+ #
7
+ # Client for the Doc Scan sandbox service
8
+ #
9
+ class Client
10
+ #
11
+ # @param [String] base_url
12
+ #
13
+ def initialize(base_url: nil)
14
+ @base_url = base_url || "#{Yoti.configuration.api_url}/sandbox/idverify/v1"
15
+ end
16
+
17
+ #
18
+ # @param [String] session_id
19
+ # @param [Yoti::SandboxDocScan::Request::ResponseConfig] response_config
20
+ #
21
+ def configure_session_response(session_id, response_config)
22
+ request = Yoti::Request
23
+ .builder
24
+ .with_http_method('PUT')
25
+ .with_base_url(@base_url)
26
+ .with_endpoint("sessions/#{session_id}/response-config")
27
+ .with_query_param('sdkId', Yoti.configuration.client_sdk_id)
28
+ .with_payload(response_config)
29
+ .build
30
+
31
+ begin
32
+ request.execute
33
+ rescue Yoti::RequestError => e
34
+ raise Yoti::Sandbox::DocScan::Error.wrap(e)
35
+ end
36
+ end
37
+
38
+ #
39
+ # @param [Yoti::SandboxDocScan::Request::ResponseConfig] response_config
40
+ #
41
+ def configure_application_response(response_config)
42
+ request = Yoti::Request
43
+ .builder
44
+ .with_http_method('PUT')
45
+ .with_base_url(@base_url)
46
+ .with_endpoint("apps/#{Yoti.configuration.client_sdk_id}/response-config")
47
+ .with_payload(response_config)
48
+ .build
49
+
50
+ begin
51
+ request.execute
52
+ rescue Yoti::RequestError => e
53
+ raise Yoti::Sandbox::DocScan::Error.wrap(e)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,83 @@
1
+ require 'json'
2
+
3
+ module Yoti
4
+ module Sandbox
5
+ module DocScan
6
+ #
7
+ # Raises exceptions related to Doc Scan Sandbox API requests
8
+ #
9
+ class Error < RequestError
10
+ def initialize(msg = nil, response = nil)
11
+ super(msg, response)
12
+
13
+ @default_message = msg
14
+ end
15
+
16
+ def message
17
+ @message ||= format_message
18
+ end
19
+
20
+ #
21
+ # Wraps an existing error
22
+ #
23
+ # @param [Error] error
24
+ #
25
+ # @return [self]
26
+ #
27
+ def self.wrap(error)
28
+ new(error.message, error.response)
29
+ end
30
+
31
+ private
32
+
33
+ #
34
+ # Formats error message from response.
35
+ #
36
+ # @return [String]
37
+ #
38
+ def format_message
39
+ return @default_message if @response.nil? || @response['Content-Type'] != 'application/json'
40
+
41
+ json = JSON.parse(@response.body)
42
+ format_response(json) || @default_message
43
+ end
44
+
45
+ #
46
+ # Format JSON error response.
47
+ #
48
+ # @param [Hash] json
49
+ #
50
+ # @return [String, nil]
51
+ #
52
+ def format_response(json)
53
+ return nil if json['code'].nil? || json['message'].nil?
54
+
55
+ code_message = "#{json['code']} - #{json['message']}"
56
+
57
+ unless json['errors'].nil?
58
+ property_errors = format_property_errors(json['errors'])
59
+
60
+ return "#{code_message}: #{property_errors.compact.join(', ')}" if property_errors.count.positive?
61
+ end
62
+
63
+ code_message
64
+ end
65
+
66
+ #
67
+ # Format property errors.
68
+ #
69
+ # @param [Array<Hash>] errors
70
+ #
71
+ # @return [Array<String>]
72
+ #
73
+ def format_property_errors(errors)
74
+ errors
75
+ .map do |e|
76
+ "#{e['property']} \"#{e['message']}\"" if e['property'] && e['message']
77
+ end
78
+ .compact
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module Sandbox
5
+ module DocScan
6
+ module Request
7
+ class Check
8
+ #
9
+ # @param [CheckResult] result
10
+ #
11
+ def initialize(result)
12
+ raise(TypeError, "#{self.class} cannot be instantiated") if instance_of?(Check)
13
+
14
+ Validation.assert_is_a(CheckResult, result, 'result')
15
+ @result = result
16
+ end
17
+
18
+ def to_json(*_args)
19
+ as_json.to_json
20
+ end
21
+
22
+ def as_json(*_args)
23
+ {
24
+ result: @result.as_json
25
+ }
26
+ end
27
+ end
28
+
29
+ class CheckBuilder
30
+ def initialize
31
+ @breakdowns = []
32
+ end
33
+
34
+ #
35
+ # @param [Recommendation] recommendation
36
+ #
37
+ # @return [self]
38
+ #
39
+ def with_recommendation(recommendation)
40
+ Validation.assert_is_a(Recommendation, recommendation, 'recommendation')
41
+ @recommendation = recommendation
42
+ self
43
+ end
44
+
45
+ #
46
+ # @param [Breakdown] breakdown
47
+ #
48
+ # @return [self]
49
+ #
50
+ def with_breakdown(breakdown)
51
+ Validation.assert_is_a(Breakdown, breakdown, 'breakdown')
52
+ @breakdowns.push(breakdown)
53
+ self
54
+ end
55
+
56
+ #
57
+ # @param [Array<Breakdown>] breakdowns
58
+ #
59
+ # @return [self]
60
+ #
61
+ def with_breakdowns(breakdowns)
62
+ Validation.assert_is_a(Array, breakdowns, 'breakdown')
63
+ @breakdowns = breakdowns
64
+ self
65
+ end
66
+ end
67
+
68
+ class CheckResult
69
+ #
70
+ # @param [CheckReport] report
71
+ #
72
+ def initialize(report)
73
+ Validation.assert_is_a(CheckReport, report, 'report')
74
+ @report = report
75
+ end
76
+
77
+ def to_json(*_args)
78
+ as_json.to_json
79
+ end
80
+
81
+ def as_json(*_args)
82
+ {
83
+ report: @report.as_json
84
+ }
85
+ end
86
+ end
87
+
88
+ class CheckReport
89
+ #
90
+ # @param [Recommendation] recommendation
91
+ # @param [Breakdown] breakdowns
92
+ #
93
+ def initialize(recommendation, breakdowns)
94
+ Validation.assert_is_a(Recommendation, recommendation, 'recommendation')
95
+ @recommendation = recommendation
96
+
97
+ Validation.assert_is_a(Array, breakdowns, 'breakdowns')
98
+ @breakdowns = breakdowns
99
+ end
100
+
101
+ def to_json(*_args)
102
+ as_json.to_json
103
+ end
104
+
105
+ def as_json(*_args)
106
+ {
107
+ recommendation: @recommendation.as_json,
108
+ breakdown: @breakdowns.map(&:as_json)
109
+ }
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module Sandbox
5
+ module DocScan
6
+ module Request
7
+ class DocumentAuthenticityCheck < DocumentCheck
8
+ #
9
+ # @return [DocumentAuthenticityCheckBuilder]
10
+ #
11
+ def self.builder
12
+ DocumentAuthenticityCheckBuilder.new
13
+ end
14
+ end
15
+
16
+ class DocumentAuthenticityCheckBuilder < DocumentCheckBuilder
17
+ #
18
+ # @return [DocumentAuthenticityCheck]
19
+ #
20
+ def build
21
+ report = CheckReport.new(@recommendation, @breakdowns)
22
+ result = CheckResult.new(report)
23
+ DocumentAuthenticityCheck.new(result, @document_filter)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module Sandbox
5
+ module DocScan
6
+ module Request
7
+ class DocumentCheck < Check
8
+ #
9
+ # @param [CheckResult] result
10
+ # @param [DocumentFilter] document_filter
11
+ #
12
+ def initialize(result, document_filter)
13
+ raise(TypeError, "#{self.class} cannot be instantiated") if instance_of?(DocumentCheck)
14
+
15
+ super(result)
16
+
17
+ Validation.assert_is_a(DocumentFilter, document_filter, 'document_filter', true)
18
+ @document_filter = document_filter
19
+ end
20
+
21
+ def as_json(*_args)
22
+ json = super
23
+ json[:document_filter] = @document_filter.as_json unless @document_filter.nil?
24
+ json
25
+ end
26
+ end
27
+
28
+ class DocumentCheckBuilder < CheckBuilder
29
+ def initialize
30
+ raise(TypeError, "#{self.class} cannot be instantiated") if instance_of?(DocumentCheckBuilder)
31
+
32
+ super
33
+ end
34
+
35
+ #
36
+ # @param [DocumentFilter] document_filter
37
+ #
38
+ # @return [self]
39
+ #
40
+ def with_document_filter(document_filter)
41
+ @document_filter = document_filter
42
+ self
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module Sandbox
5
+ module DocScan
6
+ module Request
7
+ class DocumentFaceMatchCheck < DocumentCheck
8
+ #
9
+ # @return [DocumentFaceMatchCheckBuilder]
10
+ #
11
+ def self.builder
12
+ DocumentFaceMatchCheckBuilder.new
13
+ end
14
+ end
15
+
16
+ class DocumentFaceMatchCheckBuilder < DocumentCheckBuilder
17
+ #
18
+ # @return [DocumentFaceMatchCheck]
19
+ #
20
+ def build
21
+ report = CheckReport.new(@recommendation, @breakdowns)
22
+ result = CheckResult.new(report)
23
+ DocumentFaceMatchCheck.new(result, @document_filter)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Yoti
6
+ module Sandbox
7
+ module DocScan
8
+ module Request
9
+ class DocumentTextDataCheck < DocumentCheck
10
+ #
11
+ # @return [DocumentTextDataCheckBuilder]
12
+ #
13
+ def self.builder
14
+ DocumentTextDataCheckBuilder.new
15
+ end
16
+ end
17
+
18
+ class DocumentTextDataCheckResult < CheckResult
19
+ #
20
+ # @param [CheckReport] report
21
+ # @param [Hash,nil] document_fields
22
+ #
23
+ def initialize(report, document_fields)
24
+ super(report)
25
+
26
+ unless document_fields.nil?
27
+ Validation.assert_is_a(Hash, document_fields, 'document_fields')
28
+ document_fields.each { |_k, v| Validation.assert_respond_to(:to_json, v, 'document_fields value') }
29
+ end
30
+ @document_fields = document_fields
31
+ end
32
+
33
+ def as_json(*_args)
34
+ super.merge(
35
+ document_fields: @document_fields
36
+ ).compact
37
+ end
38
+ end
39
+
40
+ class DocumentTextDataCheckBuilder < DocumentCheckBuilder
41
+ #
42
+ # @param [String] key
43
+ # @param [#to_json] value
44
+ #
45
+ # @return [self]
46
+ #
47
+ def with_document_field(key, value)
48
+ Validation.assert_is_a(String, key, 'key')
49
+ Validation.assert_respond_to(:to_json, value, 'value')
50
+ @document_fields ||= {}
51
+ @document_fields[key] = value
52
+ self
53
+ end
54
+
55
+ #
56
+ # @param [Hash] document_fields
57
+ #
58
+ # @return [self]
59
+ #
60
+ def with_document_fields(document_fields)
61
+ Validation.assert_is_a(Hash, document_fields, 'document_fields')
62
+ @document_fields = document_fields
63
+ self
64
+ end
65
+
66
+ #
67
+ # @return [DocumentTextDataCheck]
68
+ #
69
+ def build
70
+ report = CheckReport.new(@recommendation, @breakdowns)
71
+ result = DocumentTextDataCheckResult.new(report, @document_fields)
72
+ DocumentTextDataCheck.new(result, @document_filter)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end