trusona 2.2.0 → 2.5.2

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.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gitignore +3 -0
  5. data/.rubocop.yml +13 -0
  6. data/.ruby-version +1 -1
  7. data/.travis.yml +26 -16
  8. data/DEVELOP.md +11 -0
  9. data/README.md +4 -3
  10. data/bin/console +0 -1
  11. data/integrations/buster.rb +15 -0
  12. data/integrations/spec_helper.rb +3 -0
  13. data/integrations/trusonafication_spec.rb +18 -3
  14. data/lib/trusona.rb +3 -1
  15. data/lib/trusona/api/signed_request.rb +4 -1
  16. data/lib/trusona/api/verified_response.rb +6 -1
  17. data/lib/trusona/identity_document.rb +0 -6
  18. data/lib/trusona/mappers/base_mapper.rb +5 -0
  19. data/lib/trusona/mappers/paired_tru_code_mapper.rb +1 -0
  20. data/lib/trusona/resources/base_resource.rb +1 -1
  21. data/lib/trusona/resources/device_user_binding.rb +1 -0
  22. data/lib/trusona/resources/device_user_binding_activation.rb +2 -1
  23. data/lib/trusona/resources/identity_document.rb +4 -4
  24. data/lib/trusona/resources/paired_tru_code.rb +1 -0
  25. data/lib/trusona/resources/tru_code.rb +2 -1
  26. data/lib/trusona/resources/trusonafication.rb +29 -20
  27. data/lib/trusona/resources/user_account.rb +6 -2
  28. data/lib/trusona/resources/user_identifier.rb +3 -1
  29. data/lib/trusona/resources/validators.rb +1 -0
  30. data/lib/trusona/services/base_service.rb +9 -2
  31. data/lib/trusona/services/device_user_bindings_service.rb +3 -3
  32. data/lib/trusona/services/identity_documents_service.rb +3 -3
  33. data/lib/trusona/services/paired_tru_code_service.rb +1 -0
  34. data/lib/trusona/trusonafication.rb +32 -3
  35. data/lib/trusona/version.rb +1 -1
  36. data/lib/trusona/workers/device_finder.rb +1 -0
  37. data/lib/trusona/workers/identity_document_finder.rb +1 -0
  38. data/lib/trusona/workers/paired_tru_code_finder.rb +1 -0
  39. data/lib/trusona/workers/tru_code_finder.rb +1 -0
  40. data/lib/trusona/workers/trusonafication_canceler.rb +27 -0
  41. data/lib/trusona/workers/trusonafication_creator.rb +2 -1
  42. data/lib/trusona/workers/trusonafication_finder.rb +1 -1
  43. data/lib/trusona/workers/user_account_finder.rb +1 -3
  44. data/lib/trusona/workers/user_deactivator.rb +1 -3
  45. data/lib/trusona/workers/user_identifier_finder.rb +1 -0
  46. data/trusona.cnf +14 -0
  47. data/trusona.gemspec +9 -7
  48. metadata +85 -57
  49. metadata.gz.sig +0 -0
  50. data/certs/trusona.pem +0 -34
  51. data/trusona.key.pem.enc +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 398cae673c18c91ca4edf45a61db8321a4b3a409
4
- data.tar.gz: e65a8f49e68558631ade4e92a565c9d9f113cedc
2
+ SHA256:
3
+ metadata.gz: 40d92199f258cfcf2372a965a9130538740bc66b3efd448b5c6a934f2455e96d
4
+ data.tar.gz: 641e86b8b550a00308ab97e2568075b3acfd5346ffb9c19f0b1722448ff73869
5
5
  SHA512:
6
- metadata.gz: bae3928a80ca2f52a2c4ce3a0d4d8afa4e72d079b8ee73016b28c5efcdb963422ef7b30593125f8dddbae533760395e49abec02157572fb42b63cb6a71f40c81
7
- data.tar.gz: 40d854cab5c18fd0451ce85317ed337b10bafc815a35f6dceb2f871a7b477d3f3dbdfc4ceb1cccf54d831da81c71b59c1b98b75ab46c95b02b7ef628ef7cda31
6
+ metadata.gz: 3781ff09ccd9ef242c8ead30d2ffae002b9a66f539b39d4a631d233c4e33c84df2cf6b2cff46e0bd37456d03a38dc717a357d8e3be515a12ac92aaead6f500e2
7
+ data.tar.gz: 7f9378e8ef9576c1d4872e3fbb024b34b1b86be2f72a7cc7117b12b7e4020141f05e547934809da281262db4ae5ee3ab333f2062a7dda92c6efa46f7688c1927
Binary file
data.tar.gz.sig CHANGED
Binary file
data/.gitignore CHANGED
@@ -10,6 +10,8 @@
10
10
  *.gem
