omniauth 2.1.4 → 2.2.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,30 @@
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/test_mode'
2
7
 
3
8
  module OmniAuth
4
9
  class NoSessionError < StandardError; end
10
+
5
11
  # The Strategy is the base unit of OmniAuth's ability to
6
12
  # wrangle multiple providers. Each strategy provided by
7
13
  # OmniAuth includes this mixin to gain the default functionality
8
14
  # necessary to be compatible with the OmniAuth library.
9
- module Strategy # rubocop:disable ModuleLength
15
+ module Strategy # rubocop:disable Metrics/ModuleLength
16
+ include Fetchers
17
+ include Hosts
18
+ include Paths
19
+ include TestMode
20
+
10
21
  def self.included(base)
11
22
  OmniAuth.strategies << base
12
23
 
13
24
  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
25
+ base.option :setup, false
26
+ base.option :skip_info, false
27
+ base.option :origin_param, 'origin'
114
28
  end
115
29
 
116
30
  attr_reader :app, :env, :options, :response
@@ -130,7 +44,7 @@ module OmniAuth
130
44
  # will be passed through and set to the appropriate values.
131
45
  #
132
46
  # @yield [Options] Yields options to block for further configuration.
133
- def initialize(app, *args, &block) # rubocop:disable UnusedMethodArgument
47
+ def initialize(app, *args)
134
48
  @app = app
135
49
  @env = nil
136
50
  @options = self.class.default_options.dup
@@ -145,7 +59,7 @@ module OmniAuth
145
59
  end
146
60
 
147
61
  # 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?
62
+ raise(ArgumentError.new("Received wrong number of arguments. #{args}")) unless args.empty?
149
63
 
150
64
  yield options if block_given?
151
65
  end
@@ -160,12 +74,15 @@ module OmniAuth
160
74
  # @example
161
75
  # log :warn, "This is a warning."
162
76
  def log(level, message)
163
- OmniAuth.logger.send(level, "(#{name}) #{message}")
77
+ OmniAuth.logger.public_send(level, "(#{name}) #{message}")
164
78
  end
165
79
 
166
- # Duplicates this instance and runs #call! on it.
80
+ # Duplicates this instance and runs #call! on it. A request that can't be
81
+ # the strategy's goes straight to the app instead, skipping the copy.
167
82
  # @param [Hash] The Rack environment.
168
83
  def call(env)
84
+ return @app.call(env) if passthrough?(env)
85
+
169
86
  dup.call!(env)
170
87
  end
171
88
 
@@ -174,9 +91,9 @@ module OmniAuth
174
91
  # the request path is recognized.
175
92
  #
176
93
  # @param env [Hash] The Rack environment.
177
- def call!(env) # rubocop:disable CyclomaticComplexity, PerceivedComplexity
94
+ def call!(env)
178
95
  unless env['rack.session']
179
- error = OmniAuth::NoSessionError.new('You must provide a session to use OmniAuth.')
96
+ error = NoSessionError.new('You must provide a session to use OmniAuth.')
180
97
  raise(error)
181
98
  end
182
99
 
@@ -184,22 +101,37 @@ module OmniAuth
184
101
 
185
102
  warn_if_using_get_on_request_path
186
103
 
187
- @env['omniauth.strategy'] = self if on_auth_path?
104
+ env['omniauth.strategy'] = self if on_auth_path?
188
105
 
189
106
  return mock_call!(env) if OmniAuth.config.test_mode
190
107
 
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')
108
+ phase_call || @app.call(env)
109
+ end
198
110
 
199
- return fail!(e.message, e)
111
+ # Runs the phase that matches the current request, or returns nil
112
+ # if the request isn't for this strategy.
113
+ def phase_call
114
+ if options_call?
115
+ options_call
116
+ elsif request_call?
117
+ request_call
118
+ elsif on_callback_path?
119
+ callback_call
120
+ elsif respond_to?(:other_phase)
121
+ other_phase
200
122
  end
123
+ rescue StandardError => e
124
+ handle_phase_error(e)
125
+ end
126
+
127
+ # True for an OPTIONS request to the request or callback path.
128
+ def options_call?
129
+ on_auth_path? && options_request?
130
+ end
201
131
 
