smile-identity-core 1.2.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,55 +196,37 @@ 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
231
  end
271
232
 
@@ -275,43 +236,44 @@ module SmileIdentityCore
275
236
  end
276
237
 
277
238
  def configure_info_json(server_information)
278
- info = {
239
+ {
279
240
  "package_information": {
280
241
  "apiVersion": {
281
242
  "buildNumber": 0,
282
243
  "majorVersion": 2,
283
244
  "minorVersion": 0
284
245
  },
285
- "language": "ruby"
246
+ "language": 'ruby'
286
247
  },
287
- "misc_information": request_security(use_new_signature: @use_new_signature).merge(
288
- "retry": "false",
289
- "partner_params": @partner_params,
290
- "file_name": "selfie.zip", # figure out what to do here
291
- "smile_client_id": @partner_id,
292
- "callback_url": @callback_url,
293
- "userData": { # TO ASK what goes here
294
- "isVerifiedProcess": false,
295
- "name": "",
296
- "fbUserID": "",
297
- "firstName": "Bill",
298
- "lastName": "",
299
- "gender": "",
300
- "email": "",
301
- "phone": "",
302
- "countryCode": "+",
303
- "countryName": ""
304
- }
305
- ),
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
+ ),
306
269
  "id_info": @id_info,
307
270
  "images": configure_image_payload,
308
271
  "server_information": server_information
309
272
  }
310
- info
311
273
  end
312
274
 
313
275
  def configure_image_payload
314
- @images.map { |i|
276
+ @images.map do |i|
315
277
  if image_file?(i[:image_type_id])
316
278
  {
317
279
  image_type_id: i[:image_type_id],
@@ -325,11 +287,11 @@ module SmileIdentityCore
325
287
  file_name: ''
326
288
  }
327
289
  end
328
- }
290
+ end
329
291
  end
330
292
 
331
293
  def image_file?(type)
332
- type.to_i == 0 || type.to_i == 1
294
+ type.to_i.zero? || type.to_i == 1
333
295
  end
334
296
 
335
297
  def zip_up_file(info_json)
@@ -338,9 +300,9 @@ module SmileIdentityCore
338
300
  zos.put_next_entry('info.json')
339
301
  zos.puts JSON.pretty_generate(info_json)
340
302
 
341
- if @images.length > 0
303
+ if @images.length.positive?
342
304
  @images.each do |img|
343
- if img[:image_type_id] == 0 || img[:image_type_id] == 1
305
+ if (img[:image_type_id]).zero? || img[:image_type_id] == 1
344
306
  zos.put_next_entry(File.basename(img[:image]))
345
307
  zos.print IO.read(img[:image])
346
308
  end
@@ -350,36 +312,31 @@ module SmileIdentityCore
350
312
  end
351
313
 
352
314
  def upload_file(url, info_json, smile_job_id)
353
-
354
315
  file = zip_up_file(info_json)
355
316
  file.rewind
356
317
 
357
318
  request = Typhoeus::Request.new(
358
319
  url,
359
320
  method: 'PUT',
360
- headers: {'Content-Type'=> "application/zip"},
361
- body: file.read,
321
+ headers: { 'Content-Type' => 'application/zip' },
322
+ body: file.read
362
323
  )
363
324
 
364
325
  request.on_complete do |response|
365
- if response.success?
366
- if @options[:return_job_status]
367
- @utilies_connection = SmileIdentityCore::Utilities.new(@partner_id, @api_key, @sid_server)
368
- job_response = query_job_status
369
- job_response["success"] = true
370
- job_response["smile_job_id"] = smile_job_id
371
- return job_response
372
- else
373
- return {success: true, smile_job_id: smile_job_id}.to_json
374
- end
375
- end
376
- raise " #{response.code}: #{response.body}"
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
377
335
  end
378
336
  request.run
379
-
380
337
  end
381
338
 
382
- def query_job_status(counter=0)
339
+ def query_job_status(counter = 0)
383
340
  counter < 4 ? (sleep 2) : (sleep 6)
384
341
  counter += 1
385
342
 
@@ -390,7 +347,6 @@ module SmileIdentityCore
390
347
  else
391
348
  query_job_status(counter)
392
349
  end
393
-
394
350
  end
395
351
  end
396
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