11
11
  *.key.pem
12
12
 
13
+ vendor/
14
+
13
15
  # rspec failure tracking
14
16
  .rspec_status
15
17
 
@@ -19,3 +21,4 @@
19
21
 
20
22
  test.rb
21
23
  .vscode
24
+ *.pem
@@ -0,0 +1,13 @@
1
+ ## https://github.com/rubocop-hq/rubocop/blob/master/config/default.yml
2
+ ##
3
+ Style/Documentation:
4
+ Enabled: false
5
+
6
+ require: rubocop-performance
7
+
8
+ AllCops:
9
+ Include:
10
+ - 'lib/**/*'
11
+ Metrics:
12
+ Exclude:
13
+ - 'spec/**/*'
@@ -1 +1 @@
1
- 2.6.3
1
+ 2.6.5
@@ -1,30 +1,40 @@
1
- sudo: false
2
1
  language: ruby
3
2
  cache:
4
3
  - bundler
4
+ - directories:
5
+ - vendor/
5
6
  rvm:
6
- - 2.4.3
7
- - 2.5.1
7
+ - 2.6
8
+ - 2.7
8
9
  before_script:
9
- - openssl aes-256-cbc -K $encrypted_2ddff5084a28_key -iv $encrypted_2ddff5084a28_iv -in trusona.key.pem.enc -out trusona.key.pem -d
10
+ - openssl req -utf8 -config trusona.cnf -new -verify -newkey rsa:4096 -days 1 -nodes -x509 -keyout trusona.key.pem -out trusona.pub.pem
10
11
  - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
11
12
  - chmod +x ./cc-test-reporter
12
13
  - ./cc-test-reporter before-build
13
14
  script:
14
- - bundle exec rspec spec -f p
15
- - bundle exec rubocop lib/**/*.rb -F
16
- - gem build trusona.gemspec
17
- after_script:
18
- - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
15
+ - bundle exec rspec -f p
16
+ - bundle exec rubocop lib
17
+ - bundle exec gem build trusona.gemspec --silent
18
+ after_success:
19
+ - if [[ $TRAVIS_PULL_REQUEST == false ]] && [[ $TRAVIS_BRANCH == master ]] && [[ $TRAVIS_JOB_NUMBER =~ ^.*.1$ ]]; then ./cc-test-reporter after-build -t simplecov --exit-code 0; fi
20
+ before_deploy:
21
+ - cp trusona-*.gem trusona.gem
22
+ - "echo ---$'\n':rubygems_api_key: $RUBYGEMS_API_KEY > ~/.gem/credentials"
23
+ - chmod 600 ~/.gem/credentials
19
24
  deploy:
20
- provider: rubygems
21
- api_key: $RUBYGEMS_API_KEY
22
- gem: trusona
23
- gemspec: trusona.gemspec
24
- skip_cleanup: true
25
+ provider: script
26
+ edge: true
27
+ script: gem push trusona.gem
28
+ cleanup: false
25
29
  on:
26
- tags: true
27
- rvm: '2.4.3'
30
+ branch: wip-deploy
31
+ rvm: '2.6'
32
+
33
+ # on:
34
+ # tags: true
35
+ # rvm: '2.6'
36
+ #
37
+
28
38
  notifications:
29
39
  slack:
30
40
  on_success: always
