omniauth 2.1.4 → 2.3.0

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.
@@ -1,116 +1,32 @@
1
1
  require 'omniauth/key_store'
2
+ require 'omniauth/strategy/class_methods'
3
+ require 'omniauth/strategy/fetchers'
4
+ require 'omniauth/strategy/hosts'
5
+ require 'omniauth/strategy/paths'
6
+ require 'omniauth/strategy/sign_ins'
7
+ require 'omniauth/strategy/test_mode'
2
8
 
3
9
  module OmniAuth
4
10
  class NoSessionError < StandardError; end
11
+
5
12
  # The Strategy is the base unit of OmniAuth's ability to
6
13
  # wrangle multiple providers. Each strategy provided by
7
14
  # OmniAuth includes this mixin to gain the default functionality
8
15
  # necessary to be compatible with the OmniAuth library.
9
- module Strategy # rubocop:disable ModuleLength
16
+ module Strategy # rubocop:disable Metrics/ModuleLength
17
+ include Fetchers
18
+ include Hosts
19
+ include Paths
20
+ include SignIns
21
+ include TestMode
22
+
10
23
  def self.included(base)
11
24
  OmniAuth.strategies << base
12
25
 
13
26
  base.extend ClassMethods
14
- base.class_eval do
15
- option :setup, false
16
- option :skip_info, false
17
- option :origin_param, 'origin'
18
- end
19
- end
20
-
21
- module ClassMethods
22
- # Returns an inherited set of default options set at the class-level
23
- # for each strategy.
24
- def default_options
25
- # existing = superclass.default_options if superclass.respond_to?(:default_options)
26
- existing = superclass.respond_to?(:default_options) ? superclass.default_options : {}
27
- @default_options ||= OmniAuth::Strategy::Options.new(existing)
28
- end
29
-
30
- # This allows for more declarative subclassing of strategies by allowing
31
- # default options to be set using a simple configure call.
32
- #
33
- # @param options [Hash] If supplied, these will be the default options (deep-merged into the superclass's default options).
34
- # @yield [Options] The options Mash that allows you to set your defaults as you'd like.
35
- #
36
- # @example Using a yield to configure the default options.
37
- #
38
- # class MyStrategy
39
- # include OmniAuth::Strategy
40
- #
41
- # configure do |c|
42
- # c.foo = 'bar'
43
- # end
44
- # end
45
- #
46
- # @example Using a hash to configure the default options.
47
- #
48
- # class MyStrategy
49
- # include OmniAuth::Strategy
50
- # configure foo: 'bar'
51
- # end
52
- def configure(options = nil)
53
- if block_given?
54
- yield default_options
55
- else
56
- default_options.deep_merge!(options)
57
- end
58
- end
59
-
60
- # Directly declare a default option for your class. This is a useful from
61
- # a documentation perspective as it provides a simple line-by-line analysis
62
- # of the kinds of options your strategy provides by default.
63
- #
64
- # @param name [Symbol] The key of the default option in your configuration hash.
65
- # @param value [Object] The value your object defaults to. Nil if not provided.
66
- #
67
- # @example
68
- #
69
- # class MyStrategy
70
- # include OmniAuth::Strategy
71
- #
72
- # option :foo, 'bar'
73
- # option
74
- # end
75
- def option(name, value = nil)
76
- default_options[name] = value
77
- end
78
-
79
- # Sets (and retrieves) option key names for initializer arguments to be
80
- # recorded as. This takes care of 90% of the use cases for overriding
81
- # the initializer in OmniAuth Strategies.
82
- def args(args = nil)
83
- if args
84
- @args = Array(args)
85
- return
86
- end
87
- existing = superclass.respond_to?(:args) ? superclass.args : []
88
- (instance_variable_defined?(:@args) && @args) || existing
89
- end
90
-
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
-
96
- def #{fetcher}(&block)
97
- return #{fetcher}_proc unless block_given?
98
- @#{fetcher}_proc = block
99
- end
100
-
101
- def #{fetcher}_stack(context)
102
- compile_stack(self.ancestors, :#{fetcher}, context)
103
- end
104
- RUBY
105
- end
106
-
107
- def compile_stack(ancestors, method, context)
108
- stack = ancestors.inject([]) do |a, ancestor|
109
- a << context.instance_eval(&ancestor.send(method)) if ancestor.respond_to?(method) && ancestor.send(method)
110
- a
111
- end
112
- stack.reverse!
113
- end
27
+ base.option :setup, false
28
+ base.option :skip_info, false
29
+ base.option :origin_param, 'origin'
114
30
  end
115
31
 
116
32
  attr_reader :app, :env, :options, :response
@@ -130,7 +46,7 @@ module OmniAuth
130
46
  # will be passed through and set to the appropriate values.
131
47
  #
132
48
  # @yield [Options] Yields options to block for further configuration.
133
- def initialize(app, *args, &block) # rubocop:disable UnusedMethodArgument
49
+ def initialize(app, *args)
134
50
  @app = app
135
51
  @env = nil
136
52
  @options = self.class.default_options.dup
@@ -145,7 +61,7 @@ module OmniAuth
145
61
  end
146
62
 
147
63
  # Make sure that all of the args have been dealt with, otherwise error out.
148
- raise(ArgumentError.new("Received wrong number of arguments. #{args.inspect}")) unless args.empty?
64
+ raise(ArgumentError.new("Received wrong number of arguments. #{args}")) unless args.empty?
149
65
 
150
66
  yield options if block_given?
151
67
  end
@@ -160,12 +76,15 @@ module OmniAuth
160
76
  # @example
161
77
  # log :warn, "This is a warning."
162
78
  def log(level, message)
163
- OmniAuth.logger.send(level, "(#{name}) #{message}")
79
+ OmniAuth.logger.public_send(level, "(#{name}) #{message}")
164
80
  end
165
81
 
166
- # Duplicates this instance and runs #call! on it.
82
+ # Duplicates this instance and runs #call! on it. A request that can't be
83
+ # the strategy's goes straight to the app instead, skipping the copy.
167
84
  # @param [Hash] The Rack environment.
168
85
  def call(env)
86
+ return @app.call(env) if passthrough?(env)
87
+
169
88
  dup.call!(env)
170
89
  end
171
90
 
@@ -174,9 +93,9 @@ module OmniAuth
174
93
  # the request path is recognized.
175
94
  #
176
95
  # @param env [Hash] The Rack environment.
177
- def call!(env) # rubocop:disable CyclomaticComplexity, PerceivedComplexity
96
+ def call!(env)
178
97
  unless env['rack.session']
179
- error = OmniAuth::NoSessionError.new('You must provide a session to use OmniAuth.')
98
+ error = NoSessionError.new('You must provide a session to use OmniAuth.')
180
99
  raise(error)
181
100
  end
182
101
 
@@ -184,22 +103,37 @@ module OmniAuth
184
103
 
185
104
  warn_if_using_get_on_request_path
186
105
 
187
- @env['omniauth.strategy'] = self if on_auth_path?
106
+ env['omniauth.strategy'] = self if on_auth_path?
188
107
 
189
108
  return mock_call!(env) if OmniAuth.config.test_mode
190
109
 
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')
110
+ phase_call || @app.call(env)
111
+ end
198
112
 
199
- return fail!(e.message, e)
113
+ # Runs the phase that matches the current request, or returns nil
114
+ # if the request isn't for this strategy.
115
+ def phase_call
116
+ if options_call?
117
+ options_call
118
+ elsif request_call?
119
+ request_call
120
+ elsif on_callback_path?
121
+ callback_call
122
+ elsif respond_to?(:other_phase)
123
+ other_phase
200
124
  end
125
+ rescue StandardError => e
126
+ handle_phase_error(e)
127
+ end
128
+
129
+ # True for an OPTIONS request to the request or callback path.
130
+ def options_call?
131
+ on_auth_path? && options_request?
132
+ end
201
133
 
202
- @app.call(env)
134
+ # True for a request to the request path with an allowed method.
135
+ def request_call?
136
+ on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
203
137
  end
204
138
 
205
139
  def warn_if_using_get_on_request_path
@@ -224,137 +158,80 @@ module OmniAuth
224
158
 
225
159
  # Responds to an OPTIONS request.
226
160
  def options_call
227
- OmniAuth.config.before_options_phase.call(env) if OmniAuth.config.before_options_phase
228
- verbs = OmniAuth.config.allowed_request_methods.collect(&:to_s).collect(&:upcase).join(', ')
161
+ run_hook(:before_options_phase)
162
+ verbs = OmniAuth.config.allowed_request_methods.collect(&:upcase).join(', ')
229
163
  [200, {'Allow' => verbs}, []]
230
164
  end
231
165
 
232
166
  # Performs the steps necessary to run the request phase of a strategy.
233
- def request_call # rubocop:disable CyclomaticComplexity, MethodLength, PerceivedComplexity
167
+ def request_call
234
168
  setup_phase
235
169
  log :debug, 'Request phase initiated.'
170
+ warn_if_using_request_host
171
+ return invalid_host! unless allowed_host?
236
172
 
237
- # store query params from the request url, extracted in the callback_phase
238
- session['omniauth.params'] = request.GET
239
-
240
- OmniAuth.config.request_validation_phase.call(env) if OmniAuth.config.request_validation_phase
241
- OmniAuth.config.before_request_phase.call(env) if OmniAuth.config.before_request_phase
173
+ run_hook(:request_validation_phase)
174
+ session['omniauth.params'] = omniauth_params
175
+ run_hook(:before_request_phase)
176
+ request_response.tap { run_hook(:after_request_phase) }
177
+ rescue OmniAuth::AuthenticityError => e
178
+ fail!(:authenticity_error, e)
179
+ end
242
180
 
243
- result = if options.form.respond_to?(:call)
181
+ # Renders the login form (from a Rack endpoint or the app itself) if
182
+ # one is configured, or else runs the strategy's request phase.
183
+ def request_response
184
+ if options.form.respond_to?(:call)
244
185
  log :debug, 'Rendering form from supplied Rack endpoint.'
245
186
  options.form.call(env)
246
187
  elsif options.form
247
188
  log :debug, 'Rendering form from underlying application.'
248
189
  call_app!
249
- elsif !options.origin_param
250
- request_phase
251
190
  else
252
- if request.params[options.origin_param]
253
- env['rack.session']['omniauth.origin'] = request.params[options.origin_param]
254
- elsif env['HTTP_REFERER'] && !env['HTTP_REFERER'].match(/#{request_path}$/)
255
- env['rack.session']['omniauth.origin'] = env['HTTP_REFERER']
256
- end
257
-
191
+ store_origin if options.origin_param
258
192
  request_phase
259
193
  end
260
-
261
- OmniAuth.config.after_request_phase.call(env) if OmniAuth.config.after_request_phase
262
- result
263
- rescue OmniAuth::AuthenticityError => e
264
- fail!(:authenticity_error, e)
265
- end
266
-
267
- # Performs the steps necessary to run the callback phase of a strategy.
268
- def callback_call
269
- setup_phase
270
- log :debug, 'Callback phase initiated.'
271
- @env['omniauth.origin'] = session.delete('omniauth.origin')
272
- @env['omniauth.origin'] = nil if env['omniauth.origin'] == ''
273
- @env['omniauth.params'] = session.delete('omniauth.params') || {}
274
- OmniAuth.config.before_callback_phase.call(@env) if OmniAuth.config.before_callback_phase
275
- callback_phase
276
- end
277
-
278
- # Returns true if the environment recognizes either the
279
- # request or callback path.
280
- def on_auth_path?
281
- on_request_path? || on_callback_path?
282
- end
283
-
284
- def on_request_path?
285
- if options[:request_path].respond_to?(:call)
286
- options[:request_path].call(env)
287
- else
288
- on_path?(request_path)
289
- end
290
- end
291
-
292
- def on_callback_path?
293
- on_path?(callback_path)
294
194
  end
295
195
 
296
- def on_path?(path)
297
- current_path.casecmp(path).zero?
298
- end
196
+ # The authenticity token never goes into omniauth.params, so the app
197
+ # can't leak it by echoing the params back.
198
+ AUTHENTICITY_PARAM = 'authenticity_token'.freeze
299
199
 
300
- def options_request?
301
- request.request_method == 'OPTIONS'
200
+ # The params the app sent to the request phase, from both the query
201
+ # string and the form, which the callback phase hands back as
202
+ # env['omniauth.params'].
203
+ def omniauth_params
204
+ request.params.reject { |key, _| key.eql?(AUTHENTICITY_PARAM) }
302
205
  end
303
206
 
304
- # This is called in lieu of the normal request process
305
- # in the event that OmniAuth has been configured to be
306
- # in test mode.
307
- def mock_call!(*)
308
- begin
309
- return mock_request_call if on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
310
- return mock_callback_call if on_callback_path?
311
- rescue StandardError => e
312
- raise e if env.delete('omniauth.error.app')
313
-
314
- return fail!(e.message, e)
207
+ # Remembers where the user came from (the origin param, or else the
208
+ # referer) so the callback phase can send them back there.
209
+ def store_origin
210
+ origin = request.params[options.origin_param]
211
+ referer = env['HTTP_REFERER']
212
+ if origin
213
+ session['omniauth.origin'] = origin
214
+ elsif referer && !referer.match?(/#{request_path}$/)
215
+ session['omniauth.origin'] = referer
315
216
  end
316
-
317
- call_app!
318
217
  end
319
218
 
320
- def mock_request_call
219
+ # Performs the steps necessary to run the callback phase of a strategy.
220
+ def callback_call
321
221
  setup_phase
222
+ log :debug, 'Callback phase initiated.'
223
+ return invalid_host! unless allowed_host?
322
224
 
323
- session['omniauth.params'] = request.GET
324
-
325
- OmniAuth.config.request_validation_phase.call(env) if OmniAuth.config.request_validation_phase
326
- OmniAuth.config.before_request_phase.call(env) if OmniAuth.config.before_request_phase
327
-
328
- if options.origin_param
329
- if request.params[options.origin_param]
330
- session['omniauth.origin'] = request.params[options.origin_param]
331
- elsif env['HTTP_REFERER'] && !env['HTTP_REFERER'].match(/#{request_path}$/)
332
- session['omniauth.origin'] = env['HTTP_REFERER']
333
- end
334
- end
335
-
336
- result = redirect(callback_url)
337
-
338
- OmniAuth.config.after_request_phase.call(env) if OmniAuth.config.after_request_phase
339
- result
225
+ sign_in = recall_sign_in
226
+ origin = sign_in.fetch('origin')
227
+ env['omniauth.origin'] = (origin unless origin.eql?(''))
228
+ env['omniauth.params'] = sign_in.fetch('params') || {}
229
+ run_hook(:before_callback_phase)
230
+ callback_phase
340
231
  end
341
232
 
342
- def mock_callback_call
343
- setup_phase
344
-
345
- origin = session.delete('omniauth.origin')
346
- @env['omniauth.origin'] ||= origin
347
- @env['omniauth.origin'] = nil if env['omniauth.origin'] == ''
348
- @env['omniauth.params'] = session.delete('omniauth.params') || {}
349
-
350
- mocked_auth = OmniAuth.mock_auth_for(name.to_s)
351
- if mocked_auth.is_a?(Symbol)
352
- fail!(mocked_auth)
353
- else
354
- @env['omniauth.auth'] = mocked_auth
355
- OmniAuth.config.before_callback_phase.call(@env) if OmniAuth.config.before_callback_phase
356
- call_app!
357
- end
233
+ def options_request?
234
+ request.request_method.eql?('OPTIONS')
358
235
  end
359
236
 
360
237
  # The setup phase looks for the `:setup` option to exist and,
@@ -362,10 +239,11 @@ module OmniAuth
362
239
  # `:setup` option or it will call out to the setup path of the
363
240
  # underlying application. This will default to `/auth/:provider/setup`.
364
241
  def setup_phase
365
- if options[:setup].respond_to?(:call)
242
+ setup = options[:setup]
243
+ if setup.respond_to?(:call)
366
244
  log :debug, 'Setup endpoint detected, running now.'
367
- options[:setup].call(env)
368
- elsif options[:setup]
245
+ setup.call(env)
246
+ elsif setup
369
247
  log :debug, 'Calling through to underlying application for setup.'
370
248
  setup_env = env.merge('PATH_INFO' => setup_path, 'REQUEST_METHOD' => 'GET')
371
249
  call_app!(setup_env)
@@ -379,147 +257,28 @@ module OmniAuth
379
257
  raise(NotImplementedError)
380
258
  end
381
259
 
382
- def uid
383
- self.class.uid_stack(self).last
384
- end
385
-
386
- def info
387
- merge_stack(self.class.info_stack(self))
388
- end
389
-
390
- def credentials
391
- merge_stack(self.class.credentials_stack(self))
392
- end
393
-
394
- def extra
395
- merge_stack(self.class.extra_stack(self))
396
- end
397
-
398
- def auth_hash
399
- credentials_data = credentials
400
- extra_data = extra
401
- AuthHash.new(:provider => name, :uid => uid).tap do |auth|
402
- auth.info = info unless skip_info?
403
- auth.credentials = credentials_data if credentials_data
404
- auth.extra = extra_data if extra_data
405
- end
406
- end
407
-
408
- # Determines whether or not user info should be retrieved. This
409
- # allows some strategies to save a call to an external API service
410
- # for existing users. You can use it either by setting the `:skip_info`
411
- # to true or by setting `:skip_info` to a Proc that takes a uid and
412
- # evaluates to true when you would like to skip info.
413
- #
414
- # @example
415
- #
416
- # use MyStrategy, :skip_info => lambda{|uid| User.find_by_uid(uid)}
417
- def skip_info?
418
- return false unless options.skip_info?
419
- return true unless options.skip_info.respond_to?(:call)
420
-
421
- options.skip_info.call(uid)
422
- end
423
-
424
260
  def callback_phase
425
261
  env['omniauth.auth'] = auth_hash
426
262
  call_app!
427
263
  end
428
264
 
429
- def path_prefix
430
- options[:path_prefix] || OmniAuth.config.path_prefix
431
- end
432
-
433
- def custom_path(kind)
434
- if options[kind].respond_to?(:call)
435
- result = options[kind].call(env)
436
- return nil unless result.is_a?(String)
437
-
438
- result
439
- else
440
- options[kind]
441
- end
442
- end
443
-
444
- def request_path
445
- @request_path ||=
446
- if options[:request_path].is_a?(String)
447
- options[:request_path]
448
- else
449
- "#{script_name}#{path_prefix}/#{name}"
450
- end
451
- end
452
-
453
- def callback_path
454
- @callback_path ||= begin
455
- path = options[:callback_path] if options[:callback_path].is_a?(String)
456
- path ||= current_path if options[:callback_path].respond_to?(:call) && options[:callback_path].call(env)
457
- path ||= custom_path(:request_path)
458
- path ||= "#{script_name}#{path_prefix}/#{name}/callback"
459
- path
460
- end
461
- end
462
-
463
- def setup_path
464
- options[:setup_path] || "#{path_prefix}/#{name}/setup"
465
- end
466
-
467
- CURRENT_PATH_REGEX = %r{/$}.freeze
468
- EMPTY_STRING = ''.freeze
469
- def current_path
470
- @current_path ||= request.path.downcase.sub(CURRENT_PATH_REGEX, EMPTY_STRING)
471
- end
472
-
473
- def query_string
474
- request.query_string.empty? ? '' : "?#{request.query_string}"
475
- end
476
-
477
- def call_app!(env = @env)
478
- @app.call(env)
479
- rescue StandardError => e
480
- env['omniauth.error.app'] = true
481
- raise e
482
- end
483
-
484
- def full_host
485
- case OmniAuth.config.full_host
486
- when String
487
- OmniAuth.config.full_host
488
- when Proc
489
- OmniAuth.config.full_host.call(env)
490
- else
491
- # in Rack 1.3.x, request.url explodes if scheme is nil
492
- if request.scheme && URI.parse(request.url).absolute?
493
- uri = URI.parse(request.url.gsub(/\?.*$/, ''))
494
- uri.path = ''
495
- # sometimes the url is actually showing http inside rails because the
496
- # other layers (like nginx) have handled the ssl termination.
497
- uri.scheme = 'https' if ssl? # rubocop:disable BlockNesting
498
- uri.to_s
499
- else ''
500
- end
501
- end
502
- end
503
-
504
- def callback_url
505
- full_host + callback_path + query_string
506
- end
507
-
508
- def script_name
509
- return '' if @env.nil?
510
- @env['SCRIPT_NAME'] || ''
265
+ def call_app!(app_env = env)
266
+ @app.call(app_env)
267
+ rescue StandardError
268
+ app_env['omniauth.error.app'] = true
269
+ raise
511
270
  end
512
271
 
513
272
  def session
514
- @env['rack.session']
273
+ env['rack.session']
515
274
  end
516
275
 
517
276
  def request
518
- @request ||= Rack::Request.new(@env)
277
+ @request ||= Rack::Request.new(env)
519
278
  end
520
279
 
521
280
  def name
522
- options[:name]
281
+ options.fetch(:name)
523
282
  end
524
283
 
525
284
  def redirect(uri)
@@ -557,24 +316,53 @@ module OmniAuth
557
316
 
558
317
  protected
559
318
 
319
+ # Re-raises errors from the downstream app; reports anything else
320
+ # raised during a phase as an authentication failure.
321
+ def handle_phase_error(error)
322
+ raise error if env.delete('omniauth.error.app')
323
+
324
+ fail!(error.message, error)
325
+ end
326
+
327
+ # Calls the named OmniAuth.config hook (such as :before_request_phase)
328
+ # with the Rack env. A hook set to nil or false is skipped.
329
+ def run_hook(name)
330
+ hook = OmniAuth.config.public_send(name)
331
+ return unless hook # not hook&.call: a hook can be set to false
332
+
333
+ hook.call(env)
334
+ end
335
+
560
336
  def initialize_copy(*args)
561
337
  super
562
338
  @options = @options.dup
563
339
  end
564
340
 
565
- def merge_stack(stack)
566
- stack.inject({}) do |a, e|
567
- a.merge!(e)
568
- a
569
- end
341
+ # True when #call! would only hand env to the app: there's a session, the
342
+ # path alone decides, and env isn't on the strategy's paths. The
343
+ # strategy's own path methods check, on a copy that shares its options.
344
+ def passthrough?(env)
345
+ return false unless env['rack.session'] && dispatch_by_path?
346
+ return false if path_probe(env).on_auth_path?
347
+
348
+ true
349
+ end
350
+
351
+ # True when OmniAuth's own dispatch runs, with no test mode or
352
+ # other_phase, and no path lambdas, which would otherwise run twice on
353
+ # the strategy's own paths.
354
+ def dispatch_by_path?
355
+ self.class.default_dispatch? && !OmniAuth.config.test_mode && !respond_to?(:other_phase) &&
356
+ !options[:request_path].respond_to?(:call) && !options[:callback_path].respond_to?(:call)
570
357
  end
571
358
 
572
- def ssl?
573
- request.env['HTTPS'] == 'on' ||
574
- request.env['HTTP_X_FORWARDED_SSL'] == 'on' ||
575
- request.env['HTTP_X_FORWARDED_SCHEME'] == 'https' ||
576
- (request.env['HTTP_X_FORWARDED_PROTO'] && request.env['HTTP_X_FORWARDED_PROTO'].split(',')[0] == 'https') ||
577
- request.env['rack.url_scheme'] == 'https'
359
+ # A copy like #dup makes, but sharing this instance's options, so the
360
+ # path methods can memoize on it instead of on this shared instance.
361
+ def path_probe(env)
362
+ probe = self.class.allocate
363
+ instance_variables.each { |ivar| probe.instance_variable_set(ivar, instance_variable_get(ivar)) }
364
+ probe.instance_variable_set(:@env, env)
365
+ probe
578
366
  end
579
367
  end
580
368
  end
@@ -6,7 +6,7 @@ module OmniAuth
6
6
  end
7
7
 
8
8
  def call(env)
9
- @session ||= (env['rack.session'] || {})
9
+ @session ||= env['rack.session'] || {}
10
10
  env['rack.session'] = @session
11
11
  @app.call(env)
12
12
  end
@@ -18,18 +18,17 @@ module OmniAuth
18
18
  # end
19
19
  module StrategyTestCase
20
20
  def app
21
- strat = strategy
22
21
  resp = app_response
23
- Rack::Builder.new do
24
- use(OmniAuth::Test::PhonySession)
25
- use(*strat)
26
- run lambda { |env| [404, {'Content-Type' => 'text/plain'}, [resp || env.key?('omniauth.auth').to_s]] }
27
- end.to_app
22
+ builder = Rack::Builder.new
23
+ builder.use(PhonySession)
24
+ builder.use(*strategy)
25
+ # @type var endpoint: ^(Rack::env) -> Rack::response
26
+ endpoint = lambda { |env| [404, {'Content-Type' => 'text/plain'}, [resp || env.key?('omniauth.auth').to_s]] }
27
+ builder.run(endpoint)
28
+ builder.to_app
28
29
  end
29
30
 
30
- def app_response
31
- nil
32
- end
31
+ def app_response; end
33
32
 
34
33
  def session
35
34
  last_request.env['rack.session']
@@ -1,3 +1,3 @@
1
1
  module OmniAuth
2
- VERSION = '2.1.4'.freeze
2
+ VERSION = '2.3.0'.freeze
3
3
  end