grand_id_simple 0.2.0 → 1.0.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: e991889a4280b4b7dc7d30464d36a518d00314975c2f5fb8202f24274e3ed72d
4
- data.tar.gz: 8abf5b274f1710ecdce7f527bb723b2b0b8c01fe09ea31e9d9f85c6069096e04
3
+ metadata.gz: 3d4bd8555409124e1b9e3ada14c4d7f6fa1922a7e589638d6526fdc0667a26db
4
+ data.tar.gz: 3a7b8476abf8a14266553bc18645a2935f4e44889d75dfb2bb27a8fcef4c8b33
5
5
  SHA512:
6
- metadata.gz: 100ec89f31208b95ed4715b502cf64899f7e4927d9b8b8fecaafc13fbf6f4fc4b3657a504e7a30bb78b3ec4edba6c87cd2192ac2a35a16cdc13ea3bc4f3947bc
7
- data.tar.gz: 8c2999ffe9841ead0d6fad056b5de425478d8348739ece4dddc42ac141ad5ad70f015bc038e2ec63320d3e81ea31913d3542a2d9a0484c61541aa44e7b653724
6
+ metadata.gz: 641b56153b7fc523839e059d41f5846ecc5ae440e191573e4ff2721aa1cbe62b3ee7370616bcaae5e1234c02de62f69163d85203b597b611d47e509d35476d9b
7
+ data.tar.gz: fc1aa93521ee825fdd21e99fae60f8dc73fec98794c5d90143b24a1d0deff0c52049f4d13616c311349857d0f99685f768334e35a730929d55c0020d43ed32d5
data/.rubocop.yml CHANGED
@@ -1,6 +1,3 @@
1
- require:
2
- rubocop-rake
3
-
4
1
  inherit_gem:
5
2
  rubocop_fonsan_style:
6
3
  - .rubocop.yml
data/Gemfile CHANGED
@@ -9,4 +9,6 @@ gem 'oj'
9
9
  gem 'rake', '~> 13.0'
10
10
  gem 'rspec', '~> 3.0'
11
11
  gem 'rubocop_fonsan_style'
12
+ gem 'sinatra'
12
13
  gem 'typhoeus'
14
+ gem 'webrick'
data/Gemfile.lock CHANGED
@@ -1,36 +1,68 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grand_id_simple (0.2.0)
4
+ grand_id_simple (1.0.0)
5
+ sinatra (~> 2.2)
5
6
  typhoeus (~> 1.4)
7
+ webrick (~> 1.8)
6
8
 
7
9
  GEM
8
10
  remote: https://rubygems.org/
9
11
  specs:
10
- activesupport (7.0.4)
11
- concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ activesupport (8.0.0)
13
+ base64
14
+ benchmark (>= 0.3)
15
+ bigdecimal
16
+ concurrent-ruby (~> 1.0, >= 1.3.1)
17
+ connection_pool (>= 2.2.5)
18
+ drb
12
19
  i18n (>= 1.6, < 2)
20
+ logger (>= 1.4.2)
13
21
  minitest (>= 5.1)
14
- tzinfo (~> 2.0)
22
+ securerandom (>= 0.3)
23
+ tzinfo (~> 2.0, >= 2.0.5)
24
+ uri (>= 0.13.1)
15
25
  ast (2.4.2)
16
- concurrent-ruby (1.1.10)
26
+ base64 (0.2.0)
27
+ benchmark (0.4.0)
28
+ bigdecimal (3.1.8)
29
+ concurrent-ruby (1.3.4)
30
+ connection_pool (2.4.1)
17
31
  diff-lcs (1.5.0)
32
+ drb (2.2.1)
18
33
  ethon (0.16.0)
19
34
  ffi (>= 1.15.0)
20
35
  ffi (1.15.5)
21
- i18n (1.12.0)
36
+ haml (6.3.0)
37
+ temple (>= 0.8.2)
38
+ thor
39
+ tilt
40
+ haml_lint (0.59.0)
41
+ haml (>= 5.0)
42
+ parallel (~> 1.10)
43
+ rainbow
44
+ rubocop (>= 1.0)
45
+ sysexits (~> 1.1)
46
+ i18n (1.14.6)
22
47
  concurrent-ruby (~> 1.0)
