omniauth 1.2.2 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of omniauth might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +33 -57
- data/.travis.yml +16 -20
- data/Gemfile +7 -16
- data/Gemfile.rack-1.3.x +8 -13
- data/Gemfile.rack-master +16 -0
- data/README.md +1 -1
- data/lib/omniauth.rb +11 -15
- data/lib/omniauth/auth_hash.rb +1 -1
- data/lib/omniauth/builder.rb +6 -2
- data/lib/omniauth/form.rb +1 -1
- data/lib/omniauth/strategies/developer.rb +1 -1
- data/lib/omniauth/strategy.rb +26 -16
- data/lib/omniauth/version.rb +1 -1
- data/omniauth.gemspec +2 -3
- metadata +13 -24
- data/.gemtest +0 -0
- data/Guardfile +0 -10
- data/spec/helper.rb +0 -55
- data/spec/omniauth/auth_hash_spec.rb +0 -111
- data/spec/omniauth/builder_spec.rb +0 -50
- data/spec/omniauth/failure_endpoint_spec.rb +0 -58
- data/spec/omniauth/form_spec.rb +0 -23
- data/spec/omniauth/strategies/developer_spec.rb +0 -73
- data/spec/omniauth/strategy_spec.rb +0 -768
- data/spec/omniauth_spec.rb +0 -145
@@ -1,768 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
def make_env(path = '/auth/test', props = {})
|
4
|
-
{
|
5
|
-
'REQUEST_METHOD' => 'GET',
|
6
|
-
'PATH_INFO' => path,
|
7
|
-
'rack.session' => {},
|
8
|
-
'rack.input' => StringIO.new('test=true')
|
9
|
-
}.merge(props)
|
10
|
-
end
|
11
|
-
|
12
|
-
describe OmniAuth::Strategy do
|
13
|
-
let(:app) do
|
14
|
-
lambda { |_env| [404, {}, ['Awesome']] }
|
15
|
-
end
|
16
|
-
|
17
|
-
let(:fresh_strategy) do
|
18
|
-
c = Class.new
|
19
|
-
c.send(:include, OmniAuth::Strategy)
|
20
|
-
end
|
21
|
-
|
22
|
-
describe '.default_options' do
|
23
|
-
it 'is inherited from a parent class' do
|
24
|
-
superklass = Class.new
|
25
|
-
superklass.send :include, OmniAuth::Strategy
|
26
|
-
superklass.configure do |c|
|
27
|
-
c.foo = 'bar'
|
28
|
-
end
|
29
|
-
|
30
|
-
klass = Class.new(superklass)
|
31
|
-
expect(klass.default_options.foo).to eq('bar')
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe '.configure' do
|
36
|
-
subject do
|
37
|
-
c = Class.new
|
38
|
-
c.send(:include, OmniAuth::Strategy)
|
39
|
-
end
|
40
|
-
|
41
|
-
context 'when block is passed' do
|
42
|
-
it 'allows for default options setting' do
|
43
|
-
subject.configure do |c|
|
44
|
-
c.wakka = 'doo'
|
45
|
-
end
|
46
|
-
expect(subject.default_options['wakka']).to eq('doo')
|
47
|
-
end
|
48
|
-
|
49
|
-
it "works when block doesn't evaluate to true" do
|
50
|
-
environment_variable = nil
|
51
|
-
subject.configure do |c|
|
52
|
-
c.abc = '123'
|
53
|
-
c.hgi = environment_variable
|
54
|
-
end
|
55
|
-
expect(subject.default_options['abc']).to eq('123')
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'takes a hash and deep merge it' do
|
60
|
-
subject.configure :abc => {:def => 123}
|
61
|
-
subject.configure :abc => {:hgi => 456}
|
62
|
-
expect(subject.default_options['abc']).to eq('def' => 123, 'hgi' => 456)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
describe '#skip_info?' do
|
67
|
-
it 'is true if options.skip_info is true' do
|
68
|
-
expect(ExampleStrategy.new(app, :skip_info => true)).to be_skip_info
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'is false if options.skip_info is false' do
|
72
|
-
expect(ExampleStrategy.new(app, :skip_info => false)).not_to be_skip_info
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'is false by default' do
|
76
|
-
expect(ExampleStrategy.new(app)).not_to be_skip_info
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'is true if options.skip_info is a callable that evaluates to truthy' do
|
80
|
-
instance = ExampleStrategy.new(app, :skip_info => lambda { |uid| uid })
|
81
|
-
expect(instance).to receive(:uid).and_return(true)
|
82
|
-
expect(instance).to be_skip_info
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe '.option' do
|
87
|
-
subject do
|
88
|
-
c = Class.new
|
89
|
-
c.send(:include, OmniAuth::Strategy)
|
90
|
-
end
|
91
|
-
it 'sets a default value' do
|
92
|
-
subject.option :abc, 123
|
93
|
-
expect(subject.default_options.abc).to eq(123)
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'sets the default value to nil if none is provided' do
|
97
|
-
subject.option :abc
|
98
|
-
expect(subject.default_options.abc).to be_nil
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
describe '.args' do
|
103
|
-
subject do
|
104
|
-
c = Class.new
|
105
|
-
c.send(:include, OmniAuth::Strategy)
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'sets args to the specified argument if there is one' do
|
109
|
-
subject.args [:abc, :def]
|
110
|
-
expect(subject.args).to eq([:abc, :def])
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'is inheritable' do
|
114
|
-
subject.args [:abc, :def]
|
115
|
-
c = Class.new(subject)
|
116
|
-
expect(c.args).to eq([:abc, :def])
|
117
|
-
end
|
118
|
-
|
119
|
-
it 'accepts corresponding options as default arg values' do
|
120
|
-
subject.args [:a, :b]
|
121
|
-
subject.option :a, '1'
|
122
|
-
subject.option :b, '2'
|
123
|
-
|
124
|
-
expect(subject.new(nil).options.a).to eq '1'
|
125
|
-
expect(subject.new(nil).options.b).to eq '2'
|
126
|
-
expect(subject.new(nil, '3', '4').options.b).to eq '4'
|
127
|
-
expect(subject.new(nil, nil, '4').options.a).to eq nil
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
context 'fetcher procs' do
|
132
|
-
subject { fresh_strategy }
|
133
|
-
%w(uid info credentials extra).each do |fetcher|
|
134
|
-
describe ".#{fetcher}" do
|
135
|
-
it 'sets and retrieve a proc' do
|
136
|
-
proc = lambda { 'Hello' }
|
137
|
-
subject.send(fetcher, &proc)
|
138
|
-
expect(subject.send(fetcher)).to eq(proc)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
context 'fetcher stacks' do
|
145
|
-
subject { fresh_strategy }
|
146
|
-
%w(uid info credentials extra).each do |fetcher|
|
147
|
-
describe ".#{fetcher}_stack" do
|
148
|
-
it 'is an array of called ancestral procs' do
|
149
|
-
fetchy = proc { 'Hello' }
|
150
|
-
subject.send(fetcher, &fetchy)
|
151
|
-
expect(subject.send("#{fetcher}_stack", subject.new(app))).to eq(['Hello'])
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
%w(request_phase).each do |abstract_method|
|
158
|
-
context "#{abstract_method}" do
|
159
|
-
it 'raises a NotImplementedError' do
|
160
|
-
strat = Class.new
|
161
|
-
strat.send :include, OmniAuth::Strategy
|
162
|
-
expect { strat.new(app).send(abstract_method) }.to raise_error(NotImplementedError)
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
describe '#auth_hash' do
|
168
|
-
subject do
|
169
|
-
klass = Class.new
|
170
|
-
klass.send :include, OmniAuth::Strategy
|
171
|
-
klass.option :name, 'auth_hasher'
|
172
|
-
klass
|
173
|
-
end
|
174
|
-
let(:instance) { subject.new(app) }
|
175
|
-
|
176
|
-
it 'calls through to uid and info' do
|
177
|
-
expect(instance).to receive(:uid)
|
178
|
-
expect(instance).to receive(:info)
|
179
|
-
instance.auth_hash
|
180
|
-
end
|
181
|
-
|
182
|
-
it 'returns an AuthHash' do
|
183
|
-
allow(instance).to receive(:uid).and_return('123')
|
184
|
-
allow(instance).to receive(:info).and_return(:name => 'Hal Awesome')
|
185
|
-
hash = instance.auth_hash
|
186
|
-
expect(hash).to be_kind_of(OmniAuth::AuthHash)
|
187
|
-
expect(hash.uid).to eq('123')
|
188
|
-
expect(hash.info.name).to eq('Hal Awesome')
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
describe '#initialize' do
|
193
|
-
context 'options extraction' do
|
194
|
-
it 'is the last argument if the last argument is a Hash' do
|
195
|
-
expect(ExampleStrategy.new(app, :abc => 123).options[:abc]).to eq(123)
|
196
|
-
end
|
197
|
-
|
198
|
-
it 'is the default options if any are provided' do
|
199
|
-
allow(ExampleStrategy).to receive(:default_options).and_return(OmniAuth::Strategy::Options.new(:abc => 123))
|
200
|
-
expect(ExampleStrategy.new(app).options.abc).to eq(123)
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
context 'custom args' do
|
205
|
-
subject do
|
206
|
-
c = Class.new
|
207
|
-
c.send(:include, OmniAuth::Strategy)
|
208
|
-
end
|
209
|
-
|
210
|
-
it 'sets options based on the arguments if they are supplied' do
|
211
|
-
subject.args [:abc, :def]
|
212
|
-
s = subject.new app, 123, 456
|
213
|
-
expect(s.options[:abc]).to eq(123)
|
214
|
-
expect(s.options[:def]).to eq(456)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
describe '#call' do
|
220
|
-
it 'duplicates and calls' do
|
221
|
-
klass = Class.new
|
222
|
-
klass.send :include, OmniAuth::Strategy
|
223
|
-
instance = klass.new(app)
|
224
|
-
expect(instance).to receive(:dup).and_return(instance)
|
225
|
-
instance.call('rack.session' => {})
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
describe '#inspect' do
|
230
|
-
it 'returns the class name' do
|
231
|
-
expect(ExampleStrategy.new(app).inspect).to eq('#<ExampleStrategy>')
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
describe '#redirect' do
|
236
|
-
it 'uses javascript if :iframe is true' do
|
237
|
-
response = ExampleStrategy.new(app, :iframe => true).redirect('http://abc.com')
|
238
|
-
expect(response.last.body.first).to be_include('top.location.href')
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
describe '#callback_phase' do
|
243
|
-
subject do
|
244
|
-
c = Class.new
|
245
|
-
c.send(:include, OmniAuth::Strategy)
|
246
|
-
c.new(app)
|
247
|
-
end
|
248
|
-
|
249
|
-
it 'sets the auth hash' do
|
250
|
-
env = make_env
|
251
|
-
allow(subject).to receive(:env).and_return(env)
|
252
|
-
allow(subject).to receive(:auth_hash).and_return('AUTH HASH')
|
253
|
-
subject.callback_phase
|
254
|
-
expect(env['omniauth.auth']).to eq('AUTH HASH')
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
describe '#full_host' do
|
259
|
-
let(:strategy) { ExampleStrategy.new(app, {}) }
|
260
|
-
it 'remains calm when there is a pipe in the URL' do
|
261
|
-
strategy.call!(make_env('/whatever', 'rack.url_scheme' => 'http', 'SERVER_NAME' => 'facebook.lame', 'QUERY_STRING' => 'code=asofibasf|asoidnasd', 'SCRIPT_NAME' => '', 'SERVER_PORT' => 80))
|
262
|
-
expect { strategy.full_host }.not_to raise_error
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
describe '#uid' do
|
267
|
-
subject { fresh_strategy }
|
268
|
-
it "is the current class's uid if one exists" do
|
269
|
-
subject.uid { 'Hi' }
|
270
|
-
expect(subject.new(app).uid).to eq('Hi')
|
271
|
-
end
|
272
|
-
|
273
|
-
it 'inherits if it can' do
|
274
|
-
subject.uid { 'Hi' }
|
275
|
-
c = Class.new(subject)
|
276
|
-
expect(c.new(app).uid).to eq('Hi')
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
%w(info credentials extra).each do |fetcher|
|
281
|
-
subject { fresh_strategy }
|
282
|
-
it "is the current class's proc call if one exists" do
|
283
|
-
subject.send(fetcher) { {:abc => 123} }
|
284
|
-
expect(subject.new(app).send(fetcher)).to eq(:abc => 123)
|
285
|
-
end
|
286
|
-
|
287
|
-
it 'inherits by merging with preference for the latest class' do
|
288
|
-
subject.send(fetcher) { {:abc => 123, :def => 456} }
|
289
|
-
c = Class.new(subject)
|
290
|
-
c.send(fetcher) { {:abc => 789} }
|
291
|
-
expect(c.new(app).send(fetcher)).to eq(:abc => 789, :def => 456)
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
|
-
describe '#call' do
|
296
|
-
before(:all) do
|
297
|
-
@options = nil
|
298
|
-
end
|
299
|
-
|
300
|
-
let(:strategy) { ExampleStrategy.new(app, @options || {}) }
|
301
|
-
|
302
|
-
context 'omniauth.origin' do
|
303
|
-
it 'is set on the request phase' do
|
304
|
-
expect { strategy.call(make_env('/auth/test', 'HTTP_REFERER' => 'http://example.com/origin')) }.to raise_error('Request Phase')
|
305
|
-
expect(strategy.last_env['rack.session']['omniauth.origin']).to eq('http://example.com/origin')
|
306
|
-
end
|
307
|
-
|
308
|
-
it 'is turned into an env variable on the callback phase' do
|
309
|
-
expect { strategy.call(make_env('/auth/test/callback', 'rack.session' => {'omniauth.origin' => 'http://example.com/origin'})) }.to raise_error('Callback Phase')
|
310
|
-
expect(strategy.last_env['omniauth.origin']).to eq('http://example.com/origin')
|
311
|
-
end
|
312
|
-
|
313
|
-
it 'sets from the params if provided' do
|
314
|
-
expect { strategy.call(make_env('/auth/test', 'QUERY_STRING' => 'origin=/foo')) }.to raise_error('Request Phase')
|
315
|
-
expect(strategy.last_env['rack.session']['omniauth.origin']).to eq('/foo')
|
316
|
-
end
|
317
|
-
|
318
|
-
it 'is set on the failure env' do
|
319
|
-
expect(OmniAuth.config).to receive(:on_failure).and_return(lambda { |env| env })
|
320
|
-
@options = {:failure => :forced_fail}
|
321
|
-
strategy.call(make_env('/auth/test/callback', 'rack.session' => {'omniauth.origin' => '/awesome'}))
|
322
|
-
end
|
323
|
-
|
324
|
-
context 'with script_name' do
|
325
|
-
it 'is set on the request phase, containing full path' do
|
326
|
-
env = {'HTTP_REFERER' => 'http://example.com/sub_uri/origin', 'SCRIPT_NAME' => '/sub_uri'}
|
327
|
-
expect { strategy.call(make_env('/auth/test', env)) }.to raise_error('Request Phase')
|
328
|
-
expect(strategy.last_env['rack.session']['omniauth.origin']).to eq('http://example.com/sub_uri/origin')
|
329
|
-
end
|
330
|
-
|
331
|
-
it 'is turned into an env variable on the callback phase, containing full path' do
|
332
|
-
env = {
|
333
|
-
'rack.session' => {'omniauth.origin' => 'http://example.com/sub_uri/origin'},
|
334
|
-
'SCRIPT_NAME' => '/sub_uri'
|
335
|
-
}
|
336
|
-
|
337
|
-
expect { strategy.call(make_env('/auth/test/callback', env)) }.to raise_error('Callback Phase')
|
338
|
-
expect(strategy.last_env['omniauth.origin']).to eq('http://example.com/sub_uri/origin')
|
339
|
-
end
|
340
|
-
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
context 'default paths' do
|
345
|
-
it 'uses the default request path' do
|
346
|
-
expect { strategy.call(make_env) }.to raise_error('Request Phase')
|
347
|
-
end
|
348
|
-
|
349
|
-
it 'is case insensitive on request path' do
|
350
|
-
expect { strategy.call(make_env('/AUTH/Test')) }.to raise_error('Request Phase')
|
351
|
-
end
|
352
|
-
|
353
|
-
it 'is case insensitive on callback path' do
|
354
|
-
expect { strategy.call(make_env('/AUTH/TeSt/CaLlBAck')) }.to raise_error('Callback Phase')
|
355
|
-
end
|
356
|
-
|
357
|
-
it 'uses the default callback path' do
|
358
|
-
expect { strategy.call(make_env('/auth/test/callback')) }.to raise_error('Callback Phase')
|
359
|
-
end
|
360
|
-
|
361
|
-
it 'strips trailing spaces on request' do
|
362
|
-
expect { strategy.call(make_env('/auth/test/')) }.to raise_error('Request Phase')
|
363
|
-
end
|
364
|
-
|
365
|
-
it 'strips trailing spaces on callback' do
|
366
|
-
expect { strategy.call(make_env('/auth/test/callback/')) }.to raise_error('Callback Phase')
|
367
|
-
end
|
368
|
-
|
369
|
-
context 'callback_url' do
|
370
|
-
it 'uses the default callback_path' do
|
371
|
-
expect(strategy).to receive(:full_host).and_return('http://example.com')
|
372
|
-
|
373
|
-
expect { strategy.call(make_env) }.to raise_error('Request Phase')
|
374
|
-
|
375
|
-
expect(strategy.callback_url).to eq('http://example.com/auth/test/callback')
|
376
|
-
end
|
377
|
-
|
378
|
-
it 'preserves the query parameters' do
|
379
|
-
allow(strategy).to receive(:full_host).and_return('http://example.com')
|
380
|
-
begin
|
381
|
-
strategy.call(make_env('/auth/test', 'QUERY_STRING' => 'id=5'))
|
382
|
-
rescue RuntimeError
|
383
|
-
end
|
384
|
-
expect(strategy.callback_url).to eq('http://example.com/auth/test/callback?id=5')
|
385
|
-
end
|
386
|
-
|
387
|
-
it 'consider script name' do
|
388
|
-
allow(strategy).to receive(:full_host).and_return('http://example.com')
|
389
|
-
begin
|
390
|
-
strategy.call(make_env('/auth/test', 'SCRIPT_NAME' => '/sub_uri'))
|
391
|
-
rescue RuntimeError
|
392
|
-
end
|
393
|
-
expect(strategy.callback_url).to eq('http://example.com/sub_uri/auth/test/callback')
|
394
|
-
end
|
395
|
-
end
|
396
|
-
end
|
397
|
-
|
398
|
-
context ':form option' do
|
399
|
-
it 'calls through to the supplied form option if one exists' do
|
400
|
-
strategy.options.form = lambda { |_env| 'Called me!' }
|
401
|
-
expect(strategy.call(make_env('/auth/test'))).to eq('Called me!')
|
402
|
-
end
|
403
|
-
|
404
|
-
it 'calls through to the app if :form => true is set as an option' do
|
405
|
-
strategy.options.form = true
|
406
|
-
expect(strategy.call(make_env('/auth/test'))).to eq(app.call(make_env('/auth/test')))
|
407
|
-
end
|
408
|
-
end
|
409
|
-
|
410
|
-
context 'dynamic paths' do
|
411
|
-
it 'runs the request phase if the custom request path evaluator is truthy' do
|
412
|
-
@options = {:request_path => lambda { |_env| true }}
|
413
|
-
expect { strategy.call(make_env('/asoufibasfi')) }.to raise_error('Request Phase')
|
414
|
-
end
|
415
|
-
|
416
|
-
it 'runs the callback phase if the custom callback path evaluator is truthy' do
|
417
|
-
@options = {:callback_path => lambda { |_env| true }}
|
418
|
-
expect { strategy.call(make_env('/asoufiasod')) }.to raise_error('Callback Phase')
|
419
|
-
end
|
420
|
-
|
421
|
-
it 'provides a custom callback path if request_path evals to a string' do
|
422
|
-
strategy_instance = fresh_strategy.new(nil, :request_path => lambda { |_env| '/auth/boo/callback/22' })
|
423
|
-
expect(strategy_instance.callback_path).to eq('/auth/boo/callback/22')
|
424
|
-
end
|
425
|
-
|
426
|
-
it 'correctly reports the callback path when the custom callback path evaluator is truthy' do
|
427
|
-
strategy_instance = ExampleStrategy.new(app,
|
428
|
-
:callback_path => lambda { |env| env['PATH_INFO'] == '/auth/bish/bosh/callback' }
|
429
|
-
)
|
430
|
-
|
431
|
-
expect { strategy_instance.call(make_env('/auth/bish/bosh/callback')) }.to raise_error('Callback Phase')
|
432
|
-
expect(strategy_instance.callback_path).to eq('/auth/bish/bosh/callback')
|
433
|
-
end
|
434
|
-
end
|
435
|
-
|
436
|
-
context 'custom paths' do
|
437
|
-
it 'uses a custom request_path if one is provided' do
|
438
|
-
@options = {:request_path => '/awesome'}
|
439
|
-
expect { strategy.call(make_env('/awesome')) }.to raise_error('Request Phase')
|
440
|
-
end
|
441
|
-
|
442
|
-
it 'uses a custom callback_path if one is provided' do
|
443
|
-
@options = {:callback_path => '/radical'}
|
444
|
-
expect { strategy.call(make_env('/radical')) }.to raise_error('Callback Phase')
|
445
|
-
end
|
446
|
-
|
447
|
-
context 'callback_url' do
|
448
|
-
it 'uses a custom callback_path if one is provided' do
|
449
|
-
@options = {:callback_path => '/radical'}
|
450
|
-
expect(strategy).to receive(:full_host).and_return('http://example.com')
|
451
|
-
|
452
|
-
expect { strategy.call(make_env('/radical')) }.to raise_error('Callback Phase')
|
453
|
-
|
454
|
-
expect(strategy.callback_url).to eq('http://example.com/radical')
|
455
|
-
end
|
456
|
-
|
457
|
-
it 'preserves the query parameters' do
|
458
|
-
@options = {:callback_path => '/radical'}
|
459
|
-
allow(strategy).to receive(:full_host).and_return('http://example.com')
|
460
|
-
begin
|
461
|
-
strategy.call(make_env('/auth/test', 'QUERY_STRING' => 'id=5'))
|
462
|
-
rescue RuntimeError
|
463
|
-
end
|
464
|
-
expect(strategy.callback_url).to eq('http://example.com/radical?id=5')
|
465
|
-
end
|
466
|
-
end
|
467
|
-
end
|
468
|
-
|
469
|
-
context 'custom prefix' do
|
470
|
-
before do
|
471
|
-
@options = {:path_prefix => '/wowzers'}
|
472
|
-
end
|
473
|
-
|
474
|
-
it 'uses a custom prefix for request' do
|
475
|
-
expect { strategy.call(make_env('/wowzers/test')) }.to raise_error('Request Phase')
|
476
|
-
end
|
477
|
-
|
478
|
-
it 'uses a custom prefix for callback' do
|
479
|
-
expect { strategy.call(make_env('/wowzers/test/callback')) }.to raise_error('Callback Phase')
|
480
|
-
end
|
481
|
-
|
482
|
-
context 'callback_url' do
|
483
|
-
it 'uses a custom prefix' do
|
484
|
-
expect(strategy).to receive(:full_host).and_return('http://example.com')
|
485
|
-
|
486
|
-
expect { strategy.call(make_env('/wowzers/test')) }.to raise_error('Request Phase')
|
487
|
-
|
488
|
-
expect(strategy.callback_url).to eq('http://example.com/wowzers/test/callback')
|
489
|
-
end
|
490
|
-
|
491
|
-
it 'preserves the query parameters' do
|
492
|
-
allow(strategy).to receive(:full_host).and_return('http://example.com')
|
493
|
-
begin
|
494
|
-
strategy.call(make_env('/auth/test', 'QUERY_STRING' => 'id=5'))
|
495
|
-
rescue RuntimeError
|
496
|
-
end
|
497
|
-
expect(strategy.callback_url).to eq('http://example.com/wowzers/test/callback?id=5')
|
498
|
-
end
|
499
|
-
end
|
500
|
-
end
|
501
|
-
|
502
|
-
context 'request method restriction' do
|
503
|
-
before do
|
504
|
-
OmniAuth.config.allowed_request_methods = [:post]
|
505
|
-
end
|
506
|
-
|
507
|
-
it 'does not allow a request method of the wrong type' do
|
508
|
-
expect { strategy.call(make_env) }.not_to raise_error
|
509
|
-
end
|
510
|
-
|
511
|
-
it 'allows a request method of the correct type' do
|
512
|
-
expect { strategy.call(make_env('/auth/test', 'REQUEST_METHOD' => 'POST')) }.to raise_error('Request Phase')
|
513
|
-
end
|
514
|
-
|
515
|
-
after do
|
516
|
-
OmniAuth.config.allowed_request_methods = [:get, :post]
|
517
|
-
end
|
518
|
-
end
|
519
|
-
|
520
|
-
context 'receiving an OPTIONS request' do
|
521
|
-
shared_examples_for 'an OPTIONS request' do
|
522
|
-
it 'responds with 200' do
|
523
|
-
expect(response[0]).to eq(200)
|
524
|
-
end
|
525
|
-
|
526
|
-
it 'sets the Allow header properly' do
|
527
|
-
expect(response[1]['Allow']).to eq('GET, POST')
|
528
|
-
end
|
529
|
-
end
|
530
|
-
|
531
|
-
context 'to the request path' do
|
532
|
-
let(:response) { strategy.call(make_env('/auth/test', 'REQUEST_METHOD' => 'OPTIONS')) }
|
533
|
-
it_behaves_like 'an OPTIONS request'
|
534
|
-
end
|
535
|
-
|
536
|
-
context 'to the request path' do
|
537
|
-
let(:response) { strategy.call(make_env('/auth/test/callback', 'REQUEST_METHOD' => 'OPTIONS')) }
|
538
|
-
it_behaves_like 'an OPTIONS request'
|
539
|
-
end
|
540
|
-
|
541
|
-
context 'to some other path' do
|
542
|
-
it 'does not short-circuit the request' do
|
543
|
-
env = make_env('/other', 'REQUEST_METHOD' => 'OPTIONS')
|
544
|
-
expect(strategy.call(env)).to eq(app.call(env))
|
545
|
-
end
|
546
|
-
end
|
547
|
-
end
|
548
|
-
|
549
|
-
context 'test mode' do
|
550
|
-
let(:app) do
|
551
|
-
# In test mode, the underlying app shouldn't be called on request phase.
|
552
|
-
lambda { |_env| [404, {'Content-Type' => 'text/html'}, []] }
|
553
|
-
end
|
554
|
-
|
555
|
-
before do
|
556
|
-
OmniAuth.config.test_mode = true
|
557
|
-
end
|
558
|
-
|
559
|
-
it 'short circuits the request phase entirely' do
|
560
|
-
response = strategy.call(make_env)
|
561
|
-
expect(response[0]).to eq(302)
|
562
|
-
expect(response[1]['Location']).to eq('/auth/test/callback')
|
563
|
-
end
|
564
|
-
|
565
|
-
it 'is case insensitive on request path' do
|
566
|
-
expect(strategy.call(make_env('/AUTH/Test'))[0]).to eq(302)
|
567
|
-
end
|
568
|
-
|
569
|
-
it 'respects SCRIPT_NAME (a.k.a. BaseURI)' do
|
570
|
-
response = strategy.call(make_env('/auth/test', 'SCRIPT_NAME' => '/sub_uri'))
|
571
|
-
expect(response[1]['Location']).to eq('/sub_uri/auth/test/callback')
|
572
|
-
end
|
573
|
-
|
574
|
-
it 'redirects on failure' do
|
575
|
-
response = OmniAuth.config.on_failure.call(make_env('/auth/test', 'omniauth.error.type' => 'error'))
|
576
|
-
expect(response[0]).to eq(302)
|
577
|
-
expect(response[1]['Location']).to eq('/auth/failure?message=error')
|
578
|
-
end
|
579
|
-
|
580
|
-
it 'respects SCRIPT_NAME (a.k.a. BaseURI) on failure' do
|
581
|
-
response = OmniAuth.config.on_failure.call(make_env('/auth/test', 'SCRIPT_NAME' => '/sub_uri', 'omniauth.error.type' => 'error'))
|
582
|
-
expect(response[0]).to eq(302)
|
583
|
-
expect(response[1]['Location']).to eq('/sub_uri/auth/failure?message=error')
|
584
|
-
end
|
585
|
-
|
586
|
-
it 'is case insensitive on callback path' do
|
587
|
-
expect(strategy.call(make_env('/AUTH/TeSt/CaLlBAck')).first).to eq(strategy.call(make_env('/auth/test/callback')).first)
|
588
|
-
end
|
589
|
-
|
590
|
-
it 'maintains host and port' do
|
591
|
-
response = strategy.call(make_env('/auth/test', 'rack.url_scheme' => 'http', 'HTTP_HOST' => 'example.org', 'SERVER_PORT' => 3000))
|
592
|
-
expect(response[1]['Location']).to eq('http://example.org:3000/auth/test/callback')
|
593
|
-
end
|
594
|
-
|
595
|
-
it 'maintains query string parameters' do
|
596
|
-
response = strategy.call(make_env('/auth/test', 'QUERY_STRING' => 'cheese=stilton'))
|
597
|
-
expect(response[1]['Location']).to eq('/auth/test/callback?cheese=stilton')
|
598
|
-
end
|
599
|
-
|
600
|
-
it 'does not short circuit requests outside of authentication' do
|
601
|
-
expect(strategy.call(make_env('/'))).to eq(app.call(make_env('/')))
|
602
|
-
end
|
603
|
-
|
604
|
-
it 'responds with the default hash if none is set' do
|
605
|
-
OmniAuth.config.mock_auth[:test] = nil
|
606
|
-
|
607
|
-
strategy.call make_env('/auth/test/callback')
|
608
|
-
expect(strategy.env['omniauth.auth']['uid']).to eq('1234')
|
609
|
-
end
|
610
|
-
|
611
|
-
it 'responds with a provider-specific hash if one is set' do
|
612
|
-
OmniAuth.config.mock_auth[:test] = {
|
613
|
-
'uid' => 'abc'
|
614
|
-
}
|
615
|
-
|
616
|
-
strategy.call make_env('/auth/test/callback')
|
617
|
-
expect(strategy.env['omniauth.auth']['uid']).to eq('abc')
|
618
|
-
end
|
619
|
-
|
620
|
-
it 'simulates login failure if mocked data is set as a symbol' do
|
621
|
-
OmniAuth.config.mock_auth[:test] = :invalid_credentials
|
622
|
-
|
623
|
-
strategy.call make_env('/auth/test/callback')
|
624
|
-
expect(strategy.env['omniauth.error.type']).to eq(:invalid_credentials)
|
625
|
-
end
|
626
|
-
|
627
|
-
it 'sets omniauth.origin on the request phase' do
|
628
|
-
strategy.call(make_env('/auth/test', 'HTTP_REFERER' => 'http://example.com/origin'))
|
629
|
-
expect(strategy.env['rack.session']['omniauth.origin']).to eq('http://example.com/origin')
|
630
|
-
end
|
631
|
-
|
632
|
-
it 'sets omniauth.origin from the params if provided' do
|
633
|
-
strategy.call(make_env('/auth/test', 'QUERY_STRING' => 'origin=/foo'))
|
634
|
-
expect(strategy.env['rack.session']['omniauth.origin']).to eq('/foo')
|
635
|
-
end
|
636
|
-
|
637
|
-
it 'turns omniauth.origin into an env variable on the callback phase' do
|
638
|
-
OmniAuth.config.mock_auth[:test] = {}
|
639
|
-
|
640
|
-
strategy.call(make_env('/auth/test/callback', 'rack.session' => {'omniauth.origin' => 'http://example.com/origin'}))
|
641
|
-
expect(strategy.env['omniauth.origin']).to eq('http://example.com/origin')
|
642
|
-
end
|
643
|
-
|
644
|
-
it 'executes callback hook on the callback phase' do
|
645
|
-
OmniAuth.config.mock_auth[:test] = {}
|
646
|
-
OmniAuth.config.before_callback_phase do |env|
|
647
|
-
env['foobar'] = 'baz'
|
648
|
-
end
|
649
|
-
strategy.call(make_env('/auth/test/callback', 'rack.session' => {'omniauth.origin' => 'http://example.com/origin'}))
|
650
|
-
expect(strategy.env['foobar']).to eq('baz')
|
651
|
-
end
|
652
|
-
|
653
|
-
it 'sets omniauth.params on the request phase' do
|
654
|
-
OmniAuth.config.mock_auth[:test] = {}
|
655
|
-
|
656
|
-
strategy.call(make_env('/auth/test', 'QUERY_STRING' => 'foo=bar'))
|
657
|
-
expect(strategy.env['rack.session']['omniauth.params']).to eq('foo' => 'bar')
|
658
|
-
end
|
659
|
-
|
660
|
-
it 'executes request hook on the request phase' do
|
661
|
-
OmniAuth.config.mock_auth[:test] = {}
|
662
|
-
OmniAuth.config.before_request_phase do |env|
|
663
|
-
env['foobar'] = 'baz'
|
664
|
-
end
|
665
|
-
strategy.call(make_env('/auth/test', 'QUERY_STRING' => 'foo=bar'))
|
666
|
-
expect(strategy.env['foobar']).to eq('baz')
|
667
|
-
end
|
668
|
-
|
669
|
-
it 'turns omniauth.params into an env variable on the callback phase' do
|
670
|
-
OmniAuth.config.mock_auth[:test] = {}
|
671
|
-
|
672
|
-
strategy.call(make_env('/auth/test/callback', 'rack.session' => {'omniauth.params' => {'foo' => 'bar'}}))
|
673
|
-
expect(strategy.env['omniauth.params']).to eq('foo' => 'bar')
|
674
|
-
end
|
675
|
-
|
676
|
-
after do
|
677
|
-
OmniAuth.config.test_mode = false
|
678
|
-
end
|
679
|
-
end
|
680
|
-
|
681
|
-
context 'custom full_host' do
|
682
|
-
before do
|
683
|
-
OmniAuth.config.test_mode = true
|
684
|
-
end
|
685
|
-
|
686
|
-
it 'is the string when a string is there' do
|
687
|
-
OmniAuth.config.full_host = 'my.host.com'
|
688
|
-
expect(strategy.full_host).to eq('my.host.com')
|
689
|
-
end
|
690
|
-
|
691
|
-
it 'runs the proc with the env when it is a proc' do
|
692
|
-
OmniAuth.config.full_host = proc { |env| env['HOST'] }
|
693
|
-
strategy.call(make_env('/auth/test', 'HOST' => 'my.host.net'))
|
694
|
-
expect(strategy.full_host).to eq('my.host.net')
|
695
|
-
end
|
696
|
-
|
697
|
-
it "is based on the request if it's not a string nor a proc" do
|
698
|
-
OmniAuth.config.full_host = nil
|
699
|
-
strategy.call(make_env('/whatever', 'rack.url_scheme' => 'http', 'SERVER_NAME' => 'my.host.net', 'SERVER_PORT' => 80))
|
700
|
-
expect(strategy.full_host).to eq('http://my.host.net')
|
701
|
-
end
|
702
|
-
|
703
|
-
it 'honors HTTP_X_FORWARDED_PROTO if present' do
|
704
|
-
OmniAuth.config.full_host = nil
|
705
|
-
strategy.call(make_env('/whatever', 'HTTP_X_FORWARDED_PROTO' => 'https', 'rack.url_scheme' => 'http', 'SERVER_NAME' => 'my.host.net', 'SERVER_PORT' => 443))
|
706
|
-
expect(strategy.full_host).to eq('https://my.host.net')
|
707
|
-
end
|
708
|
-
|
709
|
-
after do
|
710
|
-
OmniAuth.config.full_host = nil
|
711
|
-
OmniAuth.config.test_mode = false
|
712
|
-
end
|
713
|
-
end
|
714
|
-
end
|
715
|
-
|
716
|
-
context 'setup phase' do
|
717
|
-
before do
|
718
|
-
OmniAuth.config.test_mode = true
|
719
|
-
end
|
720
|
-
|
721
|
-
context 'when options[:setup] = true' do
|
722
|
-
let(:strategy) do
|
723
|
-
ExampleStrategy.new(app, :setup => true)
|
724
|
-
end
|
725
|
-
|
726
|
-
let(:app) do
|
727
|
-
lambda do |env|
|
728
|
-
env['omniauth.strategy'].options[:awesome] = 'sauce' if env['PATH_INFO'] == '/auth/test/setup'
|
729
|
-
[404, {}, 'Awesome']
|
730
|
-
end
|
731
|
-
end
|
732
|
-
|
733
|
-
it 'calls through to /auth/:provider/setup' do
|
734
|
-
strategy.call(make_env('/auth/test'))
|
735
|
-
expect(strategy.options[:awesome]).to eq('sauce')
|
736
|
-
end
|
737
|
-
|
738
|
-
it 'does not call through on a non-omniauth endpoint' do
|
739
|
-
strategy.call(make_env('/somewhere/else'))
|
740
|
-
expect(strategy.options[:awesome]).not_to eq('sauce')
|
741
|
-
end
|
742
|
-
end
|
743
|
-
|
744
|
-
context 'when options[:setup] is an app' do
|
745
|
-
let(:setup_proc) do
|
746
|
-
proc do |env|
|
747
|
-
env['omniauth.strategy'].options[:awesome] = 'sauce'
|
748
|
-
end
|
749
|
-
end
|
750
|
-
|
751
|
-
let(:strategy) { ExampleStrategy.new(app, :setup => setup_proc) }
|
752
|
-
|
753
|
-
it 'does not call the app on a non-omniauth endpoint' do
|
754
|
-
strategy.call(make_env('/somehwere/else'))
|
755
|
-
expect(strategy.options[:awesome]).not_to eq('sauce')
|
756
|
-
end
|
757
|
-
|
758
|
-
it 'calls the rack app' do
|
759
|
-
strategy.call(make_env('/auth/test'))
|
760
|
-
expect(strategy.options[:awesome]).to eq('sauce')
|
761
|
-
end
|
762
|
-
end
|
763
|
-
|
764
|
-
after do
|
765
|
-
OmniAuth.config.test_mode = false
|
766
|
-
end
|
767
|
-
end
|
768
|
-
end
|