yoti_sandbox 1.1.0 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60f6434723e625e3bbf2148d1af084c6800f4a7e682305f3eb731325174ac75a
4
- data.tar.gz: 72205e69a037a63094fe043b5ce4fd5108f3f76ded8da6ef82ee96dc4865c066
3
+ metadata.gz: 3b95016e63022dda0044df80a5000d043a84cab4df3091ac4089c7e2dff44f5c
4
+ data.tar.gz: 9d613fdbcc9a92c06e311236e74c0f17d7c2753ea728c98ebe58ea9005141ca7
5
5
  SHA512:
6
- metadata.gz: 9a042d5227329c22a0e60af7e5c44e4875af419a05e1e1816992194ff49382b4e7a23cc10028ebaf9fbf63a3d7d7614b9d4f2f4992c3c810e4f1f244003e1166
7
- data.tar.gz: 0471a65f852b28fb64533842483587232d2051c7859a6c343e708b542999f1b119ec9b8bb7dc3e2aff450a2545f419e2642cdaf369212e2ebfbb70a8a6c12280
6
+ metadata.gz: bd050c465f05d84b43d1b95155618467a1fa6dd8e7a2ea630c35822b87321aa2331bcc31343b202d98d6c5c9ce5b9b06f849541e521b40786a6a02c32b8ef4f3
7
+ data.tar.gz: 8f6eca8ad30da0dcfaab8f9909703ce12fa465e1fe43e4958464f53a47ee00719e33009152cd8db9054492644a2d63ab2f59fa631b4b36ada06f800a3a6aeac2
@@ -0,0 +1,13 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ open-pull-requests-limit: 3
8
+ target-branch: development
9
+ reviewers:
10
+ - echarrod
11
+ - davidgrayston
12
+ assignees:
13
+ - davidgrayston
@@ -1,6 +1,7 @@
1
1
  require 'yoti'
2
2
 
3
3
  require_relative 'doc_scan/client'
4
+ require_relative 'doc_scan/errors'
4
5
  require_relative 'doc_scan/request/task_results'
5
6
  require_relative 'doc_scan/request/check_reports'
6
7
  require_relative 'doc_scan/request/response_config'
@@ -19,29 +19,39 @@ module Yoti
19
19
  # @param [Yoti::SandboxDocScan::Request::ResponseConfig] response_config
20
20
  #
21
21
  def configure_session_response(session_id, response_config)
22
- 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
- .execute
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
31
36
  end
32
37
 
33
38
  #
34
39
  # @param [Yoti::SandboxDocScan::Request::ResponseConfig] response_config
35
40
  #
36
41
  def configure_application_response(response_config)
37
- Yoti::Request
38
- .builder
39
- .with_http_method('PUT')
40
- .with_base_url(@base_url)
41
- .with_endpoint("apps/#{Yoti.configuration.client_sdk_id}/response-config")
42
- .with_payload(response_config)
43
- .build
44
- .execute
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
45
55
  end
46
56
  end
47
57
  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
@@ -5,3 +5,6 @@ require_relative 'profile/anchor'
5
5
  require_relative 'profile/attribute'
6
6
  require_relative 'profile/client'
7
7
  require_relative 'profile/token_request'
