smile-identity-core 1.0.1 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: edcf68a6d2595ffaaace47ea75b7a7ef4829072f02ef7095564472261563649a
4
- data.tar.gz: e6657acf87f95de20366f5a559118bfcea6a58757bfa77a88984b083d44c2fe1
3
+ metadata.gz: 0e90f488e56f0f23468d8ce70a6190d7f343b6f626f3383e5909b0f2bede5e89
4
+ data.tar.gz: 2b53062431bd66ac011e1fde789c16fe501b565297b33324101153aa550da364
5
5
  SHA512:
6
- metadata.gz: bc0a67955105b33ca0cd3a287772ec3666a6fc22f1f5ae3c1a0d47f1fc2b70838b830748d7f29d14dde39bc84ce230d4d45028cd40b9c06ae8d419a39ff29654
7
- data.tar.gz: 7b4afa3dafab637388ffead740accaea4d1ba43327297ca7567a80ad180d60bbf39507e7865071275305b4e781bce1540ec484a4f5c576f3c73293283d175ef1
6
+ metadata.gz: 89338028a53553ddf63d7b004437b9305e6fc301578e7646888b6bf89557be2bbd5def9fce62cce7bbbc094c5e7bdc255a2ef9bf25f5a9732a06a7aa95ac3f44
7
+ data.tar.gz: efb84f0d05c9ce9df6b47126389cdc8dfa4245909b14fc396537b350e71b41c2e134a38462968432fffc85cff9c9a5347799d1eca07fb7c49253c5006deed9b1
data/.travis.yml CHANGED
@@ -1,7 +1,11 @@
1
1
  ---
2
+ dist: bionic
2
3
  sudo: false
3
4
  language: ruby
4
5
  cache: bundler
5
6
  rvm:
6
7
  - 2.5.1
7
- before_install: gem install bundler -v 2.0.2
8
+ - 2.6
9
+ - 2.7
10
+ - 3.0
11
+ before_install: gem install bundler -v 2.2.6
data/CHANGELOG.md CHANGED
@@ -44,3 +44,6 @@ Update the documentation
44
44
  ## Updated
45
45
  Remove first_name and last_name validations from id information in Web Api
46
46
  Add country, id_number and id_type validations for id information in ID Api
47
+
48
+ ## [1.0.2] - 2020-01-16
49
+ Add {"success":true,"smile_job_id":"job_id"} to the response when we poll job status too
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- smile-identity-core (1.0.1)
4
+ smile-identity-core (1.2.1)
5
5
  rubyzip (~> 1.2, >= 1.2.3)
6
6
  typhoeus (~> 1.0, >= 1.0.1)
7
7
 
@@ -12,8 +12,8 @@ GEM
12
12
  docile (1.1.5)
13
13
  ethon (0.12.0)
14
14
  ffi (>= 1.3.0)
15
- ffi (1.11.1)
16
- json (2.2.0)
15
+ ffi (1.13.1)
16
+ json (2.5.1)
17
17
  rake (10.5.0)
18
18
  rspec (3.8.0)
19
19
  rspec-core (~> 3.8.0)
@@ -34,7 +34,7 @@ GEM
34
34
  json (>= 1.8, < 3)
35
35
  simplecov-html (~> 0.10.0)
36
36
  simplecov-html (0.10.2)
37
- typhoeus (1.3.1)
37
+ typhoeus (1.4.0)
38
38
  ethon (>= 0.9.0)
39
39
 
40
40
  PLATFORMS
@@ -48,4 +48,4 @@ DEPENDENCIES
48
48
  smile-identity-core!
49
49
 
50
50
  BUNDLED WITH
51
- 2.0.2
51
+ 2.2.6
data/README.md CHANGED
@@ -1,12 +1,13 @@
1
- # SmileIdentityCore
1
+ # SmileIdentityCore [![Build Status](https://travis-ci.com/smileidentity/smile-identity-core-ruby.svg?branch=master)](https://travis-ci.com/smileidentity/smile-identity-core-ruby)
2
2
 
3
- The official Smile Identity gem exposes three classes namely, the Web API and Signature class.
3
+ The official Smile Identity gem exposes four classes namely; the Web Api class, the ID Api class, the Signature class and the Utilities class.
4
4
 
5
- The **Web API Class** allows you as the Partner to validate a user’s identity against the relevant Identity Authorities/Third Party databases that Smile Identity has access to using ID information provided by your customer/user (including photo for compare). It has the following public methods:
5
+ The **Web Api Class** allows you as the Partner to validate a user’s identity against the relevant Identity Authorities/Third Party databases that Smile Identity has access to using ID information provided by your customer/user (including photo for compare). It has the following public methods:
6
6
  - submit_job
7
7
  - get_job_status
8
+ - get_web_token
8
9
 
9
- The **ID Class** lets you performs basic KYC Services including verifying an ID number as well as retrieve a user's Personal Information. It has the following public methods:
10
+ The **ID Api Class** lets you performs basic KYC Services including verifying an ID number as well as retrieve a user's Personal Information. It has the following public methods:
10
11
  - submit_job
11
12
 