23
- json (2.6.2)
24
- minitest (5.16.3)
48
+ json (2.8.2)
49
+ language_server-protocol (3.17.0.3)
50
+ logger (1.6.1)
51
+ minitest (5.25.2)
52
+ mustermann (2.0.2)
53
+ ruby2_keywords (~> 0.0.1)
25
54
  oj (3.13.23)
26
- parallel (1.22.1)
27
- parser (3.1.3.0)
55
+ parallel (1.26.3)
56
+ parser (3.3.6.0)
28
57
  ast (~> 2.4.1)
29
- rack (3.0.1)
58
+ racc
59
+ racc (1.8.1)
60
+ rack (2.2.10)
61
+ rack-protection (2.2.4)
62
+ rack
30
63
  rainbow (3.1.1)
31
64
  rake (13.0.6)
32
- regexp_parser (2.6.1)
33
- rexml (3.2.5)
65
+ regexp_parser (2.9.2)
34
66
  rspec (3.12.0)
35
67
  rspec-core (~> 3.12.0)
36
68
  rspec-expectations (~> 3.12.0)
@@ -44,46 +76,60 @@ GEM
44
76
  diff-lcs (>= 1.2.0, < 2.0)
45
77
  rspec-support (~> 3.12.0)
46
78
  rspec-support (3.12.0)
47
- rubocop (1.39.0)
79
+ rubocop (1.68.0)
48
80
  json (~> 2.3)
81
+ language_server-protocol (>= 3.17.0)
49
82
  parallel (~> 1.10)
50
- parser (>= 3.1.2.1)
83
+ parser (>= 3.3.0.2)
51
84
  rainbow (>= 2.2.2, < 4.0)
52
- regexp_parser (>= 1.8, < 3.0)
53
- rexml (>= 3.2.5, < 4.0)
54
- rubocop-ast (>= 1.23.0, < 2.0)
85
+ regexp_parser (>= 2.4, < 3.0)
86
+ rubocop-ast (>= 1.32.2, < 2.0)
55
87
  ruby-progressbar (~> 1.7)
56
- unicode-display_width (>= 1.4.0, < 3.0)
57
- rubocop-ast (1.23.0)
58
- parser (>= 3.1.1.0)
59
- rubocop-performance (1.15.1)
60
- rubocop (>= 1.7.0, < 2.0)
61
- rubocop-ast (>= 0.4.0)
62
- rubocop-rails (2.17.3)
88
+ unicode-display_width (>= 2.4.0, < 3.0)
89
+ rubocop-ast (1.36.1)
90
+ parser (>= 3.3.1.0)
91
+ rubocop-performance (1.23.0)
92
+ rubocop (>= 1.48.1, < 2.0)
93
+ rubocop-ast (>= 1.31.1, < 2.0)
94
+ rubocop-rails (2.27.0)
63
95
  activesupport (>= 4.2.0)
64
96
  rack (>= 1.1)
65
- rubocop (>= 1.33.0, < 2.0)
66
- rubocop-rake (0.6.0)
67
- rubocop (~> 1.0)
68
- rubocop-rspec (2.15.0)
69
- rubocop (~> 1.33)
97
+ rubocop (>= 1.52.0, < 2.0)
98
+ rubocop-ast (>= 1.31.1, < 2.0)
99
+ rubocop-rspec (3.2.0)
100
+ rubocop (~> 1.61)
70
101
  rubocop-rubycw (0.1.6)
71
102
  rubocop (~> 1.0)
72
- rubocop_fonsan_style (0.1.0)
73
- rubocop (~> 1.39)
74
- rubocop-performance (~> 1.15)
75
- rubocop-rails (~> 2.17)
76
- rubocop-rake (~> 0.6.0)
77
- rubocop-rspec (~> 2.15)
103
+ rubocop_fonsan_style (0.1.8)
104
+ haml_lint (~> 0.52)
105
+ rubocop (~> 1.68)
106
+ rubocop-performance (~> 1.22)
107
+ rubocop-rails (~> 2.27)
108
+ rubocop-rspec (~> 3.2)
78
109
  rubocop-rubycw (~> 0.1)
