smile-identity-core 1.2.0 → 2.0.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.
@@ -1,50 +1,47 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'tempfile'
3
5
  require 'base64'
4
6
  require 'openssl'
5
7
  require 'uri'
6
-
7
8
  require 'typhoeus'
8
9
  require 'zip'
9
10
 
10
11
  module SmileIdentityCore
12
+ # Allows Identity verifications of ids with images
11
13
  class WebApi
12
-
13
14
  def initialize(partner_id, default_callback, api_key, sid_server)
14
15
  @partner_id = partner_id.to_s
15
16
  @callback_url = default_callback
16
17
  @api_key = api_key
17
-
18
18
  @sid_server = sid_server
19
- if !(sid_server =~ URI::regexp)
20
- sid_server_mapping = {
21
- 0 => 'https://testapi.smileidentity.com/v1',
22
- 1 => 'https://api.smileidentity.com/v1',
23
- }
24
- @url = sid_server_mapping[sid_server.to_i]
25
- else
26
- @url = sid_server
27
- end
19
+ @url = if sid_server !~ URI::DEFAULT_PARSER.make_regexp
20
+ SmileIdentityCore::ENV::SID_SERVER_MAPPING[sid_server.to_s]
21
+ else
22
+ sid_server
23
+ end
28
24
  end
29
25
 
30
26
  def submit_job(partner_params, images, id_info, options)
31
-
32
27
  self.partner_params = symbolize_keys partner_params
33
- if @partner_params[:job_type].to_i == 5
28
+ if @partner_params[:job_type].to_i == JobType::ENHANCED_KYC
34
29
  return SmileIdentityCore::IDApi.new(@partner_id, @api_key, @sid_server).submit_job(partner_params, id_info)
35
30
  end
36
31
 
32
+ if @partner_params[:job_type].to_i == JobType::BUSINESS_VERIFICATION
33
+ return SmileIdentityCore::BusinessVerification.new(@partner_id, @api_key, @sid_server).submit_job(
34
+ partner_params, id_info
35
+ )
36
+ end
37
+
37
38
  self.images = images
38
39
  self.id_info = symbolize_keys id_info
39
40
  self.options = symbolize_keys options
40
41
 
41
- if @options[:optional_callback] && @options[:optional_callback].length > 0
42
- @callback_url = @options[:optional_callback]
43
- end
42
+ @callback_url = @options[:optional_callback] if @options[:optional_callback]&.length&.positive?
44
43
 
45
- if @partner_params[:job_type].to_i == 1
46
- validate_enroll_with_id
47
- end
44
+ validate_enroll_with_id if @partner_params[:job_type].to_i == 1
48
45
 
49
46
  validate_return_data
50
47
 
@@ -59,21 +56,18 @@ module SmileIdentityCore
59
56
  job_id = partner_params[:job_id]
60
57
 
61
58
  utilities = SmileIdentityCore::Utilities.new(@partner_id, @api_key, @sid_server)
62
- utilities.get_job_status(user_id, job_id, options);
59
+ utilities.get_job_status(user_id, job_id, options)
63
60
  end
64
61
 
65
62
  def partner_params=(partner_params)
66
- if partner_params == nil
67
- raise ArgumentError, 'Please ensure that you send through partner params'
68
- end
63
+ raise ArgumentError, 'Please ensure that you send through partner params' if partner_params.nil?
69
64
 
70
- if !partner_params.is_a?(Hash)
71
- raise ArgumentError, 'Partner params needs to be a hash'
72
- end
65
+ raise ArgumentError, 'Partner params needs to be a hash' unless partner_params.is_a?(Hash)
73
66
 
74
- [:user_id, :job_id, :job_type].each do |key|
75
- unless partner_params[key] && !partner_params[key].nil? && !(partner_params[key].empty? if partner_params[key].is_a?(String))
76
- raise ArgumentError, "Please make sure that #{key} is included in the partner params"
67
+ %i[user_id job_id job_type].each do |key|
68
+ if partner_params[key].to_s.empty?
69
+ raise ArgumentError,
70
+ "Please make sure that #{key} is included in the partner params"
77
71
  end
78
72
  end
79
73
 
@@ -81,46 +75,30 @@ module SmileIdentityCore
81
75
  end
82
76
 
83
77
  def images=(images)
84
- if images == nil
85
- raise ArgumentError, 'Please ensure that you send through image details'
86
- end
78
+ raise ArgumentError, 'Please ensure that you send through image details' if images.nil?
87
79
 
88
- if !images.is_a?(Array)
89
- raise ArgumentError, 'Image details needs to be an array'
90
- end
80
+ raise ArgumentError, 'Image details needs to be an array' unless images.is_a?(Array)
91
81
 