8
+ require_relative 'profile/extra_data'
9
+ require_relative 'profile/third_party'
10
+ require_relative 'profile/document_images'
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module Sandbox
5
+ module Profile
6
+ class DocumentImages
7
+ #
8
+ # @param [Array<Image>] images
9
+ #
10
+ def initialize(images)
11
+ Validation.assert_is_a(Array, images, 'images')
12
+ @images = images
13
+ end
14
+
15
+ #
16
+ # @return [DocumentImagesBuilder]
17
+ #
18
+ def self.builder
19
+ DocumentImagesBuilder.new
20
+ end
21
+
22
+ #
23
+ # @return [String]
24
+ #
25
+ def value
26
+ @images
27
+ .map(&:base64_content)
28
+ .join('&')
29
+ end
30
+ end
31
+
32
+ #
33
+ # Builder for {DocumentImages}
34
+ #
35
+ class DocumentImagesBuilder
36
+ def initialize
37
+ @images = []
38
+ end
39
+
40
+ #
41
+ # @param [bin] content
42
+ #
43
+ # @return [self]
44
+ #
45
+ def with_jpeg_content(content)
46
+ @images << Yoti::ImageJpeg.new(content)
47
+ self
48
+ end
49
+
50
+ #
51
+ # @param [bin] content
52
+ #
53
+ # @return [self]
54
+ #
55
+ def with_png_content(content)
56
+ @images << Yoti::ImagePng.new(content)
57
+ self
58
+ end
59
+
60
+ #
61
+ # @return [DocumentImages]
62
+ #
63
+ def build
64
+ DocumentImages.new(@images)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yoti
4
+ module Sandbox
5
+ module Profile
6
+ class ExtraData
7
+ def initialize(data_entries)
8
+ @data_entries = data_entries
9
+ end
10
+
11
+ #
12
+ # @return [Hash]
13
+ #
14
+ def as_json(*_args)
15
+ {
16
+ data_entry: @data_entries
17
+ }
18
+ end
19
+
20
+ #
21
+ # @return [String]
22
+ #
23
+ def to_json(*args)
24
+ as_json.to_json(*args)
25
+ end
26
+
27
+ #
28
+ # @return [ExtraDataBuilder]
29
+ #
30
+ def self.builder
31
+ ExtraDataBuilder.new
32
+ end
33
+ end
34
+
35
+ #
36
+ # Base DataEntry
37
+ #
38
+ class DataEntry
39
+ #
40
+ # @param [String] type
41
+ # @param [#as_json] value
42
+ #
43
+ def initialize(type, value)
44
+ raise(TypeError, "#{self.class} cannot be instantiated") if self.class == DataEntry
45
+
46
+ Validation.assert_is_a(String, type, 'type')
47
+ @type = type
48
+
49
+ Validation.assert_respond_to(:as_json, value, 'value')
50
+ @value = value
51
+ end
52
+
53
+ def to_json(*_args)
54
+ as_json.to_json
55
+ end
56
+
57
+ def as_json(*_args)
58
+ {
59
+ type: @type,
60
+ value: @value.as_json
61
+ }
62
+ end
63
+ end
64
+
65
+ #
66
+ # Builder for ExtraData
67
+ #
68
+ class ExtraDataBuilder
69
+ def initialize
70
+ @data_entries = []
71
+ end
72
+
73
+ #
74
+ # @param [DataEntry] data_entry
75
+ #
76
+ # @return [self]
77
+ #
78
+ def with_data_entry(data_entry)
79
+ @data_entries << data_entry
80
+ self
81
+ end
82
+
83
+ #
84
+ # @return [ExtraData]
85
+ #
86
+ def build
87
+ ExtraData.new(@data_entries)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+
5
+ module Yoti
6
+ module Sandbox
7
+ module Profile
8
+ #
9
+ # Provides attribute issuance details data entry
10
+ #
11
+ class AttributeIssuanceDetails < DataEntry
12
+ #
13
+ # @param [AttributeIssuanceDetailsValue] value
14
+ #
15
+ def initialize(value)
16
+ Validation.assert_is_a(AttributeIssuanceDetailsValue, value, 'value')
17
+ super('THIRD_PARTY_ATTRIBUTE', value)
18
+ end
19
+
20
+ #
21
+ # @return [AttributeIssuanceDetailsBuilder]
22
+ #
23
+ def self.builder
24
+ AttributeIssuanceDetailsBuilder.new
25
+ end
26
+ end
27
+
28
+ #
29
+ # Builder for AttributeIssuanceDetails
30
+ #
31
+ class AttributeIssuanceDetailsBuilder
32
+ def initialize
33
+ @definitions = []
34
+ end
35
+
36
+ #
37
+ # @param [String] issuance_token
38
+ #
39
+ # @return [self]
40
+ #
41
+ def with_issuance_token(issuance_token)
42
+ Validation.assert_is_a(String, issuance_token, 'issuance_token')
43
+ @issuance_token = issuance_token
44
+ self
45
+ end
46
+
47
+ #
48
+ # @param [Time, DateTime] expiry_date
49
+ #
50
+ # @return [self]
51
+ #
52
+ def with_expiry_date(expiry_date)
53
+ Validation.assert_respond_to(:to_time, expiry_date, 'expiry_date')
54
+ @expiry_date = expiry_date
55
+ self
56
+ end
57
+
58
+ #
59
+ # @param [String] definition
60
+ #
61
+ # @return [self]
62
+ #
63
+ def with_definition(definition)
64
+ @definitions << AttributeDefinition.new(definition)
65
+ self
66
+ end
67
+
68
+ #
69
+ # @return [AttributeIssuanceDetails]
70
+ #
71
+ def build
72
+ issuing_attributes = IssuingAttributes.new(@expiry_date, @definitions)
73
+ value = AttributeIssuanceDetailsValue.new(@issuance_token, issuing_attributes)
74
+ AttributeIssuanceDetails.new(value)
75
+ end
76
+ end
77
+
78
+ #
79
+ # Provides attribute issuance details value consisting of token and attributes.
80
+ #
81
+ class AttributeIssuanceDetailsValue
82
+ #
83
+ # @param [String] issuance_token
84
+ # @param [IssuingAttributes] issuing_attributes
85
+ #
86
+ def initialize(issuance_token, issuing_attributes)
87
+ Validation.assert_is_a(String, issuance_token, 'issuance_token')
88
+ @issuance_token = issuance_token
89
+
90
+ Validation.assert_is_a(IssuingAttributes, issuing_attributes, 'issuing_attributes')
91
+ @issuing_attributes = issuing_attributes
92
+ end
93
+
94
+ def to_json(*_args)
95
+ as_json.to_json
96
+ end
97
+
98
+ def as_json(*_args)
99
+ {
100
+ issuance_token: @issuance_token,
101
+ issuing_attributes: @issuing_attributes
102
+ }
103
+ end
104
+ end
105
+
106
+ #
107
+ # Provides issuing attributes, consisting of expiry date and list of definitions.
108
+ #
109
+ class IssuingAttributes
110
+ #
111
+ # @param [Time, DateTime] expiry_date
112
+ # @param [Array<AttributeDefinition>] definitions
113
+ #
114
+ def initialize(expiry_date, definitions)
115
+ Validation.assert_respond_to(:to_time, expiry_date, 'expiry_date')
116
+ @expiry_date = expiry_date
117
+
118
+ Validation.assert_is_a(Array, definitions, 'definitions')
119
+ @definitions = definitions
120
+ end
121
+
122
+ def to_json(*_args)
123
+ as_json.to_json
124
+ end
125
+
126
+ def as_json(*_args)
127
+ json = {}
128
+ json[:expiry_date] = @expiry_date.to_time.utc.strftime('%FT%T.%3NZ') unless @expiry_date.nil?
129
+ json[:definitions] = @definitions.map(&:as_json)
130
+ json
131
+ end
132
+ end
133
+
134
+ #
135
+ # Provides a single attribute definition.
136
+ #
137
+ class AttributeDefinition
138
+ #
139
+ # @param [String] name
140
+ #
141
+ def initialize(name)
142
+ Validation.assert_is_a(String, name, 'name')
143
+ @name = name
144
+ end
145
+
146
+ def to_json(*_args)
147
+ as_json.to_json
148
+ end
149
+
150
+ def as_json(*_args)
151
+ {
152
+ name: @name
153
+ }
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
@@ -14,12 +14,19 @@ module Yoti
14
14
  #