202
- @app.call(env)
132
+ # True for a request to the request path with an allowed method.
133
+ def request_call?
134
+ on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
203
135
  end
204
136
 
205
137
  def warn_if_using_get_on_request_path
@@ -224,137 +156,79 @@ module OmniAuth
224
156
 
225
157
  # Responds to an OPTIONS request.
226
158
  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(', ')
159
+ run_hook(:before_options_phase)
160
+ verbs = OmniAuth.config.allowed_request_methods.collect(&:upcase).join(', ')
229
161
  [200, {'Allow' => verbs}, []]
230
162
  end
231
163
 
232
164
  # Performs the steps necessary to run the request phase of a strategy.
233
- def request_call # rubocop:disable CyclomaticComplexity, MethodLength, PerceivedComplexity
165
+ def request_call
234
166
  setup_phase
235
167
  log :debug, 'Request phase initiated.'
168
+ warn_if_using_request_host
169
+ return invalid_host! unless allowed_host?
236
170
 
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
171
+ run_hook(:request_validation_phase)
172
+ session['omniauth.params'] = omniauth_params
173
+ run_hook(:before_request_phase)
174
+ request_response.tap { run_hook(:after_request_phase) }
175
+ rescue OmniAuth::AuthenticityError => e
176
+ fail!(:authenticity_error, e)
177
+ end
242
178
 
243
- result = if options.form.respond_to?(:call)
179
+ # Renders the login form (from a Rack endpoint or the app itself) if
180
+ # one is configured, or else runs the strategy's request phase.
181
+ def request_response
182
+ if options.form.respond_to?(:call)
244
183
  log :debug, 'Rendering form from supplied Rack endpoint.'
245
184
  options.form.call(env)
246
185
  elsif options.form
247
186
  log :debug, 'Rendering form from underlying application.'
248
187
  call_app!
249
- elsif !options.origin_param
250
- request_phase
251
188
  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
-
189
+ store_origin if options.origin_param
258
190
  request_phase
259
191
  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
192
  end
291
193
 
292
- def on_callback_path?
293
- on_path?(callback_path)
294
- end
194
+ # The authenticity token never goes into omniauth.params, so the app
195
+ # can't leak it by echoing the params back.
196
+ AUTHENTICITY_PARAM = 'authenticity_token'.freeze
295
197
 
296
- def on_path?(path)
297
- current_path.casecmp(path).zero?
198
+ # The params the app sent to the request phase, from both the query
199
+ # string and the form, which the callback phase hands back as
200
+ # env['omniauth.params'].
201
+ def omniauth_params
202
+ request.params.reject { |key, _| key.eql?(AUTHENTICITY_PARAM) }
298
203
  end
299
204
 