data/DEVELOP.md CHANGED
@@ -65,6 +65,17 @@ The token needs to belong to relying party id `5dfc5568-fbd3-4c1c-80f6-d0cf3d9ed
65
65
  Code coverage is calculated used `SimpleCov` and can be found in the `coverage`
66
66
  directory after running the tests
67
67
 
68
+ #### The console
69
+ There's a little console command you can use to test the SDK in `bin/console`. Just set the following environment variables in `.env`:
70
+
71
+ - `TRUSONA_API_HOST`
72
+ - `TRUSONA_SECRET`
73
+ - `TRUSONA_TOKEN`
74
+
75
+ Then run
76
+
77
+ `bundle exec bin/console`
78
+
68
79
  ### Deployment
69
80
 
70
81
  To deploy a new version of the gem to Artifactory, use `bump` to bump the
data/README.md CHANGED
@@ -4,7 +4,7 @@ Easily interact with the Trusona REST API.
4
4
 
5
5
  ## Current Status
6
6
 
7
- [![Build Status](https://travis-ci.com/lighthauz/trusona-server-sdk-ruby.svg?token=2f2CMAnop6pxz1LFFPky&branch=master)](https://travis-ci.com/lighthauz/trusona-server-sdk-ruby)
7
+ [![Build Status](https://travis-ci.com/trusona/trusona-server-sdk-ruby.svg?branch=master)](https://travis-ci.com/trusona/trusona-server-sdk-ruby)
8
8
  [![Maintainability](https://api.codeclimate.com/v1/badges/ec9f4f928125c278fa39/maintainability)](https://codeclimate.com/github/trusona/trusona-server-sdk-ruby/maintainability)
9
9
  [![Test Coverage](https://api.codeclimate.com/v1/badges/ec9f4f928125c278fa39/test_coverage)](https://codeclimate.com/github/trusona/trusona-server-sdk-ruby/test_coverage)
10
10
 
@@ -171,8 +171,9 @@ Note that the custom fields are not used in the case that the Trusonafication is
171
171
  | Prompt | `prompt` | N | Should the user be prompted to Accept or Reject this Trusonafication? Defaults to `true`. |
172
172
  | Expiration | `expires_at` | N | The ISO-8601 UTC timestamp of the Trusonafication's expiration. Defaults to 90 seconds from creation. |
173
173
  | Custom Fields | `custom_fields` | N | Arbitrary key-value data fields made available to the Trusonafication. Amount of data in the hash is limited to 1MB |
174
+ | Callback URL | `callback_url` | N | A HTTPS URL to POST to when the trusonafication has been completed (accepted, rejected, or expired).<br><br> **NOTE:** The URL should include a randomized segment so it cannot be guessed and abused by third-parties e.g. https://your.domain.com/completed_authentications/f8abe61d-4e51-493f-97b1-464c157624f2. |
174
175
 
175
- [^1]: You must provide at least one field that would allow Trusona to determine which user to authenticate. The identifier fields are `device_identifier`, `user_identifier`, and `trucode_id`.
176
+ [^1]: You must provide at least one field that would allow Trusona to determine which user to authenticate. The identifier fields are `device_identifier`, `user_identifier`, `email`, and `trucode_id`.
176
177
 
177
178
  #### Retrieving an existing Trusonafication
178
179
 
@@ -255,7 +256,7 @@ end
255
256
 
256
257
  ### TruCodes
257
258
 
258
- After a user has scanned a TruCode, it's possible to acquire that user's information by getting the
259
+ After a user has scanned a TruCode, it's possible to acquire that user's information by getting the
259
260
  scanned TruCode from the server. The code sample below shows how to do that:
260
261
 
261
262
  ```ruby
@@ -10,7 +10,6 @@ require 'trusona'
10
10
  # with your gem easier. You can also use a different console, if you like.
11
11
 
12
12
  Trusona.config do |c|
13
- c.beacons_host = ENV['BEACONS_HOST']
14
13
  c.api_host = ENV['TRUSONA_API_HOST']
15
14
  c.secret = ENV['TRUSONA_SECRET']
16
15
  c.token = ENV['TRUSONA_TOKEN']
@@ -0,0 +1,15 @@
1
+ require 'httparty'
2
+
3
+ class Buster
4
+ def initialize
5
+ @url = 'https://buster.staging.trusona.net'
6
+ end
7
+
8
+ def callback_url(id)
9
+ "#{@url}/callbacks/#{id}"
10
+ end
11
+
12
+ def callback_result(id)
13
+ HTTParty.get(callback_url(id))
14
+ end
15
+ end
@@ -7,9 +7,12 @@ SimpleCov.start do
7
7
  end
8
8
 
9
9
  require 'bundler/setup'
10
+ require 'active_support/core_ext/numeric/time'
11
+ require 'rspec/wait'
10
12
  require 'trusona'
11
13
  require 'securerandom'
12
14
  require 'webmock/rspec'
15
+ require_relative 'buster'
13
16
 
14
17
  WebMock.allow_net_connect!
15
18
 
@@ -12,6 +12,8 @@ RSpec.describe 'Trusonafications' do
12
12
  }
13
13
 
14
14
  @timeout = 5
15
+
16
+ @buster = Buster.new
15
17
  end
16
18
  describe 'creating a trusonafication for a known trusona user' do
17
19
  before do
@@ -40,10 +42,8 @@ RSpec.describe 'Trusonafications' do
40
42
  end
