omniauth 1.3.1 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/omniauth/form.rb CHANGED
@@ -9,7 +9,7 @@ module OmniAuth
9
9
  options[:header_info] ||= ''
10
10
  self.options = options
11
11
 
12
- @html = ''
12
+ @html = +'' # unary + string allows it to be mutable if strings are frozen
13
13
  @with_custom_button = false
14
14
  @footer = nil
15
15
  header(options[:title], options[:header_info])
@@ -82,6 +82,7 @@ module OmniAuth
82
82
 
83
83
  def footer
84
84
  return self if @footer
85
+
85
86
  @html << "\n<button type='submit'>Connect</button>" unless @with_custom_button
86
87
  @html << <<-HTML
87
88
  </form>
@@ -0,0 +1,22 @@
1
+ require 'hashie/mash'
2
+
3
+ module OmniAuth
4
+ # Generic helper hash that allows method access on deeply nested keys.
5
+ class KeyStore < ::Hashie::Mash
6
+ # Disables warnings on Hashie 3.5.0+ for overwritten keys
7
+ def self.override_logging
8
+ require 'hashie/version'
9
+ return unless Gem::Version.new(Hashie::VERSION) >= Gem::Version.new('3.5.0')
10
+
11
+ if respond_to?(:disable_warnings)
12
+ disable_warnings
13
+ else
14
+ define_method(:log_built_in_message) { |*| }
15
+ private :log_built_in_message
16
+ end
17
+ end
18
+
19
+ # Disable on loading of the class
20
+ override_logging
21
+ end
22
+ end
@@ -31,7 +31,7 @@ module OmniAuth
31
31
  class Developer
32
32
  include OmniAuth::Strategy
33
33
 
34
- option :fields, [:name, :email]
34
+ option :fields, %i[name email]
35
35
  option :uid_field, :email
36
36
 
37
37
  def request_phase
@@ -1,4 +1,4 @@
1
- require 'hashie/mash'
1
+ require 'omniauth/key_store'
2
2
 
3
3
  module OmniAuth
4
4
  class NoSessionError < StandardError; end
@@ -14,6 +14,7 @@ module OmniAuth
14
14
  base.class_eval do
15
15
  option :setup, false
16
16
  option :skip_info, false
17
+ option :origin_param, 'origin'
17
18
  end
18
19
  end
19
20
 
@@ -21,9 +22,9 @@ module OmniAuth
21
22
  # Returns an inherited set of default options set at the class-level
22
23
  # for each strategy.
23
24
  def default_options
24
- return @default_options if instance_variable_defined?(:@default_options) && @default_options
25
+ # existing = superclass.default_options if superclass.respond_to?(:default_options)
25
26
  existing = superclass.respond_to?(:default_options) ? superclass.default_options : {}
26
- @default_options = OmniAuth::Strategy::Options.new(existing)
27
+ @default_options ||= OmniAuth::Strategy::Options.new(existing)
27
28
  end
28
29
 
29
30
  # This allows for more declarative subclassing of strategies by allowing
@@ -87,10 +88,13 @@ module OmniAuth
87
88
  (instance_variable_defined?(:@args) && @args) || existing
88
89
  end
89
90
 
90
- %w(uid info extra credentials).each do |fetcher|
91
- class_eval <<-RUBY
91
+ %w[uid info extra credentials].each do |fetcher|
92
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
93
+ attr_reader :#{fetcher}_proc
94
+ private :#{fetcher}_proc
95
+
92
96
  def #{fetcher}(&block)
93
- return @#{fetcher}_proc unless block_given?
97
+ return #{fetcher}_proc unless block_given?
94
98
  @#{fetcher}_proc = block
95
99
  end
96
100
 
@@ -132,15 +136,16 @@ module OmniAuth
132
136
  @options = self.class.default_options.dup
133
137
 
134
138
  options.deep_merge!(args.pop) if args.last.is_a?(Hash)
135
- options.name ||= self.class.to_s.split('::').last.downcase
139
+ options[:name] ||= self.class.to_s.split('::').last.downcase
136
140
 
137
141
  self.class.args.each do |arg|
138
142
  break if args.empty?
143
+
139
144
  options[arg] = args.shift
140
145
  end
141
146
 
142
147
  # Make sure that all of the args have been dealt with, otherwise error out.