300
- def options_request?
301
- request.request_method == 'OPTIONS'
302
- end
303
-
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)
205
+ # Remembers where the user came from (the origin param, or else the
206
+ # referer) so the callback phase can send them back there.
207
+ def store_origin
208
+ origin = request.params[options.origin_param]
209
+ referer = env['HTTP_REFERER']
210
+ if origin
211
+ session['omniauth.origin'] = origin
212
+ elsif referer && !referer.match?(/#{request_path}$/)
213
+ session['omniauth.origin'] = referer
315
214
  end
316
-
317
- call_app!
318
215
  end
319
216
 
320
- def mock_request_call
321
- setup_phase
322
-
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
340
- end
341
-
342
- def mock_callback_call
217
+ # Performs the steps necessary to run the callback phase of a strategy.
218
+ def callback_call
343
219
  setup_phase
220
+ log :debug, 'Callback phase initiated.'
221
+ return invalid_host! unless allowed_host?
344
222
 
345
223
  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') || {}
224
+ env['omniauth.origin'] = (origin unless origin.eql?(''))
225
+ env['omniauth.params'] = session.delete('omniauth.params') || {}
226
+ run_hook(:before_callback_phase)
227
+ callback_phase
228
+ end
349
229
 
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
230
+ def options_request?
231
+ request.request_method.eql?('OPTIONS')
358
232
  end
359
233
 
360
234
  # The setup phase looks for the `:setup` option to exist and,
@@ -362,10 +236,11 @@ module OmniAuth
362
236
  # `:setup` option or it will call out to the setup path of the
363
237
  # underlying application. This will default to `/auth/:provider/setup`.
364
238
  def setup_phase
365
- if options[:setup].respond_to?(:call)
239
+ setup = options[:setup]
240
+ if setup.respond_to?(:call)
366
241
  log :debug, 'Setup endpoint detected, running now.'
367
- options[:setup].call(env)
368
- elsif options[:setup]
242
+ setup.call(env)
243
+ elsif setup
369
244
  log :debug, 'Calling through to underlying application for setup.'
370
245
  setup_env = env.merge('PATH_INFO' => setup_path, 'REQUEST_METHOD' => 'GET')
371
246
  call_app!(setup_env)
@@ -379,147 +254,28 @@ module OmniAuth
379
254
  raise(NotImplementedError)
380
255
  end
381
256
 
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
257
  def callback_phase
425
258
  env['omniauth.auth'] = auth_hash
426
259
  call_app!
427
260
  end
428
261
 
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'] || ''
262
+ def call_app!(app_env = env)
263
+ @app.call(app_env)
264
+ rescue StandardError
265
+ app_env['omniauth.error.app'] = true
266
+ raise
511
267
  end
512
268
 
513
269
  def session
514
- @env['rack.session']
270
+ env['rack.session']
515
271
  end
516
272
 
517
273
  def request
518
- @request ||= Rack::Request.new(@env)
274
+ @request ||= Rack::Request.new(env)
519
275
  end
520
276
 
521
277
  def name
522
- options[:name]
278
+ options.fetch(:name)
523
279
  end
524
280
 
525
281
  def redirect(uri)
@@ -557,24 +313,53 @@ module OmniAuth
557
313
 
558
314
  protected
559
315
 
316
+ # Re-raises errors from the downstream app; reports anything else
317
+ # raised during a phase as an authentication failure.
318
+ def handle_phase_error(error)
319
+ raise error if env.delete('omniauth.error.app')
320
+
321
+ fail!(error.message, error)
322
+ end
323
+
324
+ # Calls the named OmniAuth.config hook (such as :before_request_phase)
325
+ # with the Rack env. A hook set to nil or false is skipped.
326
+ def run_hook(name)
327
+ hook = OmniAuth.config.public_send(name)
328
+ return unless hook # not hook&.call: a hook can be set to false
329
+
330
+ hook.call(env)
331
+ end
332
+
560
333
  def initialize_copy(*args)
561
334
  super
562
335
  @options = @options.dup
563
336
  end
564
337
 
565
- def merge_stack(stack)
566
- stack.inject({}) do |a, e|
567
- a.merge!(e)
568
- a
569
- end
338
+ # True when #call! would only hand env to the app: there's a session, the
339
+ # path alone decides, and env isn't on the strategy's paths. The
340
+ # strategy's own path methods check, on a copy that shares its options.
341
+ def passthrough?(env)
342
+ return false unless env['rack.session'] && dispatch_by_path?
343
+ return false if path_probe(env).on_auth_path?
344
+
345
+ true
346
+ end
347
+
348
+ # True when OmniAuth's own dispatch runs, with no test mode or
349
+ # other_phase, and no path lambdas, which would otherwise run twice on
350
+ # the strategy's own paths.
351
+ def dispatch_by_path?
352
+ self.class.default_dispatch? && !OmniAuth.config.test_mode && !respond_to?(:other_phase) &&
353
+ !options[:request_path].respond_to?(:call) && !options[:callback_path].respond_to?(:call)
570
354
  end
571
355
 
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'
356
+ # A copy like #dup makes, but sharing this instance's options, so the
357
+ # path methods can memoize on it instead of on this shared instance.
358
+ def path_probe(env)
359
+ probe = self.class.allocate
360
+ instance_variables.each { |ivar| probe.instance_variable_set(ivar, instance_variable_get(ivar)) }
361
+ probe.instance_variable_set(:@env, env)
362
+ probe
578
363
  end
579
364
  end
580
365
  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.2.0'.freeze
3
3
  end