12
13
  The **Signature Class** allows you as the Partner to generate a sec key to interact with our servers. It has the following public methods:
@@ -20,7 +21,7 @@ The **Utilities Class** allows you as the Partner to have access to our general
20
21
 
21
22
  This gem requires specific input parameters, for more detail on these parameters please refer to our [documentation for Web API](https://docs.smileidentity.com).
22
23
 
23
- Please note that you will have to be a Smile Identity Partner to be able to query our services. You can sign up on the [Portal](https://test-smileid.herokuapp.com/signup?products[]=1-IDVALIDATION&products[]=2-AUTHENTICATION).
24
+ Please note that you will have to be a Smile Identity Partner to be able to query our services. You can sign up on the [Portal](https://portal.smileidentity.com/signup).
24
25
 
25
26
  ## Installation
26
27
 
@@ -39,7 +40,7 @@ require 'smile-identity-core'
39
40
 
40
41
  Or install it to your system as:
41
42
 
42
- ```
43
+ ```sh
43
44
  $ gem install smile-identity-core
44
45
  ```
45
46
 
@@ -48,33 +49,33 @@ You now may use the classes as follows:
48
49
  #### Web Api Class
49
50
 
50
51
  ##### submit_job method
51
- ```
52
- $ connection = SmileIdentityCore::WebApi.new(partner_id, default_callback, api_key, sid_server)
52
+ ```ruby
53
+ connection = SmileIdentityCore::WebApi.new(partner_id, default_callback, api_key, sid_server)
53
54
 
54
- $ response = connection.submit_job(partner_params, images, id_info, options)
55
+ response = connection.submit_job(partner_params, images, id_info, options)
55
56
  ```
56
57
 
57
58
  Please note that if you do not need to pass through id_info or options, you may omit calling those class and send through nil in submit_job, as follows:
58
59
 
59
- ```
60
- $ response = connection.submit_job(partner_params, images, nil, nil);
60
+ ```ruby
61
+ response = connection.submit_job(partner_params, images, nil, nil);
61
62
  ```
62
63
 
63
64
  In the case of a Job Type 5 you can simply omit the the images and options keys. Remember that the response is immediate, so there is no need to query the job_status. There is also no enrollment so no images are required. The response for a job type 5 can be found in the response section below.
64
65
 
65
- ```
66
- $ response = connection.submit_job(partner_params, nil, id_info, nil);
66
+ ```ruby
67
+ response = connection.submit_job(partner_params, nil, id_info, nil);
67
68
  ```
68
69
 
69
70
  **Response:**
70
71
 
71
72
  Should you choose to *set return_job_status to false*, the response will be a JSON String containing:
72
- ```
73
+ ```ruby
73
74
  {success: true, smile_job_id: smile_job_id}
74
75
  ```
75
76
 
76
77
  However, if you have *set return_job_status to true (with image_links and history)* then you will receive JSON Object response like below:
77
- ```
78
+ ```json
78
79
  {
79
80
  "job_success":true,
80
81
  "result":{
@@ -150,7 +151,7 @@ However, if you have *set return_job_status to true (with image_links and histor
150
151
  ```
151
152
 
152
153
  You can also *view your response asynchronously at the callback* that you have set, it will look as follows:
153
- ```
154
+ ```json
154
155
  {
155
156
  "job_success":true,
156
157
  "result":{
@@ -226,7 +227,7 @@ You can also *view your response asynchronously at the callback* that you have s
226
227
  ```
227
228
 
228
229
  If you have queried a job type 5, your response be a JSON String that will contain the following:
229
- ```
230
+ ```json
230
231
  {
231
232
  "JSONVersion":"1.0.0",
232
233
  "SmileJobID":"0000001105",
@@ -279,7 +280,7 @@ response = connection.get_job_status(partner_params, nil);
279
280
 
280
281
  Your response will return a JSON Object below with image_links and history included:
281
282
 
282
- ```
283
+ ```json
283
284
  {
284
285
  "job_success":true,
285
286
  "result":{
@@ -354,20 +355,54 @@ Your response will return a JSON Object below with image_links and history inclu
354
355
  }
355
356
  ```
356
357
 
358
+ ##### get_web_token method
359
+ You may want to use our hosted web integration, and create a session. The `get_web_token` method enables this.
360
+ You have your Web Api class initialised as follows:
361
+ ```ruby
362
+ connection = SmileIdentityCore::WebApi.new(partner_id, default_callback, api_key, sid_server)
363
+
364
+ ```
365
+
366
+ Next, you'll need to create your request params. This should take the following
367
+ structure:
368
+
369
+ ```ruby
370
+ {
371
+ user_id: 'user-1', # String: required
372
+ job_id: 'job-1', # String: required
373
+ product: 'authentication', # String: required one of 'authentication', 'identity_verification', 'smartselfie', 'ekyc_smartselfie', 'enhanced_kyc', 'document_verification'
374
+ callback_url: "https://smileidentity.com/callback" # String: required, optional if callback url was set during instantiation of the class
375
+ }
376
+ ```
377
+
378
+ Thereafter, call `get_web_token` with the correct parameters:
379
+ ```ruby
380
+ response = connection.get_web_token(request_params)
381
+ ```
382
+
383
+ **Response**
384
+
385
+ Your response will return a hash that contains
386
+ ```ruby
387
+ {
388
+ token: <token_string>
389
+ }
390
+ ```
391
+
357
392
  #### ID Api Class
358
393
 
359
394
 
360
395
  ##### submit_job method
361
- ```
362
- $ connection = SmileIdentityCore::IDApi.new(partner_id, api_key, sid_server)
396
+ ```ruby
397
+ connection = SmileIdentityCore::IDApi.new(partner_id, api_key, sid_server)
363
398
 
364
- $ response = connection.submit_job(partner_params, id_info)
399
+ response = connection.submit_job(partner_params, id_info)
365
400
  ```
366
401
 
367
402
  **Response**
368
403
 
369
404
  Your response will return a JSON String containing the below:
370
- ```
405
+ ```json
371
406
  {
372
407
  "JSONVersion":"1.0.0",
373
408
  "SmileJobID":"0000001105",
@@ -400,17 +435,17 @@ Your response will return a JSON String containing the below:
400
435
 
401
436
  ##### generate_sec_key method
402
437
 
403
- ```
404
- $ connection = SmileIdentityCore::Signature.new(partner_id, api_key)
438
+ ```ruby
439
+ connection = SmileIdentityCore::Signature.new(partner_id, api_key)
405
440
 
406
- $ sec_key = connection.generate_sec_key(timestamp)
441
+ sec_key = connection.generate_sec_key(timestamp)
407
442
  where timestamp is optional
408
443
 
409
444
  ```
410
445
 
411
446
  The response will be a hash:
412
447
 
413
- ```
448
+ ```ruby
414
449
  {
415
450
  :sec_key=> "<the generated sec key>",
416
451
  :timestamp=> 1563283420
@@ -422,8 +457,8 @@ The response will be a hash:
422
457
  You can also confirm the signature that you receive when you interacting with our servers, simply use the confirm_sec_key method which returns a boolean:
423
458
 
424
459
  ```ruby
425
- $ connection = SmileIdentityCore::Signature.new(partner_id, api_key)
426
- $ sec_key = connection.confirm_sec_key(sec_key, timestamp)
460
+ connection = SmileIdentityCore::Signature.new(partner_id, api_key)
461
+ sec_key = connection.confirm_sec_key(sec_key, timestamp)
427
462
  ```
428
463
 
429
464
  #### Utilities Class
@@ -443,13 +478,23 @@ After checking out the repo, run `bundle install` to install dependencies. Then,
443
478
 
444
479
  To install this gem onto your local machine, run `bundle exec rake install`.
445
480
 
481
+ You can use `bundle console` and then call the necessary classes with their parameters.
482
+
483
+ ## Testing
484
+
485
+ Run `bundle exec rspec` to run the tests.
486
+ After running your tests open the coverage/index.html to view the test coverage
487
+
488
+ ## Deployment
489
+
446
490
  To release a new version:
447
491
  - Update the version number in `version.rb`
448
492
  - Run `gem build smile-identity-core.gemspec`
449
- - Thereafter `gem push smile-identity-core-version.gem`.
493
+ - Thereafter `gem push smile-identity-core-<version>.gem`.
450
494
 
451
495
  Make sure to git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
452
496
 
497
+
453
498
  ## Contributing
454
499
 
455
500
  Bug reports and pull requests are welcome on GitHub at https://github.com/smileidentity/smile-identity-core
@@ -8,8 +8,8 @@ module SmileIdentityCore
8
8
  @sid_server = sid_server
9
9
  if !(sid_server =~ URI::regexp)
10
10
  sid_server_mapping = {
11
- 0 => 'https://3eydmgh10d.execute-api.us-west-2.amazonaws.com/test',
12
- 1 => 'https://la7am6gdm8.execute-api.us-west-2.amazonaws.com/prod'
11
+ 0 => 'https://testapi.smileidentity.com/v1',
12
+ 1 => 'https://api.smileidentity.com/v1',
13
13
  }
14
14
  @url = sid_server_mapping[sid_server.to_i]
15
15
  else
@@ -17,32 +17,30 @@ module SmileIdentityCore
17
17
  end
18
18
  end
19
19
 
20
- def submit_job(partner_params, id_info)
20
+ def submit_job(partner_params, id_info, options = {})
21
21
  self.partner_params = symbolize_keys partner_params
22
-
23
- @timestamp = Time.now.to_i
24
-
25
22
  self.id_info = symbolize_keys id_info
23
+ @use_new_signature = symbolize_keys(options || {}).fetch(:signature, false)
26
24
 
27
25
  if @partner_params[:job_type].to_i != 5
28
- raise ArgumentError.new('Please ensure that you are setting your job_type to 5 to query ID Api')
26
+ raise ArgumentError, 'Please ensure that you are setting your job_type to 5 to query ID Api'
29
27
  end
30
28
 
31
- return setup_requests
29
+ setup_requests
32
30
  end
33
31
 
34
32
  def partner_params=(partner_params)
35
33
  if partner_params == nil
36
- raise ArgumentError.new('Please ensure that you send through partner params')
34
+ raise ArgumentError, 'Please ensure that you send through partner params'
37
35
  end
38
36
 
39
37
  if !partner_params.is_a?(Hash)
40
- raise ArgumentError.new('Partner params needs to be a hash')
38
+ raise ArgumentError, 'Partner params needs to be a hash'
41
39
  end
42
40
 
43
41
  [:user_id, :job_id, :job_type].each do |key|
44
42
  unless partner_params[key] && !partner_params[key].nil? && !(partner_params[key].empty? if partner_params[key].is_a?(String))
45
- raise ArgumentError.new("Please make sure that #{key.to_s} is included in the partner params")
43
+ raise ArgumentError, "Please make sure that #{key} is included in the partner params"
46
44
  end
47
45
  end
48
46
 
@@ -54,12 +52,12 @@ module SmileIdentityCore
54
52
  updated_id_info = id_info
55
53
 
56
54
  if updated_id_info.nil? || updated_id_info.keys.length == 0
57
- raise ArgumentError.new("Please make sure that id_info not empty or nil")
55
+ raise ArgumentError, 'Please make sure that id_info not empty or nil'
58
56
  end
59
57
 
60
58
  [:country, :id_type, :id_number].each do |key|
61
59
  unless updated_id_info[key] && !updated_id_info[key].nil? && !updated_id_info[key].empty?
62
- raise ArgumentError.new("Please make sure that #{key.to_s} is included in the id_info")
60
+ raise ArgumentError, "Please make sure that #{key} is included in the id_info"
63
61
  end
64
62
  end
65
63
 
@@ -83,36 +81,46 @@ module SmileIdentityCore
83
81
  )
84
82
 
85
83
  request.on_complete do |response|
86
- if response.success?
87
- return response.body
88
- elsif response.timed_out?
89
- raise "#{response.code.to_s}: #{response.body}"
90
- elsif response.code == 0
91
- # Could not get an http response, something's wrong.
92
- raise "#{response.code.to_s}: #{response.body}"
93
- else
94
- # Received a non-successful http response.
95
- raise "#{response.code.to_s}: #{response.body}"
96
- end
84
+ return response.body if response.success?
85
+
86
+ raise "#{response.code}: #{response.body}"
97
87
  end
98
88
  request.run
99
89
  end
100
90
 
101
91
  def configure_json
102
- body = {
103
- timestamp: @timestamp,
104
- sec_key: determine_sec_key,
105
- partner_id: @partner_id,
106
- partner_params: @partner_params
107
- }
92
+ request_security(use_new_signature: @use_new_signature)
93
+ .merge(@id_info)
94
+ .merge(
95
+ partner_id: @partner_id,
96
+ partner_params: @partner_params)
97
+ .to_json
98
+ end
108
99
 
109
- body.merge!(@id_info)
110
- JSON.generate(body)
100
+ def signature_generator
101
+ SmileIdentityCore::Signature.new(@partner_id, @api_key)
111
102
  end
112
103
 
113
- def determine_sec_key
114
- @sec_key = SmileIdentityCore::Signature.new(@partner_id, @api_key).generate_sec_key(@timestamp)[:sec_key]
104
+ def signature(timestamp: Time.now.to_s)
105
+ signature = signature_generator.generate_signature(timestamp)[:signature]
106
+ {
107
+ signature: signature,
108
+ timestamp: timestamp
109
+ }
110
+ end
111
+
112
+ def sec_key(timestamp: Time.now.to_s)
113
+ sec_key = signature_generator.generate_sec_key(timestamp)[:sec_key]
114
+ {
115
+ sec_key: sec_key,
116
+ timestamp: timestamp
117
+ }
115
118
  end
116
119
 
120
+ def request_security(use_new_signature: true)
121
+ return signature if use_new_signature
122
+
123
+ sec_key
124
+ end
117
125
  end
118
126
  end
@@ -3,7 +3,7 @@ module SmileIdentityCore
3
3
 
4
4
  def initialize(partner_id, api_key)
5
5
  @api_key = api_key
6
- @partner_id = partner_id.to_i
6
+ @partner_id = partner_id
7
7
  end
8
8
 
9
9
  def generate_sec_key(timestamp=Time.now.to_i)
@@ -14,7 +14,7 @@ module SmileIdentityCore
14
14
  public_key = OpenSSL::PKey::RSA.new(Base64.decode64(@api_key))
15
15
  @sec_key = [Base64.encode64(public_key.public_encrypt(hash_signature)), hash_signature].join('|')
16
16
 
17
- return {
17
+ {
18
18
  sec_key: @sec_key,
19
19
  timestamp: @timestamp
20
20
  }
@@ -31,10 +31,26 @@ module SmileIdentityCore
31
31
  public_key = OpenSSL::PKey::RSA.new(Base64.decode64(@api_key))
32
32
  decrypted = public_key.public_decrypt(Base64.decode64(encrypted))
33
33
 
34
- return decrypted == hash_signature
34
+ decrypted == hash_signature
35
35
  rescue => e
36
36
  raise e
37
37
  end
38
38
  end
39
+
40
+ def generate_signature(timestamp=Time.now.to_s)
41
+ hmac = OpenSSL::HMAC.new(@api_key, 'sha256')
42
+ hmac.update(timestamp.to_s)
43
+ hmac.update(@partner_id)
44
+ hmac.update("sid_request")
45
+ signature = Base64.strict_encode64(hmac.digest())
46
+ {
47
+ signature: signature,
48
+ timestamp: timestamp.to_s
49
+ }
50
+ end
51
+
52
+ def confirm_signature(timestamp, msg_signature)
53
+ generate_signature(timestamp)[:signature] == msg_signature
54
+ end
39
55
  end
40
56
  end
@@ -7,8 +7,8 @@ module SmileIdentityCore
7
7
 
8
8
  if !(sid_server =~ URI::regexp)
9
9
  sid_server_mapping = {
10
- 0 => 'https://3eydmgh10d.execute-api.us-west-2.amazonaws.com/test',
11
- 1 => 'https://la7am6gdm8.execute-api.us-west-2.amazonaws.com/prod'
10
+ 0 => 'https://testapi.smileidentity.com/v1',
11
+ 1 => 'https://api.smileidentity.com/v1',
12
12
  }
13
13
  @url = sid_server_mapping[sid_server.to_i]
14
14
  else
@@ -20,16 +20,12 @@ module SmileIdentityCore
20
20
  end
21
21
 
22
22
  def get_job_status(user_id, job_id, options = {})
23
+ options = symbolize_keys(options || {})
24
+ options[:return_history] ||= false
25
+ options[:return_image_links] ||= false
23
26
 
24
- if(options.nil? || options.empty?)
25
- options = {
26
- return_history: false,
27
- return_job_status: false
28
- }
29
- end
30
-
31
- @timestamp = Time.now.to_i
32
- return query_job_status(user_id, job_id, symbolize_keys(options))
27
+ security = request_security(use_new_signature: options.fetch(:signature, false))
28
+ query_job_status(configure_job_query(user_id, job_id, options).merge(security))
33
29
  end
34
30
 
35
31
  private
@@ -38,21 +34,30 @@ module SmileIdentityCore
38
34
  (params.is_a?(Hash)) ? Hash[params.map{ |k, v| [k.to_sym, v] }] : params
39
35
  end
40
36
 
41
- def query_job_status(user_id, job_id, options)
37
+ def query_job_status(request_json_data)
42
38
  url = "#{@url}/job_status"
43
39
 
44
40
  request = Typhoeus::Request.new(
45
41
  url,
46
42
  headers: {'Content-Type': 'application/json', 'Accept': 'application/json'},
47
43
  method: :post,
48
- body: configure_job_query(user_id, job_id, options)
44
+ body: request_json_data.to_json
49
45
  )
50
46
 
51
47
  request.on_complete do |response|
52
48
  begin
53
49
  body = JSON.parse(response.body)
54
50
 
55
- valid = @signature_connection.confirm_sec_key(body['timestamp'], body['signature'])
51
+ # NB: we have to trust that the server will return the right kind of
52
+ # timestamp (integer or string) for the signature, and the right kind
53
+ # of signature in the "signature" field. The best way to know what
54
+ # kind of validation to perform is by remembering which kind of
55
+ # security we started with.
56
+ if request_json_data.has_key?(:sec_key)
57
+ valid = @signature_connection.confirm_sec_key(body['timestamp'], body['signature'])
58
+ else
59
+ valid = @signature_connection.confirm_signature(body['timestamp'], body['signature'])
60
+ end
56
61
 
57
62
  if(!valid)
58
63
  raise "Unable to confirm validity of the job_status response"
@@ -67,17 +72,30 @@ module SmileIdentityCore
67
72
  request.run
68
73
  end
69
74
 
75
+ def request_security(use_new_signature: false)
76
+ if use_new_signature
77
+ @timestamp = Time.now.to_s
78
+ {
79
+ signature: @signature_connection.generate_signature(@timestamp)[:signature],
80
+ timestamp: @timestamp,
81
+ }
82
+ else
83
+ @timestamp = Time.now.to_i
84
+ {
85
+ sec_key: @signature_connection.generate_sec_key(@timestamp)[:sec_key],
86
+ timestamp: @timestamp,
87
+ }
88
+ end
89
+ end
90
+
70
91
  def configure_job_query(user_id, job_id, options)
71
- return {
72
- sec_key: @signature_connection.generate_sec_key(@timestamp)[:sec_key],
73
- timestamp: @timestamp,
92
+ {
74
93
  user_id: user_id,
75
94
  job_id: job_id,
76
95
  partner_id: @partner_id,
77
- image_links: options[:return_image_links] || false,
78
- history: options[:return_history] || false
79
- }.to_json
96
+ image_links: options[:return_image_links],
97
+ history: options[:return_history]
98
+ }
80
99
  end
81
-
82
100
  end
83
101
  end
@@ -1,3 +1,3 @@
1
1
  module SmileIdentityCore
2
- VERSION = "1.0.1"
2
+ VERSION = "1.2.1"
3
3
  end
@@ -18,8 +18,8 @@ module SmileIdentityCore
18
18
  @sid_server = sid_server
19
19
  if !(sid_server =~ URI::regexp)
20
20
  sid_server_mapping = {
21
- 0 => 'https://3eydmgh10d.execute-api.us-west-2.amazonaws.com/test',
22
- 1 => 'https://la7am6gdm8.execute-api.us-west-2.amazonaws.com/prod'
21
+ 0 => 'https://testapi.smileidentity.com/v1',
22
+ 1 => 'https://api.smileidentity.com/v1',
23
23
  }
24
24
  @url = sid_server_mapping[sid_server.to_i]
25
25
  else
@@ -35,8 +35,6 @@ module SmileIdentityCore
35
35
  end
36
36
 
37
37
  self.images = images
38
- @timestamp = Time.now.to_i
39
-
40
38
  self.id_info = symbolize_keys id_info
41
39
  self.options = symbolize_keys options
42
40
 
@@ -50,7 +48,7 @@ module SmileIdentityCore
50
48
 
51
49
  validate_return_data
52
50
 
53
- return setup_requests
51
+ setup_requests
54
52
  end
55
53
 
56
54
  def get_job_status(partner_params, options)
@@ -61,21 +59,21 @@ module SmileIdentityCore
61
59
  job_id = partner_params[:job_id]
62
60
 
63
61
  utilities = SmileIdentityCore::Utilities.new(@partner_id, @api_key, @sid_server)
64
- return utilities.get_job_status(user_id, job_id, options);
62
+ utilities.get_job_status(user_id, job_id, options);
65
63
  end
66
64
 
67
65
  def partner_params=(partner_params)
68
66
  if partner_params == nil
69
- raise ArgumentError.new('Please ensure that you send through partner params')
67
+ raise ArgumentError, 'Please ensure that you send through partner params'
70
68
  end
71
69
 
72
70
  if !partner_params.is_a?(Hash)
73
- raise ArgumentError.new('Partner params needs to be a hash')
71
+ raise ArgumentError, 'Partner params needs to be a hash'
74
72
  end
75
73
 
76
74
  [:user_id, :job_id, :job_type].each do |key|
77
75
  unless partner_params[key] && !partner_params[key].nil? && !(partner_params[key].empty? if partner_params[key].is_a?(String))
78
- raise ArgumentError.new("Please make sure that #{key.to_s} is included in the partner params")
76
+ raise ArgumentError, "Please make sure that #{key} is included in the partner params"
79
77
  end
80
78
  end
81
79
 
@@ -84,16 +82,16 @@ module SmileIdentityCore
84
82
 
85
83
  def images=(images)
86
84
  if images == nil
87
- raise ArgumentError.new('Please ensure that you send through image details')
85
+ raise ArgumentError, 'Please ensure that you send through image details'
88
86
  end
89
87
 
90
88
  if !images.is_a?(Array)
91
- raise ArgumentError.new('Image details needs to be an array')
89
+ raise ArgumentError, 'Image details needs to be an array'
92
90
  end
93
91
 
94
92
  # all job types require atleast a selfie
95
93
  if images.length == 0 || images.none? {|h| h[:image_type_id] == 0 || h[:image_type_id] == 2 }
96
- raise ArgumentError.new('You need to send through at least one selfie image')
94
+ raise ArgumentError, 'You need to send through at least one selfie image'
97
95
  end
98
96
 
99
97
  @images = images.map { |image| symbolize_keys image }
@@ -121,7 +119,7 @@ module SmileIdentityCore
121
119
  if updated_id_info[:entered] && updated_id_info[:entered] == 'true'
122
120
  [:country, :id_type, :id_number].each do |key|
123
121
  unless id_info[key] && !id_info[key].nil? && !id_info[key].empty?
124
- raise ArgumentError.new("Please make sure that #{key.to_s} is included in the id_info")
122
+ raise ArgumentError, "Please make sure that #{key.to_s} is included in the id_info"
125
123
  end
126
124
  end
127
125
  end
@@ -130,38 +128,62 @@ module SmileIdentityCore
130
128
  end
131
129
 
132
130
  def options=(options)
133
- updated_options = options
131
+ updated_options = options || {}
134
132
 
135
- if updated_options.nil?
136
- updated_options = {}
137
- end
138
-
139
- [:optional_callback, :return_job_status, :return_image_links, :return_history].map do |key|
140
- if key != :optional_callback
141
- updated_options[key] = check_boolean(key, options)
142
- else
143
- updated_options[key] = check_string(key, options)
144
- end
145
- end
133
+ updated_options[:optional_callback] = check_string(:optional_callback, options)
134
+ updated_options[:return_job_status] = check_boolean(:return_job_status, options)
135
+ updated_options[:return_image_links] = check_boolean(:return_image_links, options)
136
+ updated_options[:return_history] = check_boolean(:return_history, options)
137
+ @use_new_signature = updated_options.fetch(:signature, false)
146
138
 
147
139
  @options = updated_options
148
140
  end
149
141
 
142
+ def get_web_token(request_params)
143
+ raise ArgumentError, 'Please ensure that you send through request params' if request_params.nil?
144
+ raise ArgumentError, 'Request params needs to be an object' unless request_params.is_a?(Hash)
145
+
146
+ callback_url = request_params[:callback_url] || @callback_url
147
+ request_params[:callback_url] = callback_url
148
+
149
+ keys = %i[user_id job_id product callback_url]
150
+ blank_keys = get_blank_keys(keys, request_params)
151
+ error_message = "#{blank_keys.join(', ')} #{blank_keys.length > 1 ? 'are' : 'is'} required to get a web token"
152
+ raise ArgumentError, error_message unless blank_keys.empty?
153
+
154
+ request_web_token(request_params)
155
+ end
156
+
150
157
  private
151
158
 
159
+ def request_web_token(request_params)
160
+ request_params.merge!({ partner_id: @partner_id }).merge!(request_security)
161
+ url = "#{@url}/token"
162
+
163
+ response = Typhoeus.post(
164
+ url,
165
+ headers: { 'Content-Type' => 'application/json' },
166
+ body: request_params.to_json
167
+ )
168
+
169
+ return response.body if response.code == 200
170
+
171
+ raise "#{response.code}: #{response.body}"
172
+ end
173
+
152
174
  def symbolize_keys params
153
175
  (params.is_a?(Hash)) ? Hash[params.map{ |k, v| [k.to_sym, v] }] : params
154
176
  end
155
177
 
156
178
  def validate_return_data
157
179
  if (!@callback_url || @callback_url.empty?) && !@options[:return_job_status]
158
- raise ArgumentError.new("Please choose to either get your response via the callback or job status query")
180
+ raise ArgumentError, 'Please choose to either get your response via the callback or job status query'
159
181
  end
160
182
  end
161
183
 
162
184
  def validate_enroll_with_id
163
185
  if(((@images.none? {|h| h[:image_type_id] == 1 || h[:image_type_id] == 3 }) && @id_info[:entered] != 'true'))
164
- raise ArgumentError.new("You are attempting to complete a job type 1 without providing an id card image or id info")
186
+ raise ArgumentError, 'You are attempting to complete a job type 1 without providing an id card image or id info'
165
187
  end
166
188
  end
167
189
 
@@ -171,37 +193,54 @@ module SmileIdentityCore
171
193
  end
172
194
 
173
195
  if !!obj[key] != obj[key]
174
- raise ArgumentError.new("#{key} needs to be a boolean")
196
+ raise ArgumentError, "#{key} needs to be a boolean"
175
197
  end
176
198
 
177
- return obj[key]
199
+ obj[key]
178
200
  end
179
201
 
180
202
  def check_string(key, obj)
181
203
  if (!obj || !obj[key])
182
- return ''
204
+ ''
183
205
  else
184
- return obj[key]
206
+ obj[key]
185
207
  end
186
208
  end
187
209
 
188
- def determine_sec_key
189
- @sec_key = SmileIdentityCore::Signature.new(@partner_id, @api_key).generate_sec_key(@timestamp)[:sec_key]
210
+ def blank?(obj, key)
211
+ return obj[key].empty? if obj[key].respond_to?(:empty?)
212
+
213
+ obj[key].nil?
190
214
  end
191
215
 
192
- def configure_prep_upload_json
216
+ def get_blank_keys(keys, obj)
217
+ keys.select { |key| blank?(obj, key) }
218
+ end
219
+
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
193
235
 
194
- body = {
236
+ def configure_prep_upload_json
237
+ request_security(use_new_signature: @use_new_signature).merge(
195
238
  file_name: 'selfie.zip',
196
- timestamp: @timestamp,
197
- sec_key: determine_sec_key,
198
239
  smile_client_id: @partner_id,
199
240
  partner_params: @partner_params,
200
241
  model_parameters: {}, # what is this for
201
242
  callback_url: @callback_url
202
- }
203
-
204
- JSON.generate(body)
243
+ ).to_json
205
244
  end
206
245
 
207
246
  def setup_requests
@@ -216,22 +255,21 @@ module SmileIdentityCore
216
255
 
217
256
  request.on_complete do |response|
218
257
  if response.success?
258
+ # TODO: if/when we sign these responses, verify the signature here and raise if it's off.
259
+ # if updated_options[:signature]
260
+ # 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
219
264
 
220
265
  prep_upload_response = JSON.parse(response.body)
221
266
  info_json = configure_info_json(prep_upload_response)
222
267
 
223
268
  file_upload_response = upload_file(prep_upload_response['upload_url'], info_json, prep_upload_response['smile_job_id'])
224
269
  return file_upload_response
225
-
226
- elsif response.timed_out?
227
- raise "#{response.code.to_s}: #{response.body}"
228
- elsif response.code == 0
229
- # Could not get an http response, something's wrong.
230
- raise "#{response.code.to_s}: #{response.body}"
231
- else
232
- # Received a non-successful http response.
233
- raise "#{response.code.to_s}: #{response.body}"
234
270
  end
271
+
272
+ raise "#{response.code}: #{response.body}"
235
273
  end
236
274
  request.run
237
275
  end
@@ -246,11 +284,9 @@ module SmileIdentityCore
246
284
  },
247
285
  "language": "ruby"
248
286
  },
249
- "misc_information": {
250
- "sec_key": @sec_key,
287
+ "misc_information": request_security(use_new_signature: @use_new_signature).merge(
251
288
  "retry": "false",
252
289
  "partner_params": @partner_params,
253
- "timestamp": @timestamp,
254
290
  "file_name": "selfie.zip", # figure out what to do here
255
291
  "smile_client_id": @partner_id,
256
292
  "callback_url": @callback_url,
@@ -266,17 +302,17 @@ module SmileIdentityCore
266
302
  "countryCode": "+",
267
303
  "countryName": ""
268
304
  }
269
- },
305
+ ),
270
306
  "id_info": @id_info,
271
307
  "images": configure_image_payload,
272
308
  "server_information": server_information
273
309
  }
274
- return info
310
+ info
275
311
  end
276
312
 
277
313
  def configure_image_payload
278
314
  @images.map { |i|
279
- if isImageFile?i[:image_type_id]
315
+ if image_file?(i[:image_type_id])
280
316
  {
281
317
  image_type_id: i[:image_type_id],
282
318
  image: '',
@@ -292,7 +328,7 @@ module SmileIdentityCore
292
328
  }
293
329
  end
294
330
 
295
- def isImageFile?type
331
+ def image_file?(type)
296
332
  type.to_i == 0 || type.to_i == 1
297
333
  end
298
334
 
@@ -329,19 +365,15 @@ module SmileIdentityCore
329
365
  if response.success?
330
366
  if @options[:return_job_status]
331
367
  @utilies_connection = SmileIdentityCore::Utilities.new(@partner_id, @api_key, @sid_server)
332
- return query_job_status
368
+ job_response = query_job_status
369
+ job_response["success"] = true
370
+ job_response["smile_job_id"] = smile_job_id
371
+ return job_response
333
372
  else
334
373
  return {success: true, smile_job_id: smile_job_id}.to_json
335
374
  end
336
- elsif response.timed_out?
337
- raise " #{response.code.to_s}: #{response.body}"
338
- elsif response.code == 0
339
- # Could not get an http response, something's wrong.
340
- raise " #{response.code.to_s}: #{response.body}"
341
- else
342
- # Received a non-successful http response.
343
- raise " #{response.code.to_s}: #{response.body}"
344
375
  end
376
+ raise " #{response.code}: #{response.body}"
345
377
  end
346
378
  request.run
347
379
 
@@ -354,9 +386,9 @@ module SmileIdentityCore
354
386
  response = @utilies_connection.get_job_status(@partner_params[:user_id], @partner_params[:job_id], @options)
355
387
 
356
388
  if response && (response['job_complete'] == true || counter == 20)
357
- return response
389
+ response
358
390
  else
359
- return query_job_status(counter)
391
+ query_job_status(counter)
360
392
  end
361
393
 
362
394
  end
@@ -5,8 +5,8 @@ require "smile-identity-core/version"
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "smile-identity-core"
7
7
  spec.version = SmileIdentityCore::VERSION
8
- spec.authors = ["Ridhwana"]
9
- spec.email = ["ridhwana.khan16@gmail.com"]
8
+ spec.authors = ["Smile Identity"]
9
+ spec.email = ["support@smileidentity.com"]
10
10
 
11
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
12
  spec.description = "The Official Smile Identity gem"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smile-identity-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
- - Ridhwana
8
- autorequire:
7
+ - Smile Identity
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-25 00:00:00.000000000 Z
11
+ date: 2021-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,7 +108,7 @@ dependencies:
108
108
  version: 1.2.3
109
109
  description: The Official Smile Identity gem
110
110
  email:
111
- - ridhwana.khan16@gmail.com
111
+ - support@smileidentity.com
112
112
  executables: []
113
113
  extensions: []
114
114
  extra_rdoc_files: []
@@ -130,7 +130,6 @@ files:
130
130
  - lib/smile-identity-core/version.rb
131
131
  - lib/smile-identity-core/web_api.rb
132
132
  - smile-identity-core.gemspec
133
- - travis.yml
134
133
  homepage: https://www.smileidentity.com/
135
134
  licenses:
136
135
  - MIT
@@ -139,7 +138,7 @@ metadata:
139
138
  source_code_uri: https://github.com/smileidentity/smile-identity-core-ruby
140
139
  documentation_uri: https://docs.smileidentity.com
141
140
  changelog_uri: https://github.com/smileidentity/smile-identity-core/blob/master/CHANGELOG.md
142
- post_install_message:
141
+ post_install_message:
143
142
  rdoc_options: []
144
143
  require_paths:
145
144
  - lib
@@ -154,9 +153,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
153
  - !ruby/object:Gem::Version
155
154
  version: '0'
156
155
  requirements: []
157
- rubyforge_project:
158
- rubygems_version: 2.7.6
159
- signing_key:
156
+ rubygems_version: 3.2.3
157
+ signing_key:
160
158
  specification_version: 4
161
159
  summary: The Smile Identity Web API allows the user to access most of the features
162
160
  of the Smile Identity system through direct server to server queries.
data/travis.yml DELETED
@@ -1,9 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.5.1
4
-
5
- script:
6
- - bundle exec rake spec
7
-
8
- before_install:
9
- - gem install bundle