omniauth-realme 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,3 +2,50 @@
2
2
 
3
3
  require 'omniauth/realme/version'
4
4
  require 'omniauth/strategies/realme'
5
+
6
+ module OmniAuth
7
+ module Realme # :nodoc:
8
+ class Error < StandardError; end
9
+
10
+ ##
11
+ # Generates SAML SP metadata XML using the same settings you used to
12
+ # configure the OmniAuth strategy. This XML is suitable for uploading to
13
+ # Realme at https://mts.realme.govt.nz/logon-mts/metadataupdate
14
+ #
15
+ # @param [Hash] options - An optional Hash of options to configure the
16
+ # strategy. This is convenient for testing but is
17
+ # not required during normal operation because the
18
+ # strategy will already be configured by the Rails
19
+ # initializer.
20
+ # @return [String] SP metadata serialized as an XML string
21
+ #
22
+ def self.generate_metadata_xml(options: {})
23
+ meta = OneLogin::RubySaml::Metadata.new
24
+
25
+ # OmniAuth strategies are Rack middlewares. When an instance of a rack
26
+ # middleware is created it is given a reference to the next rack
27
+ # app/middleware in the chain. We are only interested here in getting the
28
+ # SAML settings out of the strategy. We don't hit any code paths which
29
+ # would require a real rack app/middleware so `nil` works just fine.
30
+ rack_app = nil
31
+
32
+ # The Rails initializer calls `OmniAuth::Strategies::Realme.configure`
33
+ # which merges the provided block into the default options for
34
+ # `OmniAuth::Strategies::Realme` - use
35
+ # `OmniAuth::Strategies::Realme.default_options` to inspect the current
36
+ # state of these options.
37
+ #
38
+ # This means that the `options` we pass in here will be merged into (and
39
+ # override) those default options.
40
+ #
41
+ # When this method is called by app code, we want to use the options set
42
+ # by the Rails initializer so pass an empty hash as `options`. When this
43
+ # method is called by its specs, no Rails initializer has run so we need
44
+ # to pass in some options.
45
+ #
46
+ strategy = OmniAuth::Strategies::Realme.new(rack_app, options)
47
+
48
+ meta.generate(strategy.saml_settings)
49
+ end
50
+ end
51
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Omniauth
3
+ module OmniAuth
4
4
  module Realme
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'
6
6
  end
7
7
  end
@@ -6,47 +6,268 @@ require 'ruby-saml'
6
6
  module OmniAuth
7
7
  module Strategies
8
8
  class Realme
9
+ class Error < StandardError; end
10
+ class RelayStateTooLongError < Error; end
11
+
12
+ ##
13
+ # Create an exception for each documented Realme error
14
+ # (https://developers.realme.govt.nz/how-realme-works/realme-saml-exception-handling/).
15
+ #
16
+ # All the errors we raise inherit from `OmniAuth::Strategies::Realme::Error`
17
+ # so a caller can rescue that if they want to rescue all exceptions from
18
+ # this class.
19
+ #
20
+ class RealmeAuthnFailedError < Error; end
21
+ class RealmeInternalError < Error; end
22
+ class RealmeInternalError < Error; end
23
+ class RealmeNoAvailableIDPError < Error; end
24
+ class RealmeNoPassiveError < Error; end
25
+ class RealmeRequestDeniedError < Error; end
26
+ class RealmeRequestUnsupportedError < Error; end
27
+ class RealmeTimeoutError < Error; end
28
+ class RealmeUnknownPrincipalError < Error; end
29
+ class RealmeUnrecognisedError < Error; end
30
+ class RealmeUnsupportedBindingError < Error; end
31
+
9
32
  include OmniAuth::Strategy
10
- autoload :AuthRequest, 'omniauth/strategies/realme/auth_request'
33
+
34
+ RCMS_LAT_NAME = 'urn:nzl:govt:ict:stds:authn:safeb64:logon_attributes_jwt'
35
+
36
+ # The SAML spec says the maximum length of the RelayState is 80
37
+ # bytes. See section 3.4.3 of
38
+ # http://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf
39
+ MAX_LENGTH_OF_RELAY_STATE = 80 # bytes
11
40
 