15
15
  class TokenRequest
16
16
  #
17
- # @param [String] remember_me_id
17
+ # @param [String, nil] remember_me_id
18
18
  # @param [Array<Attribute>] attributes
19
+ # @param [ExtraData, nil] extra_data
19
20
  #
20
- def initialize(remember_me_id, attributes)
21
+ def initialize(remember_me_id, attributes, extra_data = nil)
22
+ Validation.assert_is_a(String, remember_me_id, 'remember_me_id', true)
21
23
  @remember_me_id = remember_me_id
24
+
25
+ Validation.assert_is_a(Array, attributes, 'attributes')
22
26
  @attributes = attributes
27
+
28
+ Validation.assert_is_a(ExtraData, extra_data, 'extra_data', true)
29
+ @extra_data = extra_data
23
30
  end
24
31
 
25
32
  #
@@ -35,8 +42,9 @@ module Yoti
35
42
  def as_json(*_args)
36
43
  {
37
44
  remember_me_id: @remember_me_id,
38
- profile_attributes: @attributes.map(&:as_json)
39
- }
45
+ profile_attributes: @attributes.map(&:as_json),
46
+ extra_data: @extra_data
47
+ }.compact
40
48
  end
41
49
 
42
50
  #
@@ -52,7 +60,6 @@ module Yoti
52
60
  #