92
82
  # all job types require atleast a selfie
93
- if images.length == 0 || images.none? {|h| h[:image_type_id] == 0 || h[:image_type_id] == 2 }
83
+ if images.length.zero? || images.none? { |h| (h[:image_type_id]).zero? || h[:image_type_id] == 2 }
94
84
  raise ArgumentError, 'You need to send through at least one selfie image'
95
85
  end
96
86
 
97
87
  @images = images.map { |image| symbolize_keys image }
98
-
99
88
  end
100
89
 
101
90
  def id_info=(id_info)
102
-
103
- updated_id_info = id_info
104
-
105
- if updated_id_info.nil?
106
- updated_id_info = {}
107
- end
91
+ updated_id_info = id_info.nil? ? {} : id_info
108
92
 
109
93
  # if it doesnt exist, set it false
110
- if(!updated_id_info.key?(:entered) || id_info[:entered].empty?)
111
- updated_id_info[:entered] = "false"
112
- end
94
+ updated_id_info[:entered] = 'false' if !updated_id_info.key?(:entered) || id_info[:entered].empty?
113
95
 
114
96
  # if it's a boolean
115
- if(!!updated_id_info[:entered] == updated_id_info[:entered])
116
- updated_id_info[:entered] = id_info[:entered].to_s
117
- end
97
+ updated_id_info[:entered] = id_info[:entered].to_s if !updated_id_info[:entered].nil? == updated_id_info[:entered]
118
98
 
119
99
  if updated_id_info[:entered] && updated_id_info[:entered] == 'true'
120
- [:country, :id_type, :id_number].each do |key|
121
- unless id_info[key] && !id_info[key].nil? && !id_info[key].empty?
122
- raise ArgumentError, "Please make sure that #{key.to_s} is included in the id_info"
123
- end
100
+ %i[country id_type id_number].each do |key|
101
+ raise ArgumentError, "Please make sure that #{key} is included in the id_info" if id_info[key].to_s.empty?
124
102
  end
125
103
  end
126
104
 
@@ -134,7 +112,6 @@ module SmileIdentityCore
134
112
  updated_options[:return_job_status] = check_boolean(:return_job_status, options)
135
113
  updated_options[:return_image_links] = check_boolean(:return_image_links, options)
136
114
  updated_options[:return_history] = check_boolean(:return_history, options)
137
- @use_new_signature = updated_options.fetch(:signature, false)
138
115
 
139
116
  @options = updated_options
140
117
  end
@@ -157,7 +134,13 @@ module SmileIdentityCore
157
134
  private
158
135
 
159
136
  def request_web_token(request_params)
160
- request_params.merge!({ partner_id: @partner_id }).merge!(request_security)
137
+ request_params
138
+ .merge(SmileIdentityCore::Signature.new(@partner_id, @api_key).generate_signature(Time.now.to_s))
139
+ .merge!(
140
+ { partner_id: @partner_id,
141
+ source_sdk: SmileIdentityCore::SOURCE_SDK,
142
+ source_sdk_version: SmileIdentityCore::VERSION }
143
+ )
161
144
  url = "#{@url}/token"
162
145
 