143
- fail(ArgumentError.new("Received wrong number of arguments. #{args.inspect}")) unless args.empty?
148
+ raise(ArgumentError.new("Received wrong number of arguments. #{args.inspect}")) unless args.empty?
144
149
 
145
150
  yield options if block_given?
146
151
  end
@@ -172,20 +177,51 @@ module OmniAuth
172
177
  def call!(env) # rubocop:disable CyclomaticComplexity, PerceivedComplexity
173
178
  unless env['rack.session']
174
179
  error = OmniAuth::NoSessionError.new('You must provide a session to use OmniAuth.')
175
- fail(error)
180
+ raise(error)
176
181
  end
177
182
 
178
183
  @env = env
184
+
185
+ warn_if_using_get_on_request_path
186
+
179
187
  @env['omniauth.strategy'] = self if on_auth_path?
180
188
 
181
189
  return mock_call!(env) if OmniAuth.config.test_mode
182
- return options_call if on_auth_path? && options_request?
183
- return request_call if on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
184
- return callback_call if on_callback_path?
185
- return other_phase if respond_to?(:other_phase)
190
+
191
+ begin
192
+ return options_call if on_auth_path? && options_request?
193
+ return request_call if on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
194
+ return callback_call if on_callback_path?
195
+ return other_phase if respond_to?(:other_phase)
196
+ rescue StandardError => e
197
+ raise e if env.delete('omniauth.error.app')
198
+
199
+ return fail!(e.message, e)
200
+ end
201
+
186
202
  @app.call(env)
187
203
  end
188
204
 
205
+ def warn_if_using_get_on_request_path
206
+ return unless on_request_path?
207
+ return unless OmniAuth.config.allowed_request_methods.include?(:get)
208
+ return if OmniAuth.config.silence_get_warning
209
+
210
+ log :warn, <<-WARN
211
+ You are using GET as an allowed request method for OmniAuth. This may leave
212
+ you open to CSRF attacks. As of v2.0.0, OmniAuth by default allows only POST
213
+ to its own routes. You should review the following resources to guide your
214
+ mitigation:
215
+ https://github.com/omniauth/omniauth/wiki/Resolving-CVE-2015-9284
216
+ https://github.com/omniauth/omniauth/issues/960
217
+ https://nvd.nist.gov/vuln/detail/CVE-2015-9284
218
+ https://github.com/omniauth/omniauth/pull/809
219
+
220
+ You can ignore this warning by setting:
221
+ OmniAuth.config.silence_get_warning = true
222
+ WARN
223
+ end
224
+
189
225
  # Responds to an OPTIONS request.
190
226
  def options_call
191
227
  OmniAuth.config.before_options_phase.call(env) if OmniAuth.config.before_options_phase
@@ -196,30 +232,39 @@ module OmniAuth
196
232
  # Performs the steps necessary to run the request phase of a strategy.
197
233
  def request_call # rubocop:disable CyclomaticComplexity, MethodLength, PerceivedComplexity
198
234
  setup_phase
199
- log :info, 'Request phase initiated.'
235
+ log :debug, 'Request phase initiated.'
236
+
200
237
  # store query params from the request url, extracted in the callback_phase
201
- session['omniauth.params'] = request.params
238
+ session['omniauth.params'] = request.GET
239
+
240
+ OmniAuth.config.request_validation_phase.call(env) if OmniAuth.config.request_validation_phase
202
241
  OmniAuth.config.before_request_phase.call(env) if OmniAuth.config.before_request_phase
242
+
203
243
  if options.form.respond_to?(:call)
204
- log :info, 'Rendering form from supplied Rack endpoint.'
244
+ log :debug, 'Rendering form from supplied Rack endpoint.'
205
245
  options.form.call(env)
206
246
  elsif options.form
207
- log :info, 'Rendering form from underlying application.'
247
+ log :debug, 'Rendering form from underlying application.'
208
248
  call_app!
249
+ elsif !options.origin_param
250
+ request_phase
209
251
  else