79
- ruby-progressbar (1.11.0)
110
+ ruby-progressbar (1.13.0)
111
+ ruby2_keywords (0.0.5)
112
+ securerandom (0.3.2)
113
+ sinatra (2.2.4)
114
+ mustermann (~> 2.0)
115
+ rack (~> 2.2)
116
+ rack-protection (= 2.2.4)
117
+ tilt (~> 2.0)
118
+ sysexits (1.2.0)
119
+ temple (0.10.3)
120
+ thor (1.3.2)
121
+ tilt (2.1.0)
80
122
  typhoeus (1.4.0)
81
123
  ethon (>= 0.9.0)
82
- tzinfo (2.0.5)
124
+ tzinfo (2.0.6)
83
125
  concurrent-ruby (~> 1.0)
84
- unicode-display_width (2.3.0)
126
+ unicode-display_width (2.6.0)
127
+ uri (1.0.2)
128
+ webrick (1.8.1)
85
129
 
86
130
  PLATFORMS
131
+ arm64-darwin-22
132
+ arm64-darwin-23
87
133
  x86_64-darwin-20
88
134
  x86_64-darwin-22
89
135
  x86_64-linux
@@ -94,7 +140,9 @@ DEPENDENCIES
94
140
  rake (~> 13.0)
95
141
  rspec (~> 3.0)
96
142
  rubocop_fonsan_style
143
+ sinatra
97
144
  typhoeus
145
+ webrick
98
146
 
99
147
  BUNDLED WITH
100
148
  2.3.26
data/README.md CHANGED
@@ -16,7 +16,28 @@ If bundler is not being used to manage dependencies, install the gem by executin
16
16
 
17
17
  ## Usage
18
18
 
19
- TODO: Write usage instructions here
19
+
20
+ ```bash
21
+ GRAND_ID_API_KEY='123' GRAND_ID_SERVICE_KEY='467' ruby some_app.rb
22
+ ```
23
+
24
+ ```ruby
25
+ api_key, service_key = ENV.values_at('GRAND_ID_API_KEY', 'GRAND_ID_SERVICE_KEY')
26
+
27
+ grand_id_simple = GrandIdSimple.new(api_key, service_key)
28
+
29
+ grand_id_simple.federated_login(your_callback_url)
30
+ # or if you know the personal number and would like to extend the courtesy of not having to scan qr code or manually fill
31
+ login = grand_id_simple.federated_login(your_callback_url, personal_number: '198801010101')
32
+ # => #<struct GrandIdSimple::Login session_id="123", redirect_url="https://grandid.se/redirect....">
33
+ # redirect your user
34
+ redirect_to(login.redirect_url)
35
+
36
+ # Then when you receive the callback:
37
+
38
+ person = grand_id_simple.get_session(params[:grandidsession])
39
+ # => #<struct GrandIdSimple::Person personal_number="198801010101", name="Greta Musk", given_name="Greta", surname="Musk", ip_address=...>
40
+ ```
20
41
 
21
42
  ## Development