12
41
  # Fixed OmniAuth options
13
42
  option :provider, 'realme'
14
43
 
15
44
  def request_phase
45
+ req_options = { 'SigAlg' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' }
46
+
47
+ ##
48
+ # If we recieved a `relay_state` param e.g. we were invoked like:
49
+ #
50
+ # redirect_to user_realme_omniauth_authorize_path(relay_state: 'some_value')
51
+ #
52
+ # then we pass it to Realme (via RubySaml). Realme (as a SAML IdP)
53
+ # should return that value unaltered when it redirects back to this
54
+ # application and `#callback_phase` below is executed.
55
+ #
56
+ if request.params['relay_state']
57
+ if request.params['relay_state'].length > MAX_LENGTH_OF_RELAY_STATE
58
+ ex = RelayStateTooLongError.new('RelayState exceeds SAML spec max length of 80 bytes')
59
+
60
+ # fail!() returns a rack response which this callback must also
61
+ # return if OmniAuth error handling is to work correctly.
62
+ return fail!(create_label_for(ex), ex)
63
+ end
64
+
65
+ req_options['RelayState'] = request.params['relay_state']
66
+ end
67
+
16
68
  req = OneLogin::RubySaml::Authrequest.new
17
- redirect req.create(saml_settings, 'SigAlg' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256')
69
+ redirect req.create(saml_settings, req_options)
18
70
  end
19
71
 
20
- def callback_phase
21
- response = ::OneLogin::RubySaml::Response.new(request.params['SAMLResponse'], settings: saml_settings)
72
+ def callback_phase # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/AbcSize
73
+ response = ::OneLogin::RubySaml::Response.new(request.params['SAMLResponse'],
74
+ settings: saml_settings,
75
+ allowed_clock_drift: allowed_clock_drift)
76
+
77
+ ##
78
+ # `RelayState` is an arbitrary string (length < 80 characters). If we
79
+ # sent it to Realme with the SAMLRequest then Realme will return it unaltered.
80
+ #
81
+ # If we receive any relay state then we save it.
82
+ #
83
+ @relay_state = request.params['RelayState'] if request.params['RelayState']
22
84
 
85
+ # If the Realme Context Mapping Service (RCMS) is enabled in Realme
86
+ # for our app then we will get a RCMS Login Access Token in the
87
+ # SAMLResponse.
88
+ #
89
+ # We save the token if it exists. See
90
+ # https://developers.realme.govt.nz/how-realme-works/whats-realme-rcms/
91
+ #
23
92
  if response.is_valid?
24
- session[:uid] = response.nameid
93
+ @realme_cms_lat = response.attributes[RCMS_LAT_NAME] if response.attributes[RCMS_LAT_NAME]
94
+ end
95
+
96
+ if legacy_rails_session_behaviour_enabled?
97
+ OmniAuth.logger.info "Deprecation: omniauth-realme will stop putting values via Rails `session` in a future version. Use request.env['omniauth.auth'] instead." # rubocop:disable Layout/LineLength
98
+
99
+ if response.is_valid?
100
+ session[:uid] = response.nameid
101
+ else
102
+ session[:realme_error] = {
103
+ error: response.errors.join[/=> (\S+) ->/, 1],
104
+ message: default_error_messages_for_rails_session(response.errors.join)
105
+ }
106
+ end
25
107
  else
26
- authorize_failure
108
+ if response.is_valid? # rubocop:disable Style/IfInsideElse
109
+ @uid = response.nameid
110
+ else
111
+ ex = create_exception_for(status_code: response.status_code, message: response.status_message.strip)
112
+
113
+ # fail!() returns a rack response which this callback must also
114
+ # return if OmniAuth error handling is to work correctly.
115
+ return fail!(create_label_for(ex), ex)
116
+ end
27
117
  end
28
118
 
29
- @raw_info = response
30
119
  super
31
120
  end
32
121
 
33
- private
122
+ ##
123
+ # The `credentials` Hash will be placed within the `request["omniauth.auth"]`
124
+ # Hash that `OmniAuth::Strategy` builds. See
125
+ # https://github.com/omniauth/omniauth/wiki/Auth-Hash-Schema
126
+ #
127
+ # `credentials` contains any extra credentials information about the user
128
+ # that we received from the authentication service (Realme) e.g. an RCMS
129
+ # token if it exists.
130
+ #
131
+ credentials do
132
+ output = {}
133
+ output[:realme_cms_lat] = @realme_cms_lat if @realme_cms_lat
134
+ output
135
+ end
136
+
137
+ ##
138
+ # The `extra` Hash will be placed within the `request["omniauth.auth"]`
139
+ # Hash that `OmniAuth::Strategy` builds. See
140
+ # https://github.com/omniauth/omniauth/wiki/Auth-Hash-Schema
141
+ #
142
+ # `extra` contains anything which isn't information about the user or a
143
+ # user credential.
144
+ #
145
+ extra do
146
+ output = {}
147
+ output[:relay_state] = @relay_state if @relay_state
148
+ output
149
+ end
150
+
151
+ ##
152
+ # Return the `uid` (User ID) value in a way that allows
153
+ # OmniAuth::Strategy to place it in the `request["omniauth.auth"]` Hash
154
+ # that it builds. See
155
+ # https://github.com/omniauth/omniauth/wiki/Auth-Hash-Schema
156
+ #
157
+ uid do
158
+ @uid
159
+ end
34
160
 
35
- def saml_settings
161
+ def saml_settings # rubocop:disable Metrics/AbcSize
36
162
  idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
37
163
  settings = idp_metadata_parser.parse(File.read(options.fetch('idp_service_metadata')))
38
164
 
39
- settings.issuer = options.fetch('issuer')
40
- settings.assertion_consumer_service_url = options.fetch('assertion_consumer_service_url')
41
- settings.private_key = options.fetch('private_key')
42
- settings.authn_context = options.fetch('auth_strenght', 'urn:nzl:govt:ict:stds:authn:deployment:GLS:SAML:2.0:ac:classes:LowStrength')
43
- settings.protocol_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
44
- settings.assertion_consumer_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
45
- settings.soft = false
165
+ settings.issuer = options.fetch('issuer')
166
+ settings.assertion_consumer_service_url = options.fetch('assertion_consumer_service_url')
167
+ settings.attributes_index = options.fetch('attributes_index', '0')
168
+ settings.private_key = options.fetch('private_key')
169
+ settings.authn_context = options.fetch('auth_strength', 'urn:nzl:govt:ict:stds:authn:deployment:GLS:SAML:2.0:ac:classes:LowStrength')
170
+ settings.protocol_binding = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
171
+ settings.assertion_consumer_service_binding = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
172
+ settings.soft = !options.fetch('raise_exceptions_for_saml_validation_errors', false)
173
+
174
+ settings.security[:authn_requests_signed] = true
175
+
176
+ ##
177
+ # Realme error if this is missing from the metadata
178
+ #
179
+ # WantAssertionsSigned must be true (MTS-002)
180
+ #
181
+ settings.security[:want_assertions_signed] = true
182
+
183
+ ##
184
+ # Realme MTS requires our Metadata XML to have both:
185
+ #
186
+ # <md:KeyDescriptor use="signing">...</md:KeyDescriptor>
187
+ # <md:KeyDescriptor use="encryption">...</md:KeyDescriptor>
188
+ #
189
+ # in the metadata XML we submit. We need to set a certificate **and**
190
+ # set `:want_assertions_encrypted` for ruby-saml to include these
191
+ # elements.
192
+ #
193
+ settings.certificate = options.fetch('certificate')
194
+ settings.security[:want_assertions_encrypted] = true
195
+
196
+ settings
197
+ end
46
198
 
47
- settings.security[:authn_requests_signed] = true
199
+ private
48
200
 
49
- settings
201
+ ##
202
+ # Realme documents the various error conditions it can return:
203
+ #
204
+ # https://developers.realme.govt.nz/how-realme-works/realme-saml-exception-handling/
205
+ #
206
+ def create_exception_for(status_code:, message:) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
207
+ case status_code
208
+ when /status:Timeout\z/
209
+ RealmeTimeoutError.new(message)
210
+ when /status:InternalError\z/
211
+ RealmeInternalError.new(message)
212
+ when /status:AuthnFailed\z/
213
+ RealmeAuthnFailedError.new(message)
214
+ when /status:NoAvailableIDP\z/
215
+ RealmeNoAvailableIDPError.new(message)
216
+ when /status:NoPassive\z/
217
+ RealmeNoPassiveError.new(message)
218
+ when /status:RequestDenied\z/
219
+ RealmeRequestDeniedError.new(message)
220
+ when /status:RequestUnsupported\z/
221
+ RealmeRequestUnsupportedError.new(message)
222
+ when /status:UnknownPrincipal\z/
223
+ RealmeUnknownPrincipalError.new(message)
224
+ when /status:UnsupportedBinding\z/
225
+ RealmeUnsupportedBindingError.new(message)
226
+ else
227
+ RealmeUnrecognisedError.new("Realme login service returned an unrecognised error. status_code=#{status_code} message=#{message}")
228
+ end
229
+ end
230
+
231
+ ##
232
+ # The OmniAuth failure endpoint requires us to pass an instance of an
233
+ # Exception and a String|Symbol describing the error. This method builds
234
+ # a simple description based on class of the exception.
235
+ #
236
+ # This gem can be used in any Rack environment so we don't use any Rails
237
+ # specific text wrangling methods
238
+ #
239
+ # @param [Exception] exception The exception to describe
240
+ # @return [String] The label describing the exception
241
+ #
242
+ def create_label_for(exception)
243
+ exception.class.to_s.gsub('::', '_')
244
+ end
245
+
246
+ def allowed_clock_drift
247
+ options.fetch('allowed_clock_drift', 0)
248
+ end
249
+
250
+ def legacy_rails_session_behaviour_enabled?
251
+ options.fetch('legacy_rails_session_behaviour_enabled', true)
252
+ end
253
+
254
+ def default_error_messages_for_rails_session(error)
255
+ case error
256
+ when /Timeout/
257
+ '<p>Your RealMe session has expired due to inactivity.</p>'
258
+ when /NoAvailableIDP/
259
+ "<p>RealMe reported that the TXT service, Google Authenticator or the RealMe token service is not available.</p>
260
+ <p>You may try again later. If the problem persists, please contact RealMe Help <a href='tel:'0800664774>0800 664 774</a>.</p>"
261
+ when /AuthnFailed/
262
+ '<p>You have chosen to leave the RealMe login screen without completing the login process.</p>'
263
+ when /InternalError/
264
+ "<p>RealMe was unable to process your request due to a RealMe internal error.</p>
265
+ <p>Please try again. If the problem persists, please contact RealMe Help Desk on <a href='tel:'0800664774>0800 664 774</a>.</p>"
266
+ else
267
+ "<p>RealMe reported a serious application error with the message:</p>
268
+ <p>#{error}</p>
269
+ <p>Please try again later. If the problem persists, please contact RealMe Help Desk on <a href='tel:'0800664774>0800 664 774</a>.</p>"
270
+ end
50
271
  end
51
272
  end
52
273
  end
@@ -1,33 +1,42 @@
1
-
2
1
  # frozen_string_literal: true
3
2
 
4
- lib = File.expand_path('lib', __dir__)
5
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
- require 'omniauth/realme/version'
3
+ require_relative 'lib/omniauth/realme/version'
7
4
 
8
5
  Gem::Specification.new do |spec|
9
6
  spec.name = 'omniauth-realme'
10
- spec.version = Omniauth::Realme::VERSION
11
- spec.authors = ['DanHenton']
12
- spec.email = ['Dan.henton@live.com']
7
+ spec.version = OmniAuth::Realme::VERSION
8
+ spec.authors = ['DigitalNZ']
9
+ spec.email = ['info@digitalnz.org']
13
10
 
14
11
  spec.summary = 'Omniauth strategy for New Zealands secure online identity verification service.'
15
12
  spec.description = 'Omniauth strategy for New Zealands secure online identity verification service.'
16
- spec.homepage = 'https://example.com'
13
+ spec.homepage = 'https://github.com/omniauth/omniauth'
17
14
  spec.license = 'GNU'
15
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
16
+
17
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
18
+
19
+ spec.metadata['homepage_uri'] = spec.homepage
20
+ spec.metadata['source_code_uri'] = 'https://github.com/omniauth/omniauth'
18
21
 
19
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
- f.match(%r{^(test|spec|features)/})
22
+ # Specify which files should be added to the gem when it is released.
23
+ # 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(__dir__)) do
25
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
26
  end
22
27
  spec.bindir = 'exe'
23
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
29
  spec.require_paths = ['lib']
25
30
 
26
31
  spec.add_dependency 'omniauth', '~> 1.0'
27
- spec.add_dependency 'uuid', '~> 2.0'
28
32
  spec.add_dependency 'ruby-saml', '~> 1.5'
33
+ spec.add_dependency 'uuid', '~> 2.0'
29
34
 
30
35
  spec.add_development_dependency 'bundler'
36
+ spec.add_development_dependency 'pry-byebug'
37
+ spec.add_development_dependency 'rack-test'
31
38
  spec.add_development_dependency 'rake'
32
39
  spec.add_development_dependency 'rspec'
40
+ spec.add_development_dependency 'rubocop'
41
+ spec.add_development_dependency 'rubocop-rspec'
33
42
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth-realme
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
- - DanHenton
8
- autorequire:
7
+ - DigitalNZ
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-12 00:00:00.000000000 Z
11
+ date: 2020-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: omniauth
@@ -25,33 +25,33 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: uuid
28
+ name: ruby-saml
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.0'
33
+ version: '1.5'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.0'
40
+ version: '1.5'
41
41
  - !ruby/object:Gem::Dependency
42
- name: ruby-saml
42
+ name: uuid
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.5'
47
+ version: '2.0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.5'
54
+ version: '2.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rack-test
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: rake
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -94,22 +122,50 @@ dependencies:
94
122
  - - ">="
95
123
  - !ruby/object:Gem::Version
96
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop-rspec
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
97
153
  description: Omniauth strategy for New Zealands secure online identity verification
98
154
  service.
99
155
  email:
100
- - Dan.henton@live.com
156
+ - info@digitalnz.org
101
157
  executables: []
102
158
  extensions: []
103
159
  extra_rdoc_files: []
104
160
  files:
161
+ - ".github/workflows/ci.yml"
105
162
  - ".gitignore"
106
163
  - ".rspec"
107
164
  - ".rubocop.yml"
165
+ - ".rubocop_todo.yml"
108
166
  - ".ruby-version"
109
- - ".travis.yml"
110
167
  - Gemfile
111
168
  - Gemfile.lock
112
- - LICENSE
113
169
  - LICENSE.txt
114
170
  - README.md
115
171
  - Rakefile
@@ -119,11 +175,13 @@ files:
119
175
  - lib/omniauth/realme/version.rb
120
176
  - lib/omniauth/strategies/realme.rb
121
177
  - omniauth-realme.gemspec
122
- homepage: https://example.com
178
+ homepage: https://github.com/omniauth/omniauth
123
179
  licenses:
124
180
  - GNU
125
- metadata: {}
126
- post_install_message:
181
+ metadata:
182
+ homepage_uri: https://github.com/omniauth/omniauth
183
+ source_code_uri: https://github.com/omniauth/omniauth
184
+ post_install_message:
127
185
  rdoc_options: []
128
186
  require_paths:
129
187
  - lib
@@ -131,16 +189,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
131
189
  requirements:
132
190
  - - ">="
133
191
  - !ruby/object:Gem::Version
134
- version: '0'
192
+ version: 2.3.0
135
193
  required_rubygems_version: !ruby/object:Gem::Requirement
136
194
  requirements:
137
195
  - - ">="
138
196
  - !ruby/object:Gem::Version
139
197
  version: '0'
140
198
  requirements: []
141
- rubyforge_project:
142
- rubygems_version: 2.7.7
143
- signing_key:
199
+ rubygems_version: 3.0.3
200
+ signing_key:
144
201
  specification_version: 4
145
202
  summary: Omniauth strategy for New Zealands secure online identity verification service.
146
203
  test_files: []