53
61
  class TokenRequestBuilder
54
62
  def initialize
55
- @remember_me_id = ''
56
63
  @attributes = []
57
64
  end
58
65
 
@@ -290,11 +297,38 @@ module Yoti
290
297
  )
291
298
  end
292
299
 
300
+ #
301
+ # @param [DocumentImages] document_images
302
+ # @param [Array<Anchor>] anchors
303
+ #
304
+ # @return [self]
305
+ #
306
+ def with_document_images(document_images, anchors: [])
307
+ with_attribute(
308
+ create_attribute(
309
+ name: Yoti::Attribute::DOCUMENT_IMAGES,
310
+ value: document_images.value,
311
+ anchors: anchors
312
+ )
313
+ )
314
+ end
315
+
316
+ #
317
+ # @param [ExtraData] extra_data
318
+ #
319
+ # @return [self]
320
+ #
321
+ def with_extra_data(extra_data)
322
+ Validation.assert_is_a(ExtraData, extra_data, 'extra_data')
323
+ @extra_data = extra_data
324
+ self
325
+ end
326
+
293
327
  #
294
328
  # @return [TokenRequest]
295
329
  #
296
330
  def build
297
- TokenRequest.new(@remember_me_id, @attributes)
331
+ TokenRequest.new(@remember_me_id, @attributes, @extra_data)
298
332
  end
299
333
 
300
334
  private
@@ -42,7 +42,3 @@ Style/MutableConstant:
42
42
 
43
43
  Layout/LineLength:
44
44
  Enabled: false
45
-
46
- Layout/MultilineMethodCallIndentation:
47
- Exclude:
48
- - examples/**/*.rb
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = 'yoti_sandbox'
6
- spec.version = '1.1.0'
6
+ spec.version = '1.2.0'
7
7
  spec.authors = ['Yoti']
8
8
  spec.email = ['websdk@yoti.com']
9
9
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yoti_sandbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoti
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-18 00:00:00.000000000 Z
11
+ date: 2020-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yoti
@@ -132,6 +132,7 @@ extensions: []
132
132
  extra_rdoc_files: []
133
133
  files:
134
134
  - ".github/ISSUE_TEMPLATE.md"
135
+ - ".github/dependabot.yml"
135
136
  - ".gitignore"
136
137
  - CONTRIBUTING.md
137
138
  - Gemfile
@@ -142,6 +143,7 @@ files:
142
143
  - lib/yoti_sandbox.rb
143
144
  - lib/yoti_sandbox/doc_scan.rb
144
145
  - lib/yoti_sandbox/doc_scan/client.rb
146
+ - lib/yoti_sandbox/doc_scan/errors.rb
145
147
  - lib/yoti_sandbox/doc_scan/request/check/check.rb
146
148
  - lib/yoti_sandbox/doc_scan/request/check/document_authenticity_check.rb
147
149
  - lib/yoti_sandbox/doc_scan/request/check/document_check.rb
@@ -162,6 +164,9 @@ files:
162
164
  - lib/yoti_sandbox/profile/anchor.rb
163
165
  - lib/yoti_sandbox/profile/attribute.rb
164
166
  - lib/yoti_sandbox/profile/client.rb
167
+ - lib/yoti_sandbox/profile/document_images.rb
168
+ - lib/yoti_sandbox/profile/extra_data.rb
169
+ - lib/yoti_sandbox/profile/third_party.rb
165
170
  - lib/yoti_sandbox/profile/token_request.rb
166
171
  - rubocop.yml
167
172
  - yardstick.yml