210
- if request.params['origin']
211
- env['rack.session']['omniauth.origin'] = request.params['origin']
252
+ if request.params[options.origin_param]
253
+ env['rack.session']['omniauth.origin'] = request.params[options.origin_param]
212
254
  elsif env['HTTP_REFERER'] && !env['HTTP_REFERER'].match(/#{request_path}$/)
213
255
  env['rack.session']['omniauth.origin'] = env['HTTP_REFERER']
214
256
  end
257
+
215
258
  request_phase
216
259
  end
260
+ rescue OmniAuth::AuthenticityError => e
261
+ fail!(:authenticity_error, e)
217
262
  end
218
263
 
219
264
  # Performs the steps necessary to run the callback phase of a strategy.
220
265
  def callback_call
221
266
  setup_phase
222
- log :info, 'Callback phase initiated.'
267
+ log :debug, 'Callback phase initiated.'
223
268
  @env['omniauth.origin'] = session.delete('omniauth.origin')
224
269
  @env['omniauth.origin'] = nil if env['omniauth.origin'] == ''
225
270
  @env['omniauth.params'] = session.delete('omniauth.params') || {}
@@ -234,8 +279,8 @@ module OmniAuth
234
279
  end
235
280
 
236
281
  def on_request_path?
237
- if options.request_path.respond_to?(:call)
238
- options.request_path.call(env)
282
+ if options[:request_path].respond_to?(:call)
283
+ options[:request_path].call(env)
239
284
  else
240
285
  on_path?(request_path)
241
286
  end
@@ -246,7 +291,7 @@ module OmniAuth
246
291
  end
247
292
 
248
293
  def on_path?(path)
249
- current_path.casecmp(path) == 0
294
+ current_path.casecmp(path).zero?
250
295
  end
251
296
 
252
297
  def options_request?
@@ -257,20 +302,32 @@ module OmniAuth
257
302
  # in the event that OmniAuth has been configured to be
258
303
  # in test mode.
259
304
  def mock_call!(*)
260
- return mock_request_call if on_request_path?
261
- return mock_callback_call if on_callback_path?
305
+ begin
306
+ return mock_request_call if on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
307
+ return mock_callback_call if on_callback_path?
308
+ rescue StandardError => e
309
+ raise e if env.delete('omniauth.error.app')
310
+
311
+ return fail!(e.message, e)
312
+ end
313
+
262
314
  call_app!
263
315
  end
264
316
 
265
317
  def mock_request_call
266
318
  setup_phase
267
319
 
268
- session['omniauth.params'] = request.params
320
+ session['omniauth.params'] = request.GET
321
+
322
+ OmniAuth.config.request_validation_phase.call(env) if OmniAuth.config.request_validation_phase
269
323
  OmniAuth.config.before_request_phase.call(env) if OmniAuth.config.before_request_phase
270
- if request.params['origin']
271
- @env['rack.session']['omniauth.origin'] = request.params['origin']
272
- elsif env['HTTP_REFERER'] && !env['HTTP_REFERER'].match(/#{request_path}$/)
273
- @env['rack.session']['omniauth.origin'] = env['HTTP_REFERER']
324
+
325
+ if options.origin_param
326
+ if request.params[options.origin_param]
327
+ session['omniauth.origin'] = request.params[options.origin_param]
328
+ elsif env['HTTP_REFERER'] && !env['HTTP_REFERER'].match(/#{request_path}$/)
329
+ session['omniauth.origin'] = env['HTTP_REFERER']
330
+ end
274
331
  end
275
332
 
276
333
  redirect(callback_url)
@@ -280,12 +337,13 @@ module OmniAuth
280
337
  setup_phase
281
338
  @env['omniauth.origin'] = session.delete('omniauth.origin')
282
339
  @env['omniauth.origin'] = nil if env['omniauth.origin'] == ''
340
+ @env['omniauth.params'] = session.delete('omniauth.params') || {}
341
+
283
342
  mocked_auth = OmniAuth.mock_auth_for(name.to_s)
284
343
  if mocked_auth.is_a?(Symbol)
285
344
  fail!(mocked_auth)
286
345
  else
287
346
  @env['omniauth.auth'] = mocked_auth
288
- @env['omniauth.params'] = session.delete('omniauth.params') || {}
289
347
  OmniAuth.config.before_callback_phase.call(@env) if OmniAuth.config.before_callback_phase
290
348
  call_app!
291
349
  end
@@ -297,10 +355,10 @@ module OmniAuth
297
355
  # underlying application. This will default to `/auth/:provider/setup`.
298
356
  def setup_phase
299
357
  if options[:setup].respond_to?(:call)
300
- log :info, 'Setup endpoint detected, running now.'
358
+ log :debug, 'Setup endpoint detected, running now.'
301
359
  options[:setup].call(env)
302
- elsif options.setup?
303
- log :info, 'Calling through to underlying application for setup.'
360
+ elsif options[:setup]
361
+ log :debug, 'Calling through to underlying application for setup.'
304
362
  setup_env = env.merge('PATH_INFO' => setup_path, 'REQUEST_METHOD' => 'GET')
305
363
  call_app!(setup_env)
306
364
  end
@@ -310,7 +368,7 @@ module OmniAuth
310
368
  # perform any information gathering you need to be able to authenticate
311
369
  # the user in this phase.
312
370
  def request_phase
313
- fail(NotImplementedError)
371
+ raise(NotImplementedError)
314
372
  end
315
373
 
316
374
  def uid
@@ -330,11 +388,13 @@ module OmniAuth
330
388
  end
331
389
 
332
390
  def auth_hash
333
- hash = AuthHash.new(:provider => name, :uid => uid)
334
- hash.info = info unless skip_info?
335
- hash.credentials = credentials if credentials
336
- hash.extra = extra if extra
337
- hash
391
+ credentials_data = credentials
392
+ extra_data = extra
393
+ AuthHash.new(:provider => name, :uid => uid).tap do |auth|
394
+ auth.info = info unless skip_info?
395
+ auth.credentials = credentials_data if credentials_data
396
+ auth.extra = extra_data if extra_data
397
+ end
338
398
  end
339
399
 
340
400
  # Determines whether or not user info should be retrieved. This
@@ -347,14 +407,10 @@ module OmniAuth
347
407
  #
348
408
  # use MyStrategy, :skip_info => lambda{|uid| User.find_by_uid(uid)}
349
409
  def skip_info?
350
- if options.skip_info?
351
- if options.skip_info.respond_to?(:call)
352
- return options.skip_info.call(uid)
353
- else
354
- return true
355
- end
356
- end
357
- false
410
+ return false unless options.skip_info?
411
+ return true unless options.skip_info.respond_to?(:call)
412
+
413
+ options.skip_info.call(uid)
358
414
  end
359
415
 
360
416
  def callback_phase
@@ -370,6 +426,7 @@ module OmniAuth
370
426
  if options[kind].respond_to?(:call)
371
427
  result = options[kind].call(env)
372
428
  return nil unless result.is_a?(String)
429
+
373
430
  result
374
431
  else
375
432
  options[kind]
@@ -377,7 +434,12 @@ module OmniAuth
377
434
  end
378
435
 
379
436
  def request_path
380
- @request_path ||= options[:request_path].is_a?(String) ? options[:request_path] : "#{path_prefix}/#{name}"
437
+ @request_path ||=
438
+ if options[:request_path].is_a?(String)
439
+ options[:request_path]
440
+ else
441
+ "#{script_name}#{path_prefix}/#{name}"
442
+ end
381
443
  end
382
444
 
383
445
  def callback_path
@@ -385,7 +447,7 @@ module OmniAuth
385
447
  path = options[:callback_path] if options[:callback_path].is_a?(String)
386
448
  path ||= current_path if options[:callback_path].respond_to?(:call) && options[:callback_path].call(env)
387
449
  path ||= custom_path(:request_path)
388
- path ||= "#{path_prefix}/#{name}/callback"
450
+ path ||= "#{script_name}#{path_prefix}/#{name}/callback"
389
451
  path
390
452
  end
391
453
  end
@@ -394,10 +456,10 @@ module OmniAuth
394
456
  options[:setup_path] || "#{path_prefix}/#{name}/setup"
395
457
  end
396
458
 
397
- CURRENT_PATH_REGEX = %r{/$}
459
+ CURRENT_PATH_REGEX = %r{/$}.freeze
398
460
  EMPTY_STRING = ''.freeze
399
461
  def current_path
400
- @current_path ||= request.path_info.downcase.sub(CURRENT_PATH_REGEX, EMPTY_STRING)
462
+ @current_path ||= request.path.downcase.sub(CURRENT_PATH_REGEX, EMPTY_STRING)
401
463
  end
402
464
 
403
465
  def query_string
@@ -406,6 +468,9 @@ module OmniAuth
406
468
 
407
469
  def call_app!(env = @env)
408
470
  @app.call(env)
471
+ rescue StandardError => e
472
+ env['omniauth.error.app'] = true
473
+ raise e
409
474
  end
410
475
 
411
476
  def full_host
@@ -429,7 +494,7 @@ module OmniAuth
429
494
  end
430
495
 
431
496
  def callback_url
432
- full_host + script_name + callback_path + query_string
497
+ full_host + callback_path + query_string
433
498
  end
434
499
 
435
500
  def script_name
@@ -445,7 +510,7 @@ module OmniAuth
445
510
  end
446
511
 
447
512
  def name
448
- options.name
513
+ options[:name]
449
514
  end
450
515
 
451
516
  def redirect(uri)
@@ -479,16 +544,15 @@ module OmniAuth
479
544
  OmniAuth.config.on_failure.call(env)
480
545
  end
481
546
 
482
- def dup
483
- super.tap do
484
- @options = @options.dup
485
- end
486
- end
487
-
488
- class Options < Hashie::Mash; end
547
+ class Options < OmniAuth::KeyStore; end
489
548
 
490
549
  protected
491
550
 
551
+ def initialize_copy(*args)
552
+ super
553
+ @options = @options.dup
554
+ end
555
+
492
556
  def merge_stack(stack)
493
557
  stack.inject({}) do |a, e|
494
558
  a.merge!(e)
@@ -10,7 +10,7 @@ module OmniAuth
10
10
  # include OmniAuth::Test::StrategyTestCase
11
11
  # def strategy
12
12
  # # return the parameters to a Rack::Builder map call:
13
- # [MyStrategy.new, :some, :configuration, :options => 'here']
13
+ # [MyStrategy, :some, :configuration, :options => 'here']
14
14
  # end
15
15
  # setup do
16
16
  # post '/auth/my_strategy/callback', :user => { 'name' => 'Dylan', 'id' => '445' }
@@ -37,7 +37,7 @@ module OmniAuth
37
37
 
38
38
  def strategy
39
39
  error = NotImplementedError.new('Including specs must define #strategy')
40
- fail(error)
40
+ raise(error)
41
41
  end
42
42
  end
43
43
  end
@@ -1,3 +1,3 @@
1
1
  module OmniAuth
2
- VERSION = '1.3.1'
2
+ VERSION = '2.0.4'.freeze
3
3
  end
data/lib/omniauth.rb CHANGED
@@ -15,6 +15,7 @@ module OmniAuth
15
15
  autoload :Form, 'omniauth/form'
16
16
  autoload :AuthHash, 'omniauth/auth_hash'
17
17
  autoload :FailureEndpoint, 'omniauth/failure_endpoint'
18
+ autoload :AuthenticityTokenProtection, 'omniauth/authenticity_token_protection'
18
19
 
19
20
  def self.strategies
20
21
  @strategies ||= []
@@ -29,20 +30,22 @@ module OmniAuth
29
30
  logger
30
31
  end
31
32
 
32
- def self.defaults
33
+ def self.defaults # rubocop:disable MethodLength
33
34
  @defaults ||= {
34
35
  :camelizations => {},
35
36
  :path_prefix => '/auth',
36
37
  :on_failure => OmniAuth::FailureEndpoint,
37
38
  :failure_raise_out_environments => ['development'],
39
+ :request_validation_phase => OmniAuth::AuthenticityTokenProtection,
38
40
  :before_request_phase => nil,
39
41
  :before_callback_phase => nil,
40
42
  :before_options_phase => nil,
41
43
  :form_css => Form::DEFAULT_CSS,
42
44
  :test_mode => false,
43
45
  :logger => default_logger,
44
- :allowed_request_methods => [:get, :post],
45
- :mock_auth => {:default => AuthHash.new('provider' => 'default', 'uid' => '1234', 'info' => {'name' => 'Example User'})}
46
+ :allowed_request_methods => %i[post],
47
+ :mock_auth => {:default => AuthHash.new('provider' => 'default', 'uid' => '1234', 'info' => {'name' => 'Example User'})},
48
+ :silence_get_warning => false
46
49
  }
47
50
  end
48
51
 
@@ -74,6 +77,14 @@ module OmniAuth
74
77
  end
75
78
  end
76
79
 
80
+ def request_validation_phase(&block)
81
+ if block_given?
82
+ @request_validation_phase = block
83
+ else
84
+ @request_validation_phase
85
+ end
86
+ end
87
+
77
88
  def before_request_phase(&block)
78
89
  if block_given?
79
90
  @before_request_phase = block
@@ -111,8 +122,9 @@ module OmniAuth
111
122
  camelizations[name.to_s] = camelized.to_s
112
123
  end
113
124
 
114
- attr_writer :on_failure, :before_callback_phase, :before_options_phase, :before_request_phase
115
- attr_accessor :failure_raise_out_environments, :path_prefix, :allowed_request_methods, :form_css, :test_mode, :mock_auth, :full_host, :camelizations, :logger
125
+ attr_writer :on_failure, :before_callback_phase, :before_options_phase, :before_request_phase, :request_validation_phase
126
+ attr_accessor :failure_raise_out_environments, :path_prefix, :allowed_request_methods, :form_css,
127
+ :test_mode, :mock_auth, :full_host, :camelizations, :logger, :silence_get_warning
116
128
  end
117
129
 
118
130
  def self.config
@@ -132,7 +144,7 @@ module OmniAuth
132
144
  end
133
145
 
134
146
  module Utils
135
- module_function
147
+ module_function # rubocop:disable Layout/IndentationWidth
136
148
 
137
149
  def form_css
138
150
  "<style type='text/css'>#{OmniAuth.config.form_css}</style>"
@@ -141,7 +153,7 @@ module OmniAuth
141
153
  def deep_merge(hash, other_hash)
142
154
  target = hash.dup
143
155
 
144
- other_hash.keys.each do |key|
156
+ other_hash.each_key do |key|
145
157
  if other_hash[key].is_a?(::Hash) && hash[key].is_a?(::Hash)
146
158
  target[key] = deep_merge(target[key], other_hash[key])
147
159
  next
@@ -159,7 +171,7 @@ module OmniAuth
159
171
  if first_letter_in_uppercase
160
172
  word.to_s.gsub(%r{/(.?)}) { '::' + Regexp.last_match[1].upcase }.gsub(/(^|_)(.)/) { Regexp.last_match[2].upcase }
161
173
  else
162
- word.first + camelize(word)[1..-1]
174
+ camelize(word).tap { |w| w[0] = w[0].downcase }
163
175
  end
164
176
  end
165
177
  end
data/omniauth.gemspec CHANGED
@@ -1,21 +1,25 @@
1
1
  # coding: utf-8
2
+
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'omniauth/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.add_dependency 'hashie', ['>= 1.2', '< 4']
8
- spec.add_dependency 'rack', ['>= 1.0', '< 3']
9
- spec.add_development_dependency 'bundler', '~> 1.0'
8
+ spec.add_dependency 'hashie', ['>= 3.4.6']
9
+ spec.add_dependency 'rack', ['>= 1.6.2', '< 3']
10
+ spec.add_development_dependency 'bundler', '~> 2.0'
11
+ spec.add_dependency 'rack-protection'
12
+ spec.add_development_dependency 'rake', '~> 12.0'
10
13
  spec.authors = ['Michael Bleigh', 'Erik Michaels-Ober', 'Tom Milewski']
11
14
  spec.description = 'A generalized Rack framework for multiple-provider authentication.'
12
15
  spec.email = ['michael@intridea.com', 'sferik@gmail.com', 'tmilewski@gmail.com']
13
16
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.start_with?('spec/') }
14
- spec.homepage = 'http://github.com/intridea/omniauth'
15
- spec.licenses = %w(MIT)
17
+ spec.homepage = 'https://github.com/omniauth/omniauth'
18
+ spec.licenses = %w[MIT]
16
19
  spec.name = 'omniauth'
17
- spec.require_paths = %w(lib)
20
+ spec.require_paths = %w[lib]
18
21
  spec.required_rubygems_version = '>= 1.3.5'
22
+ spec.required_ruby_version = '>= 2.2'
19
23
  spec.summary = spec.description
20
24
  spec.version = OmniAuth::VERSION
21
25
  end