41
43
  end
42
44
  end
43
- describe 'creating a trusonafication for an unknown trusona user' do
45
+ describe 'creating a trusonafication without a level' do
44
46
  it 'as expected, does not work' do
45
- @parameters[:email] = "#{Time.now.to_i}@example.com"
46
-
47
47
  expect {
48
48
  Trusona::Trusonafication.create(
49
49
  params: @parameters, timeout: @timeout
@@ -51,5 +51,20 @@ RSpec.describe 'Trusonafications' do
51
51
  }.to raise_error(Trusona::InvalidResourceError)
52
52
  end
53
53
  end
54
+ describe 'creating a trusonafication with a callback url' do
55
+ it 'should POST to the URL when the trusonafication is completed' do
56
+ callback_id = SecureRandom.uuid
57
+
58
+ @parameters[:callback_url] = @buster.callback_url(callback_id)
59
+ @parameters[:expires_at] = 1.second.from_now
60
+
61
+ Trusona::EssentialTrusonafication.create(params: @parameters, timeout: @timeout)
62
+
63
+ wait_for do
64
+ callback_result = @buster.callback_result(callback_id)
65
+ callback_result.code
66
+ end.to eq(200)
67
+ end
68
+ end
54
69
  end
55
70
  # rubocop:enable Metrics/BlockLength
@@ -32,6 +32,7 @@ require 'trusona/workers/device_user_binding_creator'
32
32
  require 'trusona/workers/device_user_binding_activator'
33
33
  require 'trusona/workers/trusonafication_creator'
34
34
  require 'trusona/workers/trusonafication_finder'
35
+ require 'trusona/workers/trusonafication_canceler'
35
36
  require 'trusona/workers/identity_document_finder'
36
37
  require 'trusona/workers/device_finder'
37
38
  require 'trusona/workers/user_deactivator'
@@ -118,6 +119,7 @@ module Trusona
118
119
  end
119
120
 
120
121
  raise Trusona::ConfigurationError unless @config
122
+
121
123
  @config
122
124
  end
123
125
 
@@ -136,7 +138,7 @@ module Trusona
136
138
  attr_accessor :token, :secret
137
139
  attr_reader :api_host
138
140
 
139
- def initialize()
141
+ def initialize
140
142
  @api_host = 'api.trusona.net'
141
143
  end
142
144
 
@@ -22,7 +22,7 @@ module Trusona
22
22
  def headers
23
23
  @headers.merge(
24
24
  'x-date' => @date,
25
- 'Date' => @date,
25
+ 'Date' => @date,
26
26
  'X-Date' => @date,
27
27
  'Authorization' => @signature,
28
28
  'Content-Type' => determine_content_type
@@ -33,17 +33,20 @@ module Trusona
33
33
 
34
34
  def determine_content_type
35
35
  return '' if @method == 'GET' || @method == 'DELETE'
36
+
36
37
  Trusona::Api::HTTPClient::CONTENT_TYPE
37
38
  end
38
39
 
39
40
  def build_path(path)
40
41
  return path if @uri.query.nil? || @uri.query.empty?
42
+
41
43
  [@uri.path, @uri.query].join('?')
42
44
  end
43
45
 
44
46
  def build_uri(path, body)
45
47
  return build_uri_with_query(URI(path)) if URI(path).query
46
48
  return build_uri_with_body_as_query(path, body) if valid_hash_body(body)
49
+
47
50
  URI::HTTPS.build(host: @host, path: path)
48
51
  end
49
52
 
@@ -15,7 +15,9 @@ module Trusona
15
15
  end
16
16
 
17
17
  def to_h
18
- JSON.parse(@unverified.body) rescue {}
18
+ JSON.parse(@unverified.body)
19
+ rescue StandardError
20
+ {}
19
21
  end
20
22
 
21
23
  def verified?
@@ -50,6 +52,7 @@ module Trusona
50
52
 
51
53
  def parse_path(uri)
52
54
  return uri.path unless uri.query
55
+
53
56
  [uri.path, uri.query].join('?')
54
57
  end
55
58
 
@@ -61,6 +64,7 @@ module Trusona
61
64
  server = @unverified.headers['server']
62
65
  response_type = @unverified.headers['Content-Type']
63
66
  return response_type unless server == LEGACY_SERVER_HEADER
67
+
64
68
  determine_request_content_type
65
69
  end
66
70
 
@@ -69,6 +73,7 @@ module Trusona
69
73
  return default_type unless @unverified.request
70
74
  return default_type unless @unverified.request.options
71
75
  return default_type unless @unverified.request.options[:headers]
76
+
72
77
  @unverified.request.options[:headers]['Content-Type']
73
78
  end
74
79
 
@@ -28,11 +28,8 @@ module Trusona
28
28
  #
29
29
 
30
30
  def self.all(user_identifier: nil)
31
- # rubocop:disable Metrics/LineLength
32
31
  raise ArgumentError, 'A user identifier is required.' unless user_identifier
33
32
 
34
- # rubocop:enable Metrics/LineLength
35
-
36
33
  Trusona::Workers::IdentityDocumentFinder.new.find_all(user_identifier)
37
34
  end
38
35
 
@@ -55,11 +52,8 @@ module Trusona
55
52
  # Trusona::IdentityDocument.find('4FDF044D-89FB-4043-947D-A029CF785B5F')
56
53
  #
57
54
  def self.find(id: nil)
58
- # rubocop:disable Metrics/LineLength
59
55
  raise ArgumentError, 'An Identity Document identifier is required.' unless id
60
56
 
61
- # rubocop:enable Metrics/LineLength
62
-
63
57
  Trusona::Workers::IdentityDocumentFinder.new.find(id)
64
58
  end
65
59
  end
@@ -27,6 +27,7 @@ module Trusona
27
27
 
28
28
  def map_item(item, existing)
29
29
  return nil if item.nil? || item.empty?
30
+
30
31
  item = normalize_keys(item)
31
32
  item = merge_existing_state(item, existing.to_h)
32
33
  item = map_custom_fields(item)
@@ -40,6 +41,7 @@ module Trusona
40
41
 
41
42
  def map_custom_fields(response)
42
43
  return response if custom_mappings.nil? || custom_mappings.empty?
44
+
43
45
  custom_mappings.each do |original_key, new_key|
44
46
  value = response.delete(original_key)
45
47
  response[new_key] = value
@@ -51,17 +53,20 @@ module Trusona
51
53
  def response_invalid?(response)
52
54
  return true if response.nil?
53
55
  return true unless response.respond_to?(:to_h)
56
+
54
57
  false
55
58
  end
56
59
 
57
60
  def resource_invalid?(resource)
58
61
  return true if resource.nil?
59
62
  return true unless resource.respond_to?(:new)
63
+
60
64
  false
61
65
  end
62
66
 
63
67
  def existing_invalid?(existing)
64
68
  return true unless existing.respond_to?(:to_h)
69
+
65
70
  false
66
71
  end
67
72
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Trusona
4
4
  module Mappers
5
+ ## A Pair Trucode Mapper
5
6
  class PairedTruCodeMapper < BaseMapper
6
7
  def resource
7
8
  Trusona::Resources::PairedTruCode
@@ -17,7 +17,7 @@ module Trusona
17
17
  @params
18
18
  end
19
19
 
20
- def to_json
20
+ def to_json(*_args)
21
21
  JSON(to_h)
22
22
  end
23
23
 
@@ -23,6 +23,7 @@ module Trusona
23
23
  def validate
24
24
  return false unless @user_identifier
25
25
  return false unless @device_identifier
26
+
26
27
  true
27
28
  end
28
29
  end
@@ -11,7 +11,7 @@ module Trusona
11
11
 
12
12
  def initialize(params = {})
13
13
  normalized_params = normalize_keys(params)
14
- @id = normalized_params[:id]
14
+ @id = normalized_params[:id]
15
15
  @active = normalized_params[:active]
16
16
 
17
17
  @params = normalized_params
@@ -20,6 +20,7 @@ module Trusona
20
20
 
21
21
  def validate
22
22
  return false unless @id
23
+
23
24
  true
24
25
  end
25
26
  end
@@ -15,14 +15,14 @@ module Trusona
15
15
  normalized = normalize_keys(params)
16
16
 
17
17
  @params = normalized
18
- @document_hash = normalized[:document_hash]
19
- @id = normalized[:id]
20
- @type = normalized[:type]
18
+ @document_hash = normalized[:document_hash]
19
+ @id = normalized[:id]
20
+ @type = normalized[:type]
21
21
  @verification_status = normalized[:verification_status]
22
22
  @user_identifier = normalized[:user_identifier]
23
23
  end
24
24
 
25
- def to_json
25
+ def to_json(*_args)
26
26
  JSON(
27
27
  hash: @document_hash,
28
28
  id: @id,