163
146
  response = Typhoeus.post(
@@ -171,8 +154,8 @@ module SmileIdentityCore
171
154
  raise "#{response.code}: #{response.body}"
172
155
  end
173
156
 
174
- def symbolize_keys params
175
- (params.is_a?(Hash)) ? Hash[params.map{ |k, v| [k.to_sym, v] }] : params
157
+ def symbolize_keys(params)
158
+ params.is_a?(Hash) ? params.transform_keys(&:to_sym) : params
176
159
  end
177
160
 
178
161
  def validate_return_data
@@ -182,25 +165,21 @@ module SmileIdentityCore
182
165
  end
183
166
 
184
167
  def validate_enroll_with_id
185
- if(((@images.none? {|h| h[:image_type_id] == 1 || h[:image_type_id] == 3 }) && @id_info[:entered] != 'true'))
168
+ if (@images.none? { |h| h[:image_type_id] == 1 || h[:image_type_id] == 3 }) && @id_info[:entered] != 'true'
186
169
  raise ArgumentError, 'You are attempting to complete a job type 1 without providing an id card image or id info'
187
170
  end
188
171
  end
189
172
 
190
173
  def check_boolean(key, obj)
191
- if (!obj || !obj[key])
192
- return false
193
- end
174
+ return false if !obj || !obj[key]
194
175
 
195
- if !!obj[key] != obj[key]
196
- raise ArgumentError, "#{key} needs to be a boolean"
197
- end
176
+ raise ArgumentError, "#{key} needs to be a boolean" if !obj[key].nil? != obj[key]
198
177
 
199
178
  obj[key]
200
179
  end
201
180
 
202
181
  def check_string(key, obj)
203
- if (!obj || !obj[key])
182
+ if !obj || !obj[key]
204
183
  ''
205
184
  else
206
185
  obj[key]
@@ -217,104 +196,84 @@ module SmileIdentityCore
217
196
  keys.select { |key| blank?(obj, key) }
218
197
  end
219
198
 
220
- def request_security(use_new_signature: true)
221
- if use_new_signature
222
- @timestamp = Time.now.to_s
223
- {
224
- signature: SmileIdentityCore::Signature.new(@partner_id, @api_key).generate_signature(@timestamp)[:signature],
225
- timestamp: @timestamp,
226
- }
227
- else
228
- @timestamp = Time.now.to_i
229
- {
230
- sec_key: SmileIdentityCore::Signature.new(@partner_id, @api_key).generate_sec_key(@timestamp)[:sec_key],
231
- timestamp: @timestamp,
232
- }
233
- end
234
- end
235
-
236
199
  def configure_prep_upload_json
237
- request_security(use_new_signature: @use_new_signature).merge(
200
+ SmileIdentityCore::Signature.new(@partner_id, @api_key).generate_signature(Time.now.to_s).merge(
238
201
  file_name: 'selfie.zip',
239
202
  smile_client_id: @partner_id,
240
203
  partner_params: @partner_params,
241
204
  model_parameters: {}, # what is this for
242
- callback_url: @callback_url
205
+ callback_url: @callback_url,
206
+ source_sdk: SmileIdentityCore::SOURCE_SDK,
207
+ source_sdk_version: SmileIdentityCore::VERSION
243
208
  ).to_json
244
209
  end
245
210
 
246
211
  def setup_requests
247
-
248
212
  url = "#{@url}/upload"
249
213
  request = Typhoeus::Request.new(
250
214
  url,
251
215
  method: 'POST',
252
- headers: {'Content-Type'=> "application/json"},
216
+ headers: { 'Content-Type' => 'application/json' },
253
217
  body: configure_prep_upload_json
254
218
  )
255
219
 
256
220
  request.on_complete do |response|
257
221
  if response.success?
258
222
  # TODO: if/when we sign these responses, verify the signature here and raise if it's off.
259
- # if updated_options[:signature]
260
223
  # SmileIdentityCore::Signature.new(@partner_id, @api_key).generate_signature(@timestamp)
261
- # else
262
- # SmileIdentityCore::Signature.new(@partner_id, @api_key).generate_sec_key(@timestamp)
263
- # end
264
224
 
265
225
  prep_upload_response = JSON.parse(response.body)
266
226
  info_json = configure_info_json(prep_upload_response)
267
227
 
268
- file_upload_response = upload_file(prep_upload_response['upload_url'], info_json, prep_upload_response['smile_job_id'])
228
+ file_upload_response = upload_file(prep_upload_response['upload_url'], info_json,
229
+ prep_upload_response['smile_job_id'])
269
230
  return file_upload_response
270
-
271
- elsif response.timed_out?
272
- raise "#{response.code}: #{response.body}"
273
- elsif response.code == 0
274
- # Could not get an http response, something's wrong.
275
- raise "#{response.code}: #{response.body}"
276
- else
277
- # Received a non-successful http response.
278
- raise "#{response.code}: #{response.body}"
279
231
  end
232
+
233
+ raise "#{response.code}: #{response.body}"
280
234
  end
281
235
  request.run
282
236
  end
283
237
 
284
238
  def configure_info_json(server_information)
285
- info = {
239
+ {
286
240
  "package_information": {
287
- "apiVersion": SmileIdentityCore.version_as_hash,
288
- "language": "ruby"
241
+ "apiVersion": {
242
+ "buildNumber": 0,
243
+ "majorVersion": 2,
244
+ "minorVersion": 0
245
+ },
246
+ "language": 'ruby'
289
247
  },
290
- "misc_information": request_security(use_new_signature: @use_new_signature).merge(
291
- "retry": "false",
292
- "partner_params": @partner_params,
293
- "file_name": "selfie.zip", # figure out what to do here
294
- "smile_client_id": @partner_id,
295
- "callback_url": @callback_url,
296
- "userData": { # TO ASK what goes here
297
- "isVerifiedProcess": false,
298
- "name": "",
299
- "fbUserID": "",
300
- "firstName": "Bill",
301
- "lastName": "",
302
- "gender": "",
303
- "email": "",
304
- "phone": "",
305
- "countryCode": "+",
306
- "countryName": ""
307
- }
308
- ),
248
+ "misc_information": SmileIdentityCore::Signature.new(@partner_id, @api_key)
249
+ .generate_signature(Time.now.to_s)
250
+ .merge(
251
+ "retry": 'false',
252
+ "partner_params": @partner_params,
253
+ "file_name": 'selfie.zip', # figure out what to do here
254
+ "smile_client_id": @partner_id,
255
+ "callback_url": @callback_url,
256
+ "userData": { # TO ASK what goes here
257
+ "isVerifiedProcess": false,
258
+ "name": '',
259
+ "fbUserID": '',
260
+ "firstName": 'Bill',
261
+ "lastName": '',
262
+ "gender": '',
263
+ "email": '',
264
+ "phone": '',
265
+ "countryCode": '+',
266
+ "countryName": ''
267
+ }
268
+ ),
309
269
  "id_info": @id_info,
310
270
  "images": configure_image_payload,
311
271
  "server_information": server_information
312
272
  }
313
- info
314
273
  end
315
274
 
316
275
  def configure_image_payload
317
- @images.map { |i|
276
+ @images.map do |i|
318
277
  if image_file?(i[:image_type_id])
319
278
  {
320
279
  image_type_id: i[:image_type_id],
@@ -328,11 +287,11 @@ module SmileIdentityCore
328
287
  file_name: ''
329
288
  }
330
289
  end
331
- }
290
+ end
332
291
  end
333
292
 
334
293
  def image_file?(type)
335
- type.to_i == 0 || type.to_i == 1
294
+ type.to_i.zero? || type.to_i == 1
336
295
  end
337
296
 
338
297
  def zip_up_file(info_json)
@@ -341,9 +300,9 @@ module SmileIdentityCore
341
300
  zos.put_next_entry('info.json')
342
301
  zos.puts JSON.pretty_generate(info_json)
343
302
 
344
- if @images.length > 0
303
+ if @images.length.positive?
345
304
  @images.each do |img|
346
- if img[:image_type_id] == 0 || img[:image_type_id] == 1
305
+ if (img[:image_type_id]).zero? || img[:image_type_id] == 1
347
306
  zos.put_next_entry(File.basename(img[:image]))
348
307
  zos.print IO.read(img[:image])
349
308
  end
@@ -353,43 +312,31 @@ module SmileIdentityCore
353
312
  end
354
313
 
355
314
  def upload_file(url, info_json, smile_job_id)
356
-
357
315
  file = zip_up_file(info_json)
358
316
  file.rewind
359
317
 
360
318
  request = Typhoeus::Request.new(
361
319
  url,
362
320
  method: 'PUT',
363
- headers: {'Content-Type'=> "application/zip"},
364
- body: file.read,
321
+ headers: { 'Content-Type' => 'application/zip' },
322
+ body: file.read
365
323
  )
366
324
 
367
325
  request.on_complete do |response|
368
- if response.success?
369
- if @options[:return_job_status]
370
- @utilies_connection = SmileIdentityCore::Utilities.new(@partner_id, @api_key, @sid_server)
371
- job_response = query_job_status
372
- job_response["success"] = true
373
- job_response["smile_job_id"] = smile_job_id
374
- return job_response
375
- else
376
- return {success: true, smile_job_id: smile_job_id}.to_json
377
- end
378
- elsif response.timed_out?
379
- raise " #{response.code.to_s}: #{response.body}"
380
- elsif response.code == 0
381
- # Could not get an http response, something's wrong.
382
- raise " #{response.code.to_s}: #{response.body}"
383
- else
384
- # Received a non-successful http response.
385
- raise " #{response.code.to_s}: #{response.body}"
386
- end
326
+ raise " #{response.code}: #{response.body}" unless response.success?
327
+
328
+ return { success: true, smile_job_id: smile_job_id }.to_json unless @options[:return_job_status]
329
+
330
+ @utilies_connection = SmileIdentityCore::Utilities.new(@partner_id, @api_key, @sid_server)
331
+ job_response = query_job_status
332
+ job_response['success'] = true
333
+ job_response['smile_job_id'] = smile_job_id
334
+ return job_response
387
335
  end
388
336
  request.run
389
-
390
337
  end
391
338
 
392
- def query_job_status(counter=0)
339
+ def query_job_status(counter = 0)
393
340
  counter < 4 ? (sleep 2) : (sleep 6)
394
341
  counter += 1
395
342
 
@@ -400,7 +347,6 @@ module SmileIdentityCore
400
347
  else
401
348
  query_job_status(counter)
402
349
  end
403
-
404
350
  end
405
351
  end
406
352
  end
@@ -1,8 +1,14 @@
1
- require "smile-identity-core/version"
2
- require "smile-identity-core/web_api.rb"
3
- require "smile-identity-core/id_api.rb"
4
- require "smile-identity-core/signature.rb"
5
- require "smile-identity-core/utilities.rb"
1
+ # frozen_string_literal: true
2
+
3
+ require 'smile-identity-core/version'
4
+ require 'smile-identity-core/web_api'
5
+ require 'smile-identity-core/id_api'
6
+ require 'smile-identity-core/signature'
7
+ require 'smile-identity-core/utilities'
8
+ require 'smile-identity-core/business_verification'
9
+ require 'smile-identity-core/constants/env'
10
+ require 'smile-identity-core/constants/image_type'
11
+ require 'smile-identity-core/constants/job_type'
6
12
 
7
13
  module SmileIdentityCore
8
14
  class Error < StandardError; end
@@ -1,39 +1,44 @@
1
- lib = File.expand_path("lib", __dir__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "smile-identity-core/version"
5
+ require 'smile-identity-core/version'
4
6
 
5
7
  Gem::Specification.new do |spec|
6
- spec.name = "smile-identity-core"
8
+ spec.name = 'smile-identity-core'
7
9
  spec.version = SmileIdentityCore::VERSION
8
- spec.authors = ["Smile Identity"]
9
- spec.email = ["support@smileidentity.com"]
10
+ spec.authors = ['Smile Identity']
11
+ spec.email = ['support@smileidentity.com']
10
12
 
11
- spec.summary = "The Smile Identity Web API allows the user to access most of the features of the Smile Identity system through direct server to server queries."
12
- spec.description = "The Official Smile Identity gem"
13
- spec.homepage = "https://www.smileidentity.com/"
14
- spec.required_ruby_version = '>= 2.0'
13
+ spec.summary = 'The Smile Identity Web API allows the user to access\
14
+ most of the features of the Smile Identity system through direct server to server queries.'
15
+ spec.description = 'The Official Smile Identity gem'
16
+ spec.homepage = 'https://www.smileidentity.com/'
17
+ spec.required_ruby_version = '>= 2.5'
15
18
  spec.license = 'MIT'
16
19
 
17
- spec.metadata["homepage_uri"] = spec.homepage
18
- spec.metadata["source_code_uri"] = "https://github.com/smileidentity/smile-identity-core-ruby"
19
- spec.metadata["documentation_uri"] = "https://docs.smileidentity.com"
20
- spec.metadata["changelog_uri"] = "https://github.com/smileidentity/smile-identity-core/blob/master/CHANGELOG.md"
20
+ spec.metadata['homepage_uri'] = spec.homepage
21
+ spec.metadata['source_code_uri'] = 'https://github.com/smileidentity/smile-identity-core-ruby'
22
+ spec.metadata['documentation_uri'] = 'https://docs.smileidentity.com'
23
+ spec.metadata['changelog_uri'] = 'https://github.com/smileidentity/smile-identity-core-ruby/blob/master/CHANGELOG.md'
21
24
 
22
25
  # Specify which files should be added to the gem when it is released.
23
26
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
27
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
28
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
29
  end
27
- spec.bindir = "exe"
30
+ spec.bindir = 'exe'
28
31
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
- spec.require_paths = ["lib"]
32
+ spec.require_paths = ['lib']
30
33
 
31
- spec.add_development_dependency "bundler", "~> 2.0"
32
- spec.add_development_dependency "rake", "~> 10.0"
33
- spec.add_development_dependency "rspec", "~> 3.0"
34
+ spec.add_development_dependency 'bundler', '~> 2.0'
35
+ spec.add_development_dependency 'rake', '~> 12.3'
36
+ spec.add_development_dependency 'rspec', '~> 3.0'
37
+ spec.add_development_dependency 'rubocop', '~> 1.37.1'
38
+ spec.add_development_dependency 'rubocop-rake', '~> 0.6.0'
39
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.14.1'
34
40
  spec.add_development_dependency 'simplecov', '~> 0.12.0'
35
41
 
36
- spec.add_dependency 'typhoeus', '~> 1.0', '>= 1.0.1'
37
42
  spec.add_dependency 'rubyzip', '~> 1.2', '>= 1.2.3'
38
-
43
+ spec.add_dependency 'typhoeus', '~> 1.0', '>= 1.0.1'
39
44
  end