22
43
 
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+ require 'webrick'
5
+ require 'grand_id_simple'
6
+ require 'sinatra/base'
7
+
8
+ class FakeGrandIdSimple < GrandIdSimple
9
+ class FakePerson < Person
10
+ def session_id
11
+ @session_id ||= Digest::SHA256.hexdigest(rand.to_s)
12
+ end
13
+
14
+ def name
15
+ "#{given_name} #{surname}"
16
+ end
17
+ end
18
+
19
+ def self.add_query_parameter(url, name, value)
20
+ uri = URI.parse(url)
21
+ new_query_ar = URI.decode_www_form(uri.query || '') << [name, value]
22
+ uri.query = URI.encode_www_form(new_query_ar)
23
+ uri.to_s
24
+ end
25
+
26
+ def initialize(&block)
27
+ super(nil, nil)
28
+ @block = block
29
+ @people = []
30
+ @server = WEBrick::HTTPServer.new(Port: 0)
31
+ @app = Sinatra.new do
32
+ get '/' do
33
+ return redirect params[:callback_url] if params[:session_id]
34
+
35
+ settings.people.map do |person|
36
+ %(<a href="#{FakeGrandIdSimple.add_query_parameter(params[:callback_url], 'grandidsession', person.session_id)}">#{person.name}</a><br/>)
37
+ end.join
38
+ end
39
+ end
40
+ @app.set :people, @people
41
+ @server.mount('/', Rack::Handler::WEBrick, @app)
42
+ @base_url = "http://localhost:#{@server.config[:Port]}"
43
+ end
44
+
45
+ def start!
46
+ @server_thread = Thread.start { @server.start }
47
+ end
48
+
49
+ def federated_login(**options)
50
+ @people.concat(@block.call) if @people.empty?
51
+ redirect_url = FakeGrandIdSimple.add_query_parameter(@base_url, 'callback_url', options[:callbackUrl])
52
+ Login.new(redirect_url: redirect_url)
53
+ end
54
+
55
+ def get_session(session_id)
56
+ @people.find {|person| person.session_id == session_id }
57
+ end
58
+
59
+ def logout(_session_id)
60
+ Logout.new(sessiondeleted: true)
61
+ end
62
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class GrandIdSimple
4
- VERSION = '0.2.0'
4
+ VERSION = '1.0.1'
5
5
  end
@@ -26,6 +26,8 @@ class GrandIdSimple
26
26
  :not_after,
27
27
  :signature,
28
28
  :ocsp_response,
29
+ :uhi,
30
+ :bank_id_issue_date,
29
31
  keyword_init: true,
30
32
  )
31
33
 
@@ -46,29 +48,40 @@ class GrandIdSimple
46
48
  @base_url = base_url
47
49
  end
48
50
 
49
- def federated_login(callback_url, personal_number: nil)
51
+ # callbackUrl string Optional Where to return end-user after completion.
52
+ # customerURL string Optional Where to return end-user if they press the back button.
53
+ # userVisibleData base64 Optional Visible data for the end-user to sign.
54
+ # userNonVisibleData base64 Optional Hidden data included in the signature.
55
+ # userVisibleDataFormat string Optional Used to format the visible signature data.
56
+ # authMessage base64 Optional Visible data for the end-user to auth.
57
+ # mobileBankId bool Optional Set to true to force usage of a Mobile BankID.
58
+ # desktopBankId bool Optional Set to true to force usage of a Desktop BankID.
59
+ # thisDevice bool Optional Set to true to allow usage of the end-users current device
60
+ # qr bool Optional Set to true to allow authentication/signing using a QR code
61
+ # allowFingerprintAuth string Optional Set whether usage of fingerprint biometrics is allowed with the authentication.
62
+ # allowFingerprintSign string Optional Set whether usage of fingerprint biometrics is allowed with the signature.
63
+ # gui string Optional Set to false to opt out of GrandID’s user interface and build your custom implementation.
64
+ # appRedirect string Optional Can be used to force a redirect to specific application from the BankID application.
65
+
66
+ def federated_login(**options)
50
67
  body = call_api(
51
68
  :FederatedLogin,
52
69
  method: :post,
53
70
  body: {
54
- thisDevice: false,
55
- askForSSN: !personal_number,
56
- personalNumber: personal_number,
57
- qr: true,
58
- callbackUrl: callback_url,
71
+ **options,
59
72
  },
60
73
  )
61
- Login.new(lower_keys(body))
74
+ Login.new(body)
62
75
  end
63
76
 
64
77
  def get_session(session_id)
65
78
  body = call_api(:GetSession, params: {sessionId: session_id})
66
- Person.new(lower_keys(body[:userAttributes]))
79
+ Person.new(body[:user_attributes])
67
80
  end
68
81
 
69
82
  def logout(session_id)
70
83
  body = call_api(:Logout, params: {sessionId: session_id})
71
- Logout.new(lower_keys(body))
84
+ Logout.new(body)
72
85
  end
73
86
 
74
87
  private
@@ -81,10 +94,10 @@ class GrandIdSimple
81
94
  body: body,
82
95
  )
83
96
  response = request.run
84
- body = Oj.load(response.body, symbol_keys: true)
97
+ body = json_load(response.body)
85
98
  raise StandardError, 'no body' unless body
86
- if error_object = body[:errorObject]
87
- raise Error.new(*lower_keys(error_object).values_at(:code, :message))
99
+ if error_object = body[:error_object]
100
+ raise Error.new(*error_object.values_at(:code, :message))
88
101
  end
