omniauth_openid_connect 0.2.4 → 0.3.0

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: 9379f2ad95525430e02d022ece044a331e36d7a5ea093d48349829305f16b445
4
- data.tar.gz: 98959c5836425cae327007dc76fefbc09db5693d71488282ec5b08f1199da306
3
+ metadata.gz: 8916e5d71adfaa8dd6c64c168746671ba026fec61798ee85a9393c03b36c5bbd
4
+ data.tar.gz: adfa760da9122452dc6cc486fb721ef1ce32a79910b8c16a32b6b153430b3e28
5
5
  SHA512:
6
- metadata.gz: 18460b36bc8dfffb027e11baea3da125406cea9749877cf02640e60e7b98a4b813821988d6bcb7e4d41b7cb4a4d20207bf4bd4684d9ee6dd374f49618bda6556
7
- data.tar.gz: 5b8f9509cdb60e5c2f0234732781dbae04379ab4ccab482b9bd374c4134d7502d9bc27bcfac57be641d4154025d97bde92e7ebd16c5588f8fde55b4f3a65133a
6
+ metadata.gz: 877b098cd0f6a167cd6486a91de34668a6a8c7329ab0fb0eddcbb5914e548895db64a5e9e2ecf20308a90685f3baf29327b0a1e163d007b76e992908b398ea96
7
+ data.tar.gz: 0ae557ebfc1319225171bba2fdae139a7c6a98338812bec2d3a5b50c58946f825511565c0a0d4c8d07a658a892ba2b652f78c12fd79a7fd1466c16925b85a3e5
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  *.rbc
3
3
  .bundle
4
4
  .config
5
+ .idea
5
6
  .yardoc
6
7
  InstalledFiles
7
8
  _yardoc
data/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # v0.3.0 (27.04.2019)
2
+
3
+ - RP-Initiated Logout phase [#5](https://github.com/m0n9oose/omniauth_openid_connect/pull/5)
4
+ - Allows `ui_locales`, `claims_locales` and `login_hint` as request params [#6](https://github.com/m0n9oose/omniauth_openid_connect/pull/6)
5
+ - Make uid label configurable [#11](https://github.com/m0n9oose/omniauth_openid_connect/pull/11)
6
+ - Allow rails applications to handle state mismatch [#14](https://github.com/m0n9oose/omniauth_openid_connect/pull/14)
7
+ - Handle errors when fetching access_token at callback_phase [#17](https://github.com/m0n9oose/omniauth_openid_connect/pull/17)
8
+ - Allow state method to receive env [#19](https://github.com/m0n9oose/omniauth_openid_connect/pull/19)
9
+
10
+ # v0.2.4 (06.01.2019)
11
+
12
+ - Prompt and login hint [#4](https://github.com/m0n9oose/omniauth_openid_connect/pull/4)
13
+ - Bump openid_connect dependency [#9](https://github.com/m0n9oose/omniauth_openid_connect/pull/9)
data/README.md CHANGED
@@ -28,6 +28,7 @@ config.omniauth :openid_connect, {
28
28
  name: :my_provider,
29
29
  scope: [:openid, :email, :profile, :address],
30
30
  response_type: :code,
31
+ uid_field: "preferred_username",
31
32
  client_options: {
32
33
  port: 443,
33
34
  scheme: "https",
@@ -43,12 +44,16 @@ Configuration details:
43
44
  * `name` is arbitrary, I recommend using the name of your provider. The name
44
45
  configuration exists because you could be using multiple OpenID Connect
45
46
  providers in a single app.
47
+
48
+ **NOTE**: if you use this gem with Devise you should use `:openid_connect` name,
49
+ or Devise would route to 'users/auth/:provider' rather than 'users/auth/openid_connect'
50
+
46
51
  * Although `response_type` is an available option, currently, only `:code`
47
52
  is valid. There are plans to bring in implicit flow and hybrid flow at some
48
53
  point, but it hasn't come up yet for me. Those flows aren't best practive for
49
54
  server side web apps anyway and are designed more for native/mobile apps.
50
55
  * If you want to pass `state` paramete by yourself. You can set Proc Object.
51
- e.g. `state: Proc.new{ SecureRandom.hex(32) }`
56
+ e.g. `state: Proc.new { SecureRandom.hex(32) }`
52
57
  * `nonce` is optional. If don't want to pass "nonce" parameter to provider, You should specify
53
58
  `false` to `send_nonce` option. (default true)
54
59
  * Support for other client authentication methods. If don't specified
@@ -58,6 +63,11 @@ Configuration details:
58
63
  If provider does not have Webfinger endpoint, You can specify "Issuer" to option.
59
64
  e.g. `issuer: "https://myprovider.com"`
60
65
  It means to get configuration from "https://myprovider.com/.well-known/openid-configuration".
66
+ * The uid is by default using the `sub` value from the `user_info` response,
67
+ which in some applications is not the expected value. To avoid such limitations, the uid label can be
68
+ configured by providing the omniauth `uid_field` option to a different label (i.e. `preferred_username`)
69
+ that appears in the `user_info` details.
70
+ * The `issuer` property should exactly match the provider's issuer link.
61
71
 
62
72
  For the full low down on OpenID Connect, please check out
63
73
  [the spec](http://openid.net/specs/openid-connect-core-1_0.html).
@@ -66,6 +76,7 @@ For the full low down on OpenID Connect, please check out
66
76
 
67
77
  1. Fork it ( http://github.com/m0n9oose/omniauth-openid-connect/fork )
68
78
  2. Create your feature branch (`git checkout -b my-new-feature`)
69
- 3. Commit your changes (`git commit -am 'Add some feature'`)
70
- 4. Push to the branch (`git push origin my-new-feature`)
71
- 5. Create new Pull Request
79
+ 3. Cover your changes with tests and make sure they're green (`bundle install && bundle exec rake test`)
80
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
81
+ 5. Push to the branch (`git push origin my-new-feature`)
82
+ 6. Create new Pull Request
@@ -1,5 +1,5 @@
1
1
  module OmniAuth
2
2
  module OpenIDConnect
3
- VERSION = '0.2.4'
3
+ VERSION = '0.3.0'
4
4
  end
5
5
  end
@@ -4,11 +4,15 @@ require 'net/http'
4
4
  require 'open-uri'
5
5
  require 'omniauth'
6
6
  require 'openid_connect'
7
+ require 'forwardable'
7
8
 
8
9
  module OmniAuth
9
10
  module Strategies
10
11
  class OpenIDConnect
11
12
  include OmniAuth::Strategy
13
+ extend Forwardable
14
+
15
+ def_delegator :request, :params
12
16
 
13
17
  option :client_options, {
14
18
  identifier: nil,
@@ -20,7 +24,8 @@ module OmniAuth
20
24
  authorization_endpoint: '/authorize',
21
25
  token_endpoint: '/token',
22
26
  userinfo_endpoint: '/userinfo',
23
- jwks_uri: '/jwk'
27
+ jwks_uri: '/jwk',
28
+ end_session_endpoint: nil
24
29
  }
25
30
  option :issuer
26
31
  option :discovery, false
@@ -37,13 +42,19 @@ module OmniAuth
37
42
  option :max_age
38
43
  option :ui_locales
39
44
  option :id_token_hint
40
- option :login_hint
41
45
  option :acr_values
42
46
  option :send_nonce, true
43
47
  option :send_scope_to_token_endpoint, true
44
48
  option :client_auth_method
45
-
46
- uid { user_info.sub }
49
+ option :post_logout_redirect_uri
50
+ option :uid_field, 'sub'
51
+
52
+ def uid
53
+ user_info.public_send(options.uid_field.to_s)
54
+ rescue NoMethodError
55
+ log :warn, "User sub:#{user_info.sub} missing info field: #{options.uid_field}"
56
+ user_info.sub
57
+ end
47
58
 
48
59
  info do
49
60
  {
@@ -82,28 +93,28 @@ module OmniAuth
82
93
  end
83
94
 
84
95
  def request_phase
85
- options.issuer = issuer if options.issuer.blank?
86
- discover! if options.discovery
96
+ options.issuer = issuer if options.issuer.nil? || options.issuer.empty?
97
+ discover!
87
98
  redirect authorize_uri
88
99
  end
89
100
 
90
101
  def callback_phase
91
- error = request.params['error_reason'] || request.params['error']
102
+ error = params['error_reason'] || params['error']
92
103
  if error
93
- raise CallbackError.new(request.params['error'], request.params['error_description'] || request.params['error_reason'], request.params['error_uri'])
94
- elsif request.params['state'].to_s.empty? || request.params['state'] != stored_state
95
- return Rack::Response.new(['401 Unauthorized'], 401).finish
96
- elsif !request.params['code']
97
- return fail!(:missing_code, OmniAuth::OpenIDConnect::MissingCodeError.new(request.params['error']))
104
+ raise CallbackError.new(params['error'], params['error_description'] || params['error_reason'], params['error_uri'])
105
+ elsif params['state'].to_s.empty? || params['state'] != stored_state
106
+ raise CallbackError, 'Invalid state parameter'
107
+ elsif !params['code']
108
+ return fail!(:missing_code, OmniAuth::OpenIDConnect::MissingCodeError.new(params['error']))
98
109
  else
99
- options.issuer = issuer if options.issuer.blank?
100
- discover! if options.discovery
110
+ options.issuer = issuer if options.issuer.nil? || options.issuer.empty?
111
+ discover!
101
112
  client.redirect_uri = redirect_uri
102
113
  client.authorization_code = authorization_code
103
114
  access_token
104
115
  super
105
116
  end
106
- rescue CallbackError => e
117
+ rescue CallbackError, ::Rack::OAuth2::Client::Error => e
107
118
  fail!(:invalid_credentials, e)
108
119
  rescue ::Timeout::Error, ::Errno::ETIMEDOUT => e
109
120
  fail!(:timeout, e)
@@ -111,8 +122,24 @@ module OmniAuth
111
122
  fail!(:failed_to_connect, e)
112
123
  end
113
124
 
125
+ def other_phase
126
+ if logout_path_pattern.match?(current_path)
127
+ options.issuer = issuer if options.issuer.nil? || options.issuer.empty?
128
+ discover!
129
+ return redirect(end_session_uri) if end_session_uri
130
+ end
131
+ call_app!
132
+ end
133
+
114
134
  def authorization_code
115
- request.params['code']
135
+ params['code']
136
+ end
137
+
138
+ def end_session_uri
139
+ return unless end_session_endpoint_is_valid?
140
+ end_session_uri = URI(client_options.end_session_endpoint)
141
+ end_session_uri.query = encoded_post_logout_redirect_uri
142
+ end_session_uri.to_s
116
143
  end
117
144
 
118
145
  def authorize_uri
@@ -121,7 +148,9 @@ module OmniAuth
121
148
  response_type: options.response_type,
122
149
  scope: options.scope,
123
150
  state: new_state,
124
- login_hint: options.login_hint,
151
+ login_hint: params['login_hint'],
152
+ ui_locales: params['ui_locales'],
153
+ claims_locales: params['claims_locales'],
125
154
  prompt: options.prompt,
126
155
  nonce: (new_nonce if options.send_nonce),
127
156
  hd: options.hd,
@@ -143,10 +172,12 @@ module OmniAuth
143
172
  end
144
173
 
145
174
  def discover!
175
+ return unless options.discovery
146
176
  client_options.authorization_endpoint = config.authorization_endpoint
147
177
  client_options.token_endpoint = config.token_endpoint
148
178
  client_options.userinfo_endpoint = config.userinfo_endpoint
149
179
  client_options.jwks_uri = config.jwks_uri
180
+ client_options.end_session_endpoint = config.end_session_endpoint if config.respond_to?(:end_session_endpoint)
150
181
  end
151
182
 
152
183
  def user_info
@@ -178,7 +209,13 @@ module OmniAuth
178
209
  end
179
210
 
180
211
  def new_state
181
- state = options.state.call if options.state.respond_to? :call
212
+ state = if options.state.respond_to?(:call)
213
+ if options.state.arity == 1
214
+ options.state.call(env)
215
+ else
216
+ options.state.call
217
+ end
218
+ end
182
219
  session['omniauth.state'] = state || SecureRandom.hex(16)
183
220
  end
184
221
 
@@ -231,8 +268,24 @@ module OmniAuth
231
268
  end
232
269
 
233
270
  def redirect_uri
234
- return client_options.redirect_uri unless request.params['redirect_uri']
235
- "#{ client_options.redirect_uri }?redirect_uri=#{ CGI.escape(request.params['redirect_uri']) }"
271
+ return client_options.redirect_uri unless params['redirect_uri']
272
+ "#{ client_options.redirect_uri }?redirect_uri=#{ CGI.escape(params['redirect_uri']) }"
273
+ end
274
+
275
+ def encoded_post_logout_redirect_uri
276
+ return unless options.post_logout_redirect_uri
277
+ URI.encode_www_form(
278
+ post_logout_redirect_uri: options.post_logout_redirect_uri
279
+ )
280
+ end
281
+
282
+ def end_session_endpoint_is_valid?
283
+ client_options.end_session_endpoint &&
284
+ client_options.end_session_endpoint =~ URI::DEFAULT_PARSER.make_regexp
285
+ end
286
+
287
+ def logout_path_pattern
288
+ @logout_path_pattern ||= %r{\A#{Regexp.quote(request_path)}(/logout)}
236
289
  end
237
290
 
238
291
  class CallbackError < StandardError
@@ -21,7 +21,6 @@ Gem::Specification.new do |spec|
21
21
  spec.add_dependency 'omniauth', '~> 1.3'
22
22
  spec.add_dependency 'openid_connect', '~> 1.1'
23
23
  spec.add_dependency 'addressable', '~> 2.5'
24
- spec.add_development_dependency 'bundler', '~> 1.5'
25
24
  spec.add_development_dependency 'minitest', '~> 5.1'
26
25
  spec.add_development_dependency 'mocha', '~> 1.7'
27
26
  spec.add_development_dependency 'guard', '~> 2.14'
@@ -18,6 +18,73 @@ module OmniAuth
18
18
  strategy.request_phase
19
19
  end
20
20
 
21
+ def test_logout_phase_with_discovery
22
+ expected_redirect = %r{^https:\/\/example\.com\/logout$}
23
+ strategy.options.client_options.host = 'example.com'
24
+ strategy.options.discovery = true
25
+
26
+ issuer = stub('OpenIDConnect::Discovery::Issuer')
27
+ issuer.stubs(:issuer).returns('https://example.com/')
28
+ ::OpenIDConnect::Discovery::Provider.stubs(:discover!).returns(issuer)
29
+
30
+ config = stub('OpenIDConnect::Discovery::Provder::Config')
31
+ config.stubs(:authorization_endpoint).returns('https://example.com/authorization')
32
+ config.stubs(:token_endpoint).returns('https://example.com/token')
33
+ config.stubs(:userinfo_endpoint).returns('https://example.com/userinfo')
34
+ config.stubs(:jwks_uri).returns('https://example.com/jwks')
35
+ config.stubs(:end_session_endpoint).returns('https://example.com/logout')
36
+ ::OpenIDConnect::Discovery::Provider::Config.stubs(:discover!).with('https://example.com/').returns(config)
37
+
38
+ request.stubs(:path_info).returns('/auth/openidconnect/logout')
39
+
40
+ strategy.expects(:redirect).with(regexp_matches(expected_redirect))
41
+ strategy.other_phase
42
+ end
43
+
44
+ def test_logout_phase_with_discovery_and_post_logout_redirect_uri
45
+ expected_redirect = 'https://example.com/logout?post_logout_redirect_uri=https%3A%2F%2Fmysite.com'
46
+ strategy.options.client_options.host = 'example.com'
47
+ strategy.options.discovery = true
48
+ strategy.options.post_logout_redirect_uri = 'https://mysite.com'
49
+
50
+ issuer = stub('OpenIDConnect::Discovery::Issuer')
51
+ issuer.stubs(:issuer).returns('https://example.com/')
52
+ ::OpenIDConnect::Discovery::Provider.stubs(:discover!).returns(issuer)
53
+
54
+ config = stub('OpenIDConnect::Discovery::Provder::Config')
55
+ config.stubs(:authorization_endpoint).returns('https://example.com/authorization')
56
+ config.stubs(:token_endpoint).returns('https://example.com/token')
57
+ config.stubs(:userinfo_endpoint).returns('https://example.com/userinfo')
58
+ config.stubs(:jwks_uri).returns('https://example.com/jwks')
59
+ config.stubs(:end_session_endpoint).returns('https://example.com/logout')
60
+ ::OpenIDConnect::Discovery::Provider::Config.stubs(:discover!).with('https://example.com/').returns(config)
61
+
62
+ request.stubs(:path_info).returns('/auth/openidconnect/logout')
63
+
64
+ strategy.expects(:redirect).with(expected_redirect)
65
+ strategy.other_phase
66
+ end
67
+
68
+ def test_logout_phase
69
+ strategy.options.issuer = 'example.com'
70
+ strategy.options.client_options.host = 'example.com'
71
+
72
+ request.stubs(:path_info).returns('/auth/openidconnect/logout')
73
+
74
+ strategy.expects(:call_app!)
75
+ strategy.other_phase
76
+ end
77
+
78
+ def test_request_phase_with_params
79
+ expected_redirect = /^https:\/\/example\.com\/authorize\?claims_locales=es&client_id=1234&login_hint=john.doe%40example.com&nonce=\w{32}&response_type=code&scope=openid&state=\w{32}&ui_locales=en$/
80
+ strategy.options.issuer = 'example.com'
81
+ strategy.options.client_options.host = 'example.com'
82
+ request.stubs(:params).returns('login_hint' => 'john.doe@example.com', 'ui_locales' => 'en', 'claims_locales' => 'es')
83
+
84
+ strategy.expects(:redirect).with(regexp_matches(expected_redirect))
85
+ strategy.request_phase
86
+ end
87
+
21
88
  def test_request_phase_with_discovery
22
89
  expected_redirect = /^https:\/\/example\.com\/authorization\?client_id=1234&nonce=\w{32}&response_type=code&scope=openid&state=\w{32}$/
23
90
  strategy.options.client_options.host = 'example.com'
@@ -42,10 +109,17 @@ module OmniAuth
42
109
  assert_equal strategy.options.client_options.token_endpoint, 'https://example.com/token'
43
110
  assert_equal strategy.options.client_options.userinfo_endpoint, 'https://example.com/userinfo'
44
111
  assert_equal strategy.options.client_options.jwks_uri, 'https://example.com/jwks'
112
+ assert_nil strategy.options.client_options.end_session_endpoint
45
113
  end
46
114
 
47
115
  def test_uid
48
116
  assert_equal user_info.sub, strategy.uid
117
+
118
+ strategy.options.uid_field = 'preferred_username'
119
+ assert_equal user_info.preferred_username, strategy.uid
120
+
121
+ strategy.options.uid_field = 'something'
122
+ assert_equal user_info.sub, strategy.uid
49
123
  end
50
124
 
51
125
  def test_callback_phase(session = {}, params = {})
@@ -139,10 +213,20 @@ module OmniAuth
139
213
  request.stubs(:path_info).returns('')
140
214
 
141
215
  strategy.call!('rack.session' => { 'omniauth.state' => state, 'omniauth.nonce' => nonce })
142
- result = strategy.callback_phase
216
+ strategy.expects(:fail!)
217
+ strategy.callback_phase
218
+ end
219
+
220
+ def test_callback_phase_without_code
221
+ state = SecureRandom.hex(16)
222
+ nonce = SecureRandom.hex(16)
223
+ request.stubs(:params).returns('state' => state)
224
+ request.stubs(:path_info).returns('')
143
225
 
144
- assert result.kind_of?(Array)
145
- assert result.first == 401, "Expecting unauthorized"
226
+ strategy.call!('rack.session' => { 'omniauth.state' => state, 'omniauth.nonce' => nonce })
227
+
228
+ strategy.expects(:fail!)
229
+ strategy.callback_phase
146
230
  end
147
231
 
148
232
  def test_callback_phase_with_timeout
@@ -190,6 +274,21 @@ module OmniAuth
190
274
  strategy.callback_phase
191
275
  end
192
276
 
277
+ def test_callback_phase_with_rack_oauth2_client_error
278
+ code = SecureRandom.hex(16)
279
+ state = SecureRandom.hex(16)
280
+ nonce = SecureRandom.hex(16)
281
+ request.stubs(:params).returns('code' => code, 'state' => state)
282
+ request.stubs(:path_info).returns('')
283
+
284
+ strategy.options.issuer = 'example.com'
285
+
286
+ strategy.stubs(:access_token).raises(::Rack::OAuth2::Client::Error.new('error', error: 'Unknown'))
287
+ strategy.call!('rack.session' => { 'omniauth.state' => state, 'omniauth.nonce' => nonce })
288
+ strategy.expects(:fail!)
289
+ strategy.callback_phase
290
+ end
291
+
193
292
  def test_info
194
293
  info = strategy.info
195
294
  assert_equal user_info.name, info[:name]
@@ -261,15 +360,15 @@ module OmniAuth
261
360
  end
262
361
 
263
362
  def test_state
264
- strategy.options.state = lambda { 42 }
265
- session = { "state" => 42 }
363
+ strategy.options.state = -> { 42 }
266
364
 
267
- expected_redirect = /&state=/
365
+ expected_redirect = /&state=42/
268
366
  strategy.options.issuer = 'example.com'
269
367
  strategy.options.client_options.host = 'example.com'
270
368
  strategy.expects(:redirect).with(regexp_matches(expected_redirect))
271
369
  strategy.request_phase
272
370
 
371
+ session = { 'state' => 42 }
273
372
  # this should succeed as the correct state is passed with the request
274
373
  test_callback_phase(session, { 'state' => 42 })
275
374
 
@@ -277,12 +376,26 @@ module OmniAuth
277
376
  code = SecureRandom.hex(16)
278
377
  request.stubs(:params).returns('code' => code, 'state' => 43)
279
378
  request.stubs(:path_info).returns('')
379
+
280
380
  strategy.call!('rack.session' => session)
381
+ strategy.expects(:fail!)
382
+ strategy.callback_phase
383
+ end
281
384
 
282
- result = strategy.callback_phase
385
+ def test_dynamic_state
386
+ # Stub request parameters
387
+ Strategy.send(:define_method, 'env', -> { { QUERY_STRING: { state: 'abc', client_id: '123' } } })
283
388
 
284
- assert result.kind_of?(Array)
285
- assert result.first == 401, 'Expecting unauthorized'
389
+ strategy.options.state = lambda { |env|
390
+ # Get params from request, e.g. CGI.parse(env['QUERY_STRING'])
391
+ env[:QUERY_STRING][:state] + env[:QUERY_STRING][:client_id]
392
+ }
393
+
394
+ expected_redirect = /&state=abc123/
395
+ strategy.options.issuer = 'example.com'
396
+ strategy.options.client_options.host = 'example.com'
397
+ strategy.expects(:redirect).with(regexp_matches(expected_redirect))
398
+ strategy.request_phase
286
399
  end
287
400
 
288
401
  def test_option_client_auth_method
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniauth_openid_connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Bohn
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-01-06 00:00:00.000000000 Z
12
+ date: 2019-04-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: omniauth
@@ -53,20 +53,6 @@ dependencies:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
55
  version: '2.5'
56
- - !ruby/object:Gem::Dependency
57
- name: bundler
58
- requirement: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - "~>"
61
- - !ruby/object:Gem::Version
62
- version: '1.5'
63
- type: :development
64
- prerelease: false
65
- version_requirements: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - "~>"
68
- - !ruby/object:Gem::Version
69
- version: '1.5'
70
56
  - !ruby/object:Gem::Dependency
71
57
  name: minitest
72
58
  requirement: !ruby/object:Gem::Requirement
@@ -217,6 +203,7 @@ extra_rdoc_files: []
217
203
  files:
218
204
  - ".gitignore"
219
205
  - ".travis.yml"
206
+ - CHANGELOG.md
220
207
  - Gemfile
221
208
  - Guardfile
222
209
  - LICENSE.txt
@@ -253,8 +240,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
253
240
  - !ruby/object:Gem::Version
254
241
  version: '0'
255
242
  requirements: []
256
- rubyforge_project:
257
- rubygems_version: 2.7.6
243
+ rubygems_version: 3.0.2
258
244
  signing_key:
259
245
  specification_version: 4
260
246
  summary: OpenID Connect Strategy for OmniAuth