89
102
 
90
103
  body
@@ -97,8 +110,26 @@ class GrandIdSimple
97
110
  }
98
111
  end
99
112
 
100
- def lower_keys(hash)
101
- hash.transform_keys {|k| k.to_s.gsub(/([a-z])([A-Z]+)/, '\1_\2').downcase.to_sym }
113
+ def json_load(body)
114
+ deep_underscore_keys(Oj.load(body, symbol_keys: true))
115
+ end
116
+
117
+ def deep_underscore_keys(hash)
118
+ deep_transform_keys(hash) {|key| key.to_s.gsub(/([a-z])([A-Z]+)/, '\1_\2').downcase.to_sym }
119
+ end
120
+
121
+ def deep_transform_keys(hash, &block)
122
+ hash.each_with_object({}) do |(key, value), result|
123
+ new_key = yield(key)
124
+ new_value = if value.is_a?(Hash)
125
+ deep_transform_keys(value, &block)
126
+ elsif value.is_a?(Array)
127
+ value.map {|item| item.is_a?(Hash) ? deep_transform_keys(item, &block) : item }
128
+ else
129
+ value
130
+ end
131
+ result[new_key] = new_value
132
+ end
102
133
  end
103
134
 
104
135
  def url(call)
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grand_id_simple
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fonsan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-19 00:00:00.000000000 Z
11
+ date: 2024-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sinatra
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.2'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: typhoeus
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +38,20 @@ dependencies:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
40
  version: '1.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: webrick
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.8'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.8'
27
55
  description: A simple wrapper around the grandid api
28
56
  email:
29
57
  - fonsan@gmail.com
@@ -40,7 +68,7 @@ files:
40
68
  - LICENSE.txt
41
69
  - README.md
42
70
  - Rakefile
43
- - grand_id_simple.gemspec
71
+ - lib/fake_grand_id_simple.rb
44
72
  - lib/grand_id_simple.rb
45
73
  - lib/grand_id_simple/version.rb
46
74
  - sig/grand_id_simple.rbs
@@ -60,14 +88,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
60
88
  requirements:
61
89
  - - ">="
62
90
  - !ruby/object:Gem::Version
63
- version: 2.6.0
91
+ version: 3.0.0
64
92
  required_rubygems_version: !ruby/object:Gem::Requirement
65
93
  requirements:
66
94
  - - ">="
67
95
  - !ruby/object:Gem::Version
68
96
  version: '0'
69
97
  requirements: []
70
- rubygems_version: 3.3.26
98
+ rubygems_version: 3.5.23
71
99
  signing_key:
72
100
  specification_version: 4
73
101
  summary: grandid wrapper
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'lib/grand_id_simple/version'
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = 'grand_id_simple'
7
- spec.version = GrandIdSimple::VERSION
8
- spec.authors = ['Fonsan']
9
- spec.email = ['fonsan@gmail.com']
10
-
11
- spec.summary = 'grandid wrapper'
12
- spec.description = 'A simple wrapper around the grandid api'
13
- spec.homepage = 'https://github.com/Fonsan/grand_id_simple'
14
- spec.license = 'MIT'
15
- spec.required_ruby_version = '>= 2.6.0'
16
-
17
- spec.metadata['homepage_uri'] = spec.homepage
18
- spec.metadata['source_code_uri'] = spec.homepage
19
- spec.metadata['changelog_uri'] = "#{spec.homepage}/CHANGELOG.md"
20
-
21
- # Specify which files should be added to the gem when it is released.
22
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
- `git ls-files -z`.split("\x0").reject do |f|
25
- (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
26
- end
27
- end
28
- spec.bindir = 'exe'
29
- spec.executables = spec.files.grep(%r{\Aexe/}) {|f| File.basename(f) }
30
- spec.require_paths = ['lib']
31
-
32
- # Uncomment to register a new dependency of your gem
33
- spec.add_dependency "typhoeus", "~> 1.4"
34
-
35
- # For more information and examples about making a new gem, check out our
36
- # guide at: https://bundler.io/guides/creating_gem.html
37
- spec.metadata['rubygems_mfa_required'] = 'true'
38
- end