loyal_warden 0.0.5
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.
- data/Gemfile +11 -0
- data/History.rdoc +150 -0
- data/LICENSE +20 -0
- data/README.textile +9 -0
- data/Rakefile +12 -0
- data/lib/loyal_warden.rb +2 -0
- data/lib/warden.rb +45 -0
- data/lib/warden/config.rb +112 -0
- data/lib/warden/errors.rb +66 -0
- data/lib/warden/hooks.rb +211 -0
- data/lib/warden/manager.rb +136 -0
- data/lib/warden/mixins/common.rb +44 -0
- data/lib/warden/proxy.rb +371 -0
- data/lib/warden/session_serializer.rb +52 -0
- data/lib/warden/strategies.rb +47 -0
- data/lib/warden/strategies/base.rb +175 -0
- data/lib/warden/test/helpers.rb +36 -0
- data/lib/warden/test/warden_helpers.rb +43 -0
- data/lib/warden/version.rb +4 -0
- data/loyal_warden.gemspec +26 -0
- data/spec/helpers/request_helper.rb +51 -0
- data/spec/helpers/strategies/failz.rb +8 -0
- data/spec/helpers/strategies/invalid.rb +8 -0
- data/spec/helpers/strategies/pass.rb +8 -0
- data/spec/helpers/strategies/pass_with_message.rb +8 -0
- data/spec/helpers/strategies/password.rb +13 -0
- data/spec/helpers/strategies/single.rb +12 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/warden/authenticated_data_store_spec.rb +114 -0
- data/spec/warden/config_spec.rb +48 -0
- data/spec/warden/errors_spec.rb +47 -0
- data/spec/warden/hooks_spec.rb +373 -0
- data/spec/warden/manager_spec.rb +316 -0
- data/spec/warden/proxy_spec.rb +1041 -0
- data/spec/warden/scoped_session_serializer.rb +123 -0
- data/spec/warden/session_serializer_spec.rb +53 -0
- data/spec/warden/strategies/base_spec.rb +313 -0
- data/spec/warden/strategies_spec.rb +93 -0
- data/spec/warden/test/helpers_spec.rb +93 -0
- data/spec/warden/test/test_mode_spec.rb +76 -0
- data/warden.gemspec +24 -0
- metadata +105 -0
@@ -0,0 +1,316 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Warden::Manager do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
load_strategies
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should insert a Proxy object into the rack env" do
|
11
|
+
env = env_with_params
|
12
|
+
setup_rack(success_app).call(env)
|
13
|
+
env["warden"].should be_an_instance_of(Warden::Proxy)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "thrown auth" do
|
17
|
+
before(:each) do
|
18
|
+
@basic_app = lambda{|env| [200,{'Content-Type' => 'text/plain'},'OK']}
|
19
|
+
@authd_app = lambda do |e|
|
20
|
+
if e['warden'].authenticated?
|
21
|
+
[200,{'Content-Type' => 'text/plain'},"OK"]
|
22
|
+
else
|
23
|
+
[401,{'Content-Type' => 'text/plain'},"Fail From The App"]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
@env = Rack::MockRequest.
|
27
|
+
env_for('/', 'HTTP_VERSION' => '1.1', 'REQUEST_METHOD' => 'GET')
|
28
|
+
end # before(:each)
|
29
|
+
|
30
|
+
describe "Failure" do
|
31
|
+
it "should respond with a 401 response if the strategy fails authentication" do
|
32
|
+
env = env_with_params("/", :foo => "bar")
|
33
|
+
app = lambda do |env|
|
34
|
+
env['warden'].authenticate(:failz)
|
35
|
+
throw(:warden, :action => :unauthenticated)
|
36
|
+
end
|
37
|
+
result = setup_rack(app, :failure_app => @fail_app).call(env)
|
38
|
+
result.first.should == 401
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should use the failure message given to the failure method" do
|
42
|
+
env = env_with_params("/", {})
|
43
|
+
app = lambda do |env|
|
44
|
+
env['warden'].authenticate(:failz)
|
45
|
+
throw(:warden)
|
46
|
+
end
|
47
|
+
result = setup_rack(app, :failure_app => @fail_app).call(env)
|
48
|
+
result.last.should == ["You Fail!"]
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should render the failure app when there's a failure" do
|
52
|
+
app = lambda do |e|
|
53
|
+
throw(:warden, :action => :unauthenticated) unless e['warden'].authenticated?(:failz)
|
54
|
+
end
|
55
|
+
fail_app = lambda do |e|
|
56
|
+
[401, {"Content-Type" => "text/plain"}, ["Failure App"]]
|
57
|
+
end
|
58
|
+
result = setup_rack(app, :failure_app => fail_app).call(env_with_params)
|
59
|
+
result.last.should == ["Failure App"]
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should call failure app if warden is thrown even after successful authentication" do
|
63
|
+
env = env_with_params("/", {})
|
64
|
+
app = lambda do |env|
|
65
|
+
env['warden'].authenticate(:pass)
|
66
|
+
throw(:warden)
|
67
|
+
end
|
68
|
+
result = setup_rack(app, :failure_app => @fail_app).call(env)
|
69
|
+
result.first.should == 401
|
70
|
+
result.last.should == ["You Fail!"]
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should set the attempted url in warden.options hash" do
|
74
|
+
env = env_with_params("/access/path", {})
|
75
|
+
app = lambda do |env|
|
76
|
+
env['warden'].authenticate(:pass)
|
77
|
+
throw(:warden)
|
78
|
+
end
|
79
|
+
result = setup_rack(app, :failure_app => @fail_app).call(env)
|
80
|
+
result.first.should == 401
|
81
|
+
env["warden.options"][:attempted_path].should == "/access/path"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should catch a resubmitted request" do
|
85
|
+
# this is a bit convoluted. but it's occurred in the field with Rack::OpenID
|
86
|
+
$count = 0
|
87
|
+
$throw_count = 0
|
88
|
+
env = env_with_params("/foo")
|
89
|
+
class ::ResubmittingMiddleware
|
90
|
+
@@app = nil
|
91
|
+
def initialize(app)
|
92
|
+
@@app = app
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.call(env)
|
96
|
+
if $count > 1
|
97
|
+
Rack::Response.new("Bad", 401)
|
98
|
+
else
|
99
|
+
$count += 1
|
100
|
+
@@app.call(env)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def call(env)
|
105
|
+
$count += 1
|
106
|
+
@@app.call(env)
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
app = lambda do |e|
|
112
|
+
$throw_count += 1
|
113
|
+
throw(:warden)
|
114
|
+
end
|
115
|
+
|
116
|
+
builder = Rack::Builder.new do
|
117
|
+
use ResubmittingMiddleware
|
118
|
+
use Warden::Manager do |config|
|
119
|
+
config.failure_app = ResubmittingMiddleware
|
120
|
+
end
|
121
|
+
run app
|
122
|
+
end
|
123
|
+
|
124
|
+
result = builder.to_app.call(env)
|
125
|
+
result[0].should == 401
|
126
|
+
result[2].body.should == ["Bad"]
|
127
|
+
$throw_count.should == 2
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should use the default scopes action when a bare throw is used" do
|
131
|
+
env = env_with_params("/", :foo => "bar")
|
132
|
+
action = nil
|
133
|
+
|
134
|
+
failure = lambda do |env|
|
135
|
+
action = env['PATH_INFO']
|
136
|
+
[401, {}, ['fail']]
|
137
|
+
end
|
138
|
+
|
139
|
+
app = lambda do |env|
|
140
|
+
throw(:warden)
|
141
|
+
end
|
142
|
+
result = setup_rack(app,
|
143
|
+
:failure_app => failure,
|
144
|
+
:configurator => lambda{ |c| c.scope_defaults(:default, :action => 'my_action', :strategies => [:password]) }
|
145
|
+
).call(env)
|
146
|
+
|
147
|
+
action.should == "/my_action"
|
148
|
+
result.first.should == 401
|
149
|
+
end
|
150
|
+
end # failure
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "integrated strategies" do
|
154
|
+
before(:each) do
|
155
|
+
RAS = Warden::Strategies unless defined?(RAS)
|
156
|
+
Warden::Strategies.clear!
|
157
|
+
@app = setup_rack do |env|
|
158
|
+
env['warden'].authenticate!(:foobar)
|
159
|
+
[200, {"Content-Type" => "text/plain"}, ["Foo Is A Winna"]]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "redirecting" do
|
164
|
+
|
165
|
+
it "should redirect with a message" do
|
166
|
+
RAS.add(:foobar) do
|
167
|
+
def authenticate!
|
168
|
+
redirect!("/foo/bar", {:foo => "bar"}, :message => "custom redirection message")
|
169
|
+
end
|
170
|
+
end
|
171
|
+
result = @app.call(env_with_params)
|
172
|
+
result[0].should == 302
|
173
|
+
result[1]["Location"].should == "/foo/bar?foo=bar"
|
174
|
+
result[2].should == ["custom redirection message"]
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should redirect with a default message" do
|
178
|
+
RAS.add(:foobar) do
|
179
|
+
def authenticate!
|
180
|
+
redirect!("/foo/bar", {:foo => "bar"})
|
181
|
+
end
|
182
|
+
end
|
183
|
+
result = @app.call(env_with_params)
|
184
|
+
result[0].should == 302
|
185
|
+
result[1]['Location'].should == "/foo/bar?foo=bar"
|
186
|
+
result[2].should == ["You are being redirected to /foo/bar?foo=bar"]
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should redirect with a permanent redirect" do
|
190
|
+
RAS.add(:foobar) do
|
191
|
+
def authenticate!
|
192
|
+
redirect!("/foo/bar", {}, :permanent => true)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
result = @app.call(env_with_params)
|
196
|
+
result[0].should == 301
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should redirect with a content type" do
|
200
|
+
RAS.add(:foobar) do
|
201
|
+
def authenticate!
|
202
|
+
redirect!("/foo/bar", {:foo => "bar"}, :content_type => "text/xml")
|
203
|
+
end
|
204
|
+
end
|
205
|
+
result = @app.call(env_with_params)
|
206
|
+
result[0].should == 302
|
207
|
+
result[1]["Location"].should == "/foo/bar?foo=bar"
|
208
|
+
result[1]["Content-Type"].should == "text/xml"
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should redirect with a default content type" do
|
212
|
+
RAS.add(:foobar) do
|
213
|
+
def authenticate!
|
214
|
+
redirect!("/foo/bar", {:foo => "bar"})
|
215
|
+
end
|
216
|
+
end
|
217
|
+
result = @app.call(env_with_params)
|
218
|
+
result[0].should == 302
|
219
|
+
result[1]["Location"].should == "/foo/bar?foo=bar"
|
220
|
+
result[1]["Content-Type"].should == "text/plain"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
describe "failing" do
|
225
|
+
it "should fail according to the failure app" do
|
226
|
+
RAS.add(:foobar) do
|
227
|
+
def authenticate!
|
228
|
+
fail!
|
229
|
+
end
|
230
|
+
end
|
231
|
+
env = env_with_params
|
232
|
+
result = @app.call(env)
|
233
|
+
result[0].should == 401
|
234
|
+
result[2].should == ["You Fail!"]
|
235
|
+
env['PATH_INFO'].should == "/unauthenticated"
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should allow you to customize the response" do
|
239
|
+
app = lambda do |e|
|
240
|
+
e['warden'].custom_failure!
|
241
|
+
[401,{'Content-Type' => 'text/plain'},["Fail From The App"]]
|
242
|
+
end
|
243
|
+
env = env_with_params
|
244
|
+
result = setup_rack(app).call(env)
|
245
|
+
result[0].should == 401
|
246
|
+
result[2].should == ["Fail From The App"]
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should allow you to customize the response without the explicit call to custom_failure! if not intercepting 401" do
|
250
|
+
app = lambda do |e|
|
251
|
+
[401,{'Content-Type' => 'text/plain'},["Fail From The App"]]
|
252
|
+
end
|
253
|
+
env = env_with_params
|
254
|
+
result = setup_rack(app, :intercept_401 => false).call(env)
|
255
|
+
result[0].should == 401
|
256
|
+
result[2].should == ["Fail From The App"]
|
257
|
+
end
|
258
|
+
|
259
|
+
it "should render the failure application for a 401 if no custom_failure flag is set" do
|
260
|
+
app = lambda do |e|
|
261
|
+
[401,{'Content-Type' => 'text/plain'},["Fail From The App"]]
|
262
|
+
end
|
263
|
+
result = setup_rack(app).call(env_with_params)
|
264
|
+
result[0].should == 401
|
265
|
+
result[2].should == ["You Fail!"]
|
266
|
+
end
|
267
|
+
|
268
|
+
end # failing
|
269
|
+
|
270
|
+
describe "custom rack response" do
|
271
|
+
it "should return a custom rack response" do
|
272
|
+
RAS.add(:foobar) do
|
273
|
+
def authenticate!
|
274
|
+
custom!([523, {"Content-Type" => "text/plain", "Custom-Header" => "foo"}, ["Custom Stuff"]])
|
275
|
+
end
|
276
|
+
end
|
277
|
+
result = @app.call(env_with_params)
|
278
|
+
result[0].should == 523
|
279
|
+
result[1]["Custom-Header"].should == "foo"
|
280
|
+
result[2].should == ["Custom Stuff"]
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
describe "success" do
|
285
|
+
it "should pass through to the application when there is success" do
|
286
|
+
RAS.add(:foobar) do
|
287
|
+
def authenticate!
|
288
|
+
success!("A User")
|
289
|
+
end
|
290
|
+
end
|
291
|
+
env = env_with_params
|
292
|
+
result = @app.call(env)
|
293
|
+
result[0].should == 200
|
294
|
+
result[2].should == ["Foo Is A Winna"]
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end # integrated strategies
|
298
|
+
|
299
|
+
it "should allow me to set a different default scope for warden" do
|
300
|
+
Rack::Builder.new do
|
301
|
+
use Warden::Manager, :default_scope => :default do |manager|
|
302
|
+
manager.default_scope.should == :default
|
303
|
+
manager.default_scope = :other
|
304
|
+
manager.default_scope.should == :other
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
it "should allow me to access strategies through manager" do
|
310
|
+
Rack::Builder.new do
|
311
|
+
use Warden::Manager do |manager|
|
312
|
+
manager.strategies.should == Warden::Strategies
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
@@ -0,0 +1,1041 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Warden::Proxy do
|
5
|
+
before(:all) do
|
6
|
+
load_strategies
|
7
|
+
end
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
@basic_app = lambda{|env| [200,{'Content-Type' => 'text/plain'},'OK']}
|
11
|
+
@authd_app = lambda do |e|
|
12
|
+
e['warden'].authenticate
|
13
|
+
if e['warden'].authenticated?
|
14
|
+
[200,{'Content-Type' => 'text/plain'},"OK"]
|
15
|
+
else
|
16
|
+
[401,{'Content-Type' => 'text/plain'},"You Fail"]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
@env = env_with_params("/")
|
20
|
+
end # before(:each)
|
21
|
+
|
22
|
+
describe "authentication" do
|
23
|
+
|
24
|
+
it "should not check the authentication if it is not checked" do
|
25
|
+
app = setup_rack(@basic_app)
|
26
|
+
app.call(@env).first.should == 200
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should check the authentication if it is explicity checked" do
|
30
|
+
app = setup_rack(@authd_app)
|
31
|
+
app.call(@env).first.should == 401
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not allow the request if incorrect conditions are supplied" do
|
35
|
+
env = env_with_params("/", :foo => "bar")
|
36
|
+
app = setup_rack(@authd_app)
|
37
|
+
response = app.call(env)
|
38
|
+
response.first.should == 401
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should allow the request if the correct conditions are supplied" do
|
42
|
+
env = env_with_params("/", :username => "fred", :password => "sekrit")
|
43
|
+
app = setup_rack(@authd_app)
|
44
|
+
resp = app.call(env)
|
45
|
+
resp.first.should == 200
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should allow authentication in my application" do
|
49
|
+
env = env_with_params('/', :username => "fred", :password => "sekrit")
|
50
|
+
app = lambda do |env|
|
51
|
+
env['warden'].authenticate
|
52
|
+
env['warden'].should be_authenticated
|
53
|
+
env['warden.spec.strategies'].should == [:password]
|
54
|
+
valid_response
|
55
|
+
end
|
56
|
+
setup_rack(app).call(env)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should allow me to select which strategies I use in my appliction" do
|
60
|
+
env = env_with_params("/", :foo => "bar")
|
61
|
+
app = lambda do |env|
|
62
|
+
env['warden'].authenticate(:failz)
|
63
|
+
env['warden'].should_not be_authenticated
|
64
|
+
env['warden.spec.strategies'].should == [:failz]
|
65
|
+
valid_response
|
66
|
+
end
|
67
|
+
setup_rack(app).call(env)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should raise error on missing strategies" do
|
71
|
+
app = lambda do |env|
|
72
|
+
env['warden'].authenticate(:unknown)
|
73
|
+
end
|
74
|
+
lambda {
|
75
|
+
setup_rack(app).call(@env)
|
76
|
+
}.should raise_error(RuntimeError, "Invalid strategy unknown")
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should not raise error on missing strategies if silencing" do
|
80
|
+
app = lambda do |env|
|
81
|
+
env['warden'].authenticate
|
82
|
+
valid_response
|
83
|
+
end
|
84
|
+
lambda {
|
85
|
+
setup_rack(app, :silence_missing_strategies => true, :default_strategies => [:unknown]).call(@env)
|
86
|
+
}.should_not raise_error
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should allow me to get access to the user at warden.user." do
|
90
|
+
app = lambda do |env|
|
91
|
+
env['warden'].authenticate(:pass)
|
92
|
+
env['warden'].should be_authenticated
|
93
|
+
env['warden.spec.strategies'].should == [:pass]
|
94
|
+
valid_response
|
95
|
+
end
|
96
|
+
setup_rack(app).call(@env)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should run strategies when authenticate? is asked" do
|
100
|
+
app = lambda do |env|
|
101
|
+
env['warden'].should_not be_authenticated
|
102
|
+
env['warden'].authenticate?(:pass)
|
103
|
+
env['warden'].should be_authenticated
|
104
|
+
env['warden.spec.strategies'].should == [:pass]
|
105
|
+
valid_response
|
106
|
+
end
|
107
|
+
setup_rack(app).call(@env)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should properly send the scope to the strategy" do
|
111
|
+
app = lambda do |env|
|
112
|
+
env['warden'].authenticate(:pass, :scope => :failz)
|
113
|
+
env['warden'].should_not be_authenticated
|
114
|
+
env['warden.spec.strategies'].should == [:pass]
|
115
|
+
valid_response
|
116
|
+
end
|
117
|
+
setup_rack(app).call(@env)
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should try multiple authentication strategies" do
|
121
|
+
app = lambda do |env|
|
122
|
+
env['warden'].authenticate(:password,:pass)
|
123
|
+
env['warden'].should be_authenticated
|
124
|
+
env['warden.spec.strategies'].should == [:password, :pass]
|
125
|
+
valid_response
|
126
|
+
end
|
127
|
+
setup_rack(app).call(@env)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should look for an active user in the session with authenticate" do
|
131
|
+
app = lambda do |env|
|
132
|
+
env['rack.session']["warden.user.default.key"] = "foo as a user"
|
133
|
+
env['warden'].authenticate(:pass)
|
134
|
+
valid_response
|
135
|
+
end
|
136
|
+
setup_rack(app).call(@env)
|
137
|
+
@env['warden'].user.should == "foo as a user"
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should look for an active user in the session with authenticate?" do
|
141
|
+
app = lambda do |env|
|
142
|
+
env['rack.session']['warden.user.foo_scope.key'] = "a foo user"
|
143
|
+
env['warden'].authenticate?(:pass, :scope => :foo_scope)
|
144
|
+
valid_response
|
145
|
+
end
|
146
|
+
setup_rack(app).call(@env)
|
147
|
+
@env['warden'].user(:foo_scope).should == "a foo user"
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should look for an active user in the session with authenticate!" do
|
151
|
+
app = lambda do |env|
|
152
|
+
env['rack.session']['warden.user.foo_scope.key'] = "a foo user"
|
153
|
+
env['warden'].authenticate!(:pass, :scope => :foo_scope)
|
154
|
+
valid_response
|
155
|
+
end
|
156
|
+
setup_rack(app).call(@env)
|
157
|
+
@env['warden'].user(:foo_scope).should == "a foo user"
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should throw an error when authenticate!" do
|
161
|
+
app = lambda do |env|
|
162
|
+
env['warden'].authenticate!(:pass, :scope => :failz)
|
163
|
+
raise "OMG"
|
164
|
+
end
|
165
|
+
setup_rack(app).call(@env)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should login 2 different users from the session" do
|
169
|
+
app = lambda do |env|
|
170
|
+
env['rack.session']['warden.user.foo.key'] = 'foo user'
|
171
|
+
env['rack.session']['warden.user.bar.key'] = 'bar user'
|
172
|
+
env['warden'].should be_authenticated(:foo)
|
173
|
+
env['warden'].should be_authenticated(:bar)
|
174
|
+
env['warden'].should_not be_authenticated # default scope
|
175
|
+
valid_response
|
176
|
+
end
|
177
|
+
setup_rack(app).call(@env)
|
178
|
+
@env['warden'].user(:foo).should == 'foo user'
|
179
|
+
@env['warden'].user(:bar).should == 'bar user'
|
180
|
+
@env['warden'].user.should be_nil
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should not authenticate other scopes just because the first is authenticated" do
|
184
|
+
app = lambda do |env|
|
185
|
+
env['warden'].authenticate(:pass, :scope => :foo)
|
186
|
+
env['warden'].authenticate(:invalid, :scope => :bar)
|
187
|
+
env['warden'].should be_authenticated(:foo)
|
188
|
+
env['warden'].should_not be_authenticated(:bar)
|
189
|
+
valid_response
|
190
|
+
end
|
191
|
+
setup_rack(app).call(@env)
|
192
|
+
end
|
193
|
+
|
194
|
+
SID_REGEXP = /rack\.session=([^;]*);/
|
195
|
+
|
196
|
+
it "should renew session when user is set" do
|
197
|
+
app = lambda do |env|
|
198
|
+
env["rack.session"]["counter"] ||= 0
|
199
|
+
env["rack.session"]["counter"] += 1
|
200
|
+
if env["warden.on"]
|
201
|
+
env["warden"].authenticate!(:pass)
|
202
|
+
env["warden"].should be_authenticated
|
203
|
+
end
|
204
|
+
valid_response
|
205
|
+
end
|
206
|
+
|
207
|
+
# Setup a rack app with Pool session.
|
208
|
+
app = setup_rack(app, :session => Rack::Session::Pool).to_app
|
209
|
+
response = app.call(@env)
|
210
|
+
@env["rack.session"]["counter"].should == 1
|
211
|
+
|
212
|
+
# Ensure a cookie was given back
|
213
|
+
cookie = response[1]["Set-Cookie"]
|
214
|
+
cookie.should_not be_nil
|
215
|
+
|
216
|
+
# Ensure a session id was given
|
217
|
+
sid = cookie.match(SID_REGEXP)[1]
|
218
|
+
sid.should_not be_nil
|
219
|
+
|
220
|
+
# Do another request, giving a cookie but turning on warden authentication
|
221
|
+
env = env_with_params("/", {}, 'rack.session' => @env['rack.session'], "HTTP_COOKIE" => cookie, "warden.on" => true)
|
222
|
+
response = app.call(env)
|
223
|
+
env["rack.session"]["counter"].should == 2
|
224
|
+
|
225
|
+
# Regardless of rack version, a cookie should be sent back
|
226
|
+
new_cookie = response[1]["Set-Cookie"]
|
227
|
+
new_cookie.should_not be_nil
|
228
|
+
|
229
|
+
# And the session id in this cookie should not be the same as the previous one
|
230
|
+
new_sid = new_cookie.match(SID_REGEXP)[1]
|
231
|
+
new_sid.should_not be_nil
|
232
|
+
new_sid.should_not == sid
|
233
|
+
end
|
234
|
+
|
235
|
+
it "should not renew session when user is fetch" do
|
236
|
+
app = lambda do |env|
|
237
|
+
env["rack.session"]["counter"] ||= 0
|
238
|
+
env["rack.session"]["counter"] += 1
|
239
|
+
env["warden"].authenticate!(:pass)
|
240
|
+
env["warden"].should be_authenticated
|
241
|
+
valid_response
|
242
|
+
end
|
243
|
+
|
244
|
+
# Setup a rack app with Pool session.
|
245
|
+
app = setup_rack(app, :session => Rack::Session::Pool).to_app
|
246
|
+
response = app.call(@env)
|
247
|
+
@env["rack.session"]["counter"].should == 1
|
248
|
+
|
249
|
+
# Ensure a cookie was given back
|
250
|
+
cookie = response[1]["Set-Cookie"]
|
251
|
+
cookie.should_not be_nil
|
252
|
+
|
253
|
+
# Ensure a session id was given
|
254
|
+
sid = cookie.match(SID_REGEXP)[1]
|
255
|
+
sid.should_not be_nil
|
256
|
+
|
257
|
+
# Do another request, passing the cookie. The user should be fetched from cookie.
|
258
|
+
env = env_with_params("/", {}, "HTTP_COOKIE" => cookie)
|
259
|
+
response = app.call(env)
|
260
|
+
env["rack.session"]["counter"].should == 2
|
261
|
+
|
262
|
+
# Depending on rack version, a cookie will be returned with the
|
263
|
+
# same session id or no cookie is given back (becase it did not change).
|
264
|
+
# If we don't get any of these two behaviors, raise an error.
|
265
|
+
# Regardless of rack version, a cookie should be sent back
|
266
|
+
new_cookie = response[1]["Set-Cookie"]
|
267
|
+
if new_cookie && new_cookie.match(SID_REGEXP)[1] != sid
|
268
|
+
raise "Expected a cookie to not be sent or session id to match"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
describe "authentication cache" do
|
274
|
+
it "should run strategies just once for a given scope" do
|
275
|
+
app = lambda do |env|
|
276
|
+
env['warden'].authenticate(:password, :pass, :scope => :failz)
|
277
|
+
env['warden'].should_not be_authenticated(:failz)
|
278
|
+
env['warden'].authenticate(:password, :pass, :scope => :failz)
|
279
|
+
env['warden'].should_not be_authenticated(:failz)
|
280
|
+
env['warden.spec.strategies'].should == [:password, :pass]
|
281
|
+
valid_response
|
282
|
+
end
|
283
|
+
setup_rack(app).call(@env)
|
284
|
+
end
|
285
|
+
|
286
|
+
it "should run strategies for a given scope several times if cache is cleaned" do
|
287
|
+
app = lambda do |env|
|
288
|
+
env['warden'].authenticate(:password, :pass, :scope => :failz)
|
289
|
+
env['warden'].clear_strategies_cache!(:scope => :failz)
|
290
|
+
env['warden'].authenticate(:password, :pass, :scope => :failz)
|
291
|
+
env['warden.spec.strategies'].should == [:password, :pass, :password, :pass]
|
292
|
+
valid_response
|
293
|
+
end
|
294
|
+
setup_rack(app).call(@env)
|
295
|
+
end
|
296
|
+
|
297
|
+
it "should clear the cache for a specified strategy" do
|
298
|
+
app = lambda do |env|
|
299
|
+
env['warden'].authenticate(:password, :pass, :scope => :failz)
|
300
|
+
env['warden'].clear_strategies_cache!(:password, :scope => :failz)
|
301
|
+
env['warden'].authenticate(:password, :pass, :scope => :failz)
|
302
|
+
env['warden.spec.strategies'].should == [:password, :pass, :password]
|
303
|
+
valid_response
|
304
|
+
end
|
305
|
+
setup_rack(app).call(@env)
|
306
|
+
end
|
307
|
+
|
308
|
+
it "should run the strategies several times for different scopes" do
|
309
|
+
app = lambda do |env|
|
310
|
+
env['warden'].authenticate(:password, :pass, :scope => :failz)
|
311
|
+
env['warden'].should_not be_authenticated(:failz)
|
312
|
+
env['warden'].authenticate(:password, :pass)
|
313
|
+
env['warden'].should be_authenticated
|
314
|
+
env['warden.spec.strategies'].should == [:password, :pass, :password, :pass]
|
315
|
+
valid_response
|
316
|
+
end
|
317
|
+
setup_rack(app).call(@env)
|
318
|
+
end
|
319
|
+
|
320
|
+
it "should not run strategies until cache is cleaned if latest winning strategy halted" do
|
321
|
+
app = lambda do |env|
|
322
|
+
env['warden'].authenticate(:failz)
|
323
|
+
env['warden'].should_not be_authenticated
|
324
|
+
env['warden'].authenticate(:pass)
|
325
|
+
env['warden'].winning_strategy.message.should == "The Fails Strategy Has Failed You"
|
326
|
+
valid_response
|
327
|
+
end
|
328
|
+
setup_rack(app).call(@env)
|
329
|
+
end
|
330
|
+
|
331
|
+
it "should not store user if strategy isn't meant for permanent login" do
|
332
|
+
session = Warden::SessionSerializer.new(@env)
|
333
|
+
app = lambda do |env|
|
334
|
+
env['warden'].authenticate(:single)
|
335
|
+
env['warden'].should be_authenticated
|
336
|
+
env['warden'].user.should == "Valid User"
|
337
|
+
session.should_not be_stored(:default)
|
338
|
+
valid_response
|
339
|
+
end
|
340
|
+
setup_rack(app).call(@env)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
describe "set user" do
|
345
|
+
it "should store the user into the session" do
|
346
|
+
app = lambda do |env|
|
347
|
+
env['warden'].authenticate(:pass)
|
348
|
+
env['warden'].should be_authenticated
|
349
|
+
env['warden'].user.should == "Valid User"
|
350
|
+
env['rack.session']["warden.user.default.key"].should == "Valid User"
|
351
|
+
valid_response
|
352
|
+
end
|
353
|
+
setup_rack(app).call(@env)
|
354
|
+
end
|
355
|
+
|
356
|
+
it "should not store the user if the :store option is set to false" do
|
357
|
+
app = lambda do |env|
|
358
|
+
env['warden'].authenticate(:pass, :store => false)
|
359
|
+
env['warden'].should be_authenticated
|
360
|
+
env['warden'].user.should == "Valid User"
|
361
|
+
env['rack.session']['warden.user.default.key'].should be_nil
|
362
|
+
valid_response
|
363
|
+
end
|
364
|
+
setup_rack(app).call(@env)
|
365
|
+
end
|
366
|
+
|
367
|
+
it "should not throw error when no session is configured and store is false" do
|
368
|
+
app = lambda do |env|
|
369
|
+
env['rack.session'] = nil
|
370
|
+
env['warden'].authenticate(:pass, :store => false)
|
371
|
+
env['warden'].should be_authenticated
|
372
|
+
env['warden'].user.should == "Valid User"
|
373
|
+
valid_response
|
374
|
+
end
|
375
|
+
setup_rack(app).call(@env)
|
376
|
+
end
|
377
|
+
|
378
|
+
it "should not run the callbacks when :run_callbacks is false" do
|
379
|
+
app = lambda do |env|
|
380
|
+
env['warden'].manager.should_not_receive(:_run_callbacks)
|
381
|
+
env['warden'].authenticate(:run_callbacks => false, :scope => :pass)
|
382
|
+
valid_response
|
383
|
+
end
|
384
|
+
setup_rack(app).call(@env)
|
385
|
+
end
|
386
|
+
|
387
|
+
it "should run the callbacks when :run_callbacks is true" do
|
388
|
+
app = lambda do |env|
|
389
|
+
env['warden'].manager.should_receive(:_run_callbacks).at_least(:once)
|
390
|
+
env['warden'].authenticate(:pass)
|
391
|
+
valid_response
|
392
|
+
end
|
393
|
+
setup_rack(app).call(@env)
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should run the callbacks by default" do
|
397
|
+
app = lambda do |env|
|
398
|
+
env['warden'].manager.should_receive(:_run_callbacks).at_least(:once)
|
399
|
+
env['warden'].authenticate(:pass)
|
400
|
+
valid_response
|
401
|
+
end
|
402
|
+
setup_rack(app).call(@env)
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
describe "lock" do
|
407
|
+
it "should not run any strategy" do
|
408
|
+
app = lambda do |env|
|
409
|
+
env['warden'].lock!
|
410
|
+
env['warden'].authenticate(:pass)
|
411
|
+
env['warden'].user.should be_nil
|
412
|
+
valid_response
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
it "should keep already authenticated users" do
|
417
|
+
app = lambda do |env|
|
418
|
+
env['warden'].authenticate(:pass)
|
419
|
+
env['warden'].lock!
|
420
|
+
env['warden'].user.should be
|
421
|
+
valid_response
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
describe "get user" do
|
427
|
+
before(:each) do
|
428
|
+
@env['rack.session'] ||= {}
|
429
|
+
@env['rack.session'].delete("warden.user.default.key")
|
430
|
+
end
|
431
|
+
|
432
|
+
it "should return nil when not logged in" do
|
433
|
+
app = lambda do |env|
|
434
|
+
env['warden'].user.should be_nil
|
435
|
+
valid_response
|
436
|
+
end
|
437
|
+
setup_rack(app).call(@env)
|
438
|
+
end
|
439
|
+
|
440
|
+
it "should not run strategies when not logged in" do
|
441
|
+
app = lambda do |env|
|
442
|
+
env['warden'].user.should be_nil
|
443
|
+
env['warden.spec.strategies'].should be_nil
|
444
|
+
valid_response
|
445
|
+
end
|
446
|
+
setup_rack(app).call(@env)
|
447
|
+
end
|
448
|
+
|
449
|
+
it "should cache unfound user" do
|
450
|
+
Warden::SessionSerializer.any_instance.should_receive(:fetch).once
|
451
|
+
app = lambda do |env|
|
452
|
+
env['warden'].user.should be_nil
|
453
|
+
env['warden'].user.should be_nil
|
454
|
+
valid_response
|
455
|
+
end
|
456
|
+
setup_rack(app).call(@env)
|
457
|
+
end
|
458
|
+
|
459
|
+
describe "previously logged in" do
|
460
|
+
before(:each) do
|
461
|
+
@env['rack.session']['warden.user.default.key'] = "A Previous User"
|
462
|
+
@env['warden.spec.strategies'] = []
|
463
|
+
end
|
464
|
+
|
465
|
+
it "should take the user from the session when logged in" do
|
466
|
+
app = lambda do |env|
|
467
|
+
env['warden'].user.should == "A Previous User"
|
468
|
+
valid_response
|
469
|
+
end
|
470
|
+
setup_rack(app).call(@env)
|
471
|
+
end
|
472
|
+
|
473
|
+
it "should cache found user" do
|
474
|
+
Warden::SessionSerializer.any_instance.should_receive(:fetch).once.and_return "A Previous User"
|
475
|
+
app = lambda do |env|
|
476
|
+
env['warden'].user.should == "A Previous User"
|
477
|
+
env['warden'].user.should == "A Previous User"
|
478
|
+
valid_response
|
479
|
+
end
|
480
|
+
setup_rack(app).call(@env)
|
481
|
+
end
|
482
|
+
|
483
|
+
it "should not run strategies when the user exists in the session" do
|
484
|
+
app = lambda do |env|
|
485
|
+
env['warden'].authenticate!(:pass)
|
486
|
+
valid_response
|
487
|
+
end
|
488
|
+
setup_rack(app).call(@env)
|
489
|
+
@env['warden.spec.strategies'].should_not include(:pass)
|
490
|
+
end
|
491
|
+
|
492
|
+
describe "run callback option" do
|
493
|
+
it "should not call run_callbacks when we pass a :run_callback => false" do
|
494
|
+
app = lambda do |env|
|
495
|
+
env['warden'].manager.should_not_receive(:_run_callbacks)
|
496
|
+
env['warden'].user(:run_callbacks => false)
|
497
|
+
valid_response
|
498
|
+
end
|
499
|
+
setup_rack(app).call(@env)
|
500
|
+
end
|
501
|
+
|
502
|
+
it "should call run_callbacks when we pass a :run_callback => true" do
|
503
|
+
app = lambda do |env|
|
504
|
+
env['warden'].manager.should_receive(:_run_callbacks).at_least(:once)
|
505
|
+
env['warden'].user(:run_callbacks => true)
|
506
|
+
valid_response
|
507
|
+
end
|
508
|
+
setup_rack(app).call(@env)
|
509
|
+
end
|
510
|
+
|
511
|
+
it "should call run_callbacks by default" do
|
512
|
+
app = lambda do |env|
|
513
|
+
env['warden'].manager.should_receive(:_run_callbacks).at_least(:once)
|
514
|
+
env['warden'].user
|
515
|
+
valid_response
|
516
|
+
end
|
517
|
+
setup_rack(app).call(@env)
|
518
|
+
end
|
519
|
+
end
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
describe "logout" do
|
524
|
+
before(:each) do
|
525
|
+
@env['rack.session'] = {"warden.user.default.key" => "default key", "warden.user.foo.key" => "foo key", :foo => "bar"}
|
526
|
+
@app = lambda do |e|
|
527
|
+
e['warden'].logout(e['warden.spec.which_logout'])
|
528
|
+
valid_response
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
it "should logout only the scoped foo user" do
|
533
|
+
@app = setup_rack(@app)
|
534
|
+
@env['warden.spec.which_logout'] = :foo
|
535
|
+
@app.call(@env)
|
536
|
+
@env['rack.session']['warden.user.default.key'].should == "default key"
|
537
|
+
@env['rack.session']['warden.user.foo.key'].should be_nil
|
538
|
+
@env['rack.session'][:foo].should == "bar"
|
539
|
+
end
|
540
|
+
|
541
|
+
it "should logout only the scoped default user" do
|
542
|
+
@app = setup_rack(@app)
|
543
|
+
@env['warden.spec.which_logout'] = :default
|
544
|
+
@app.call(@env)
|
545
|
+
@env['rack.session']['warden.user.default.key'].should be_nil
|
546
|
+
@env['rack.session']['warden.user.foo.key'].should == "foo key"
|
547
|
+
@env['rack.session'][:foo].should == "bar"
|
548
|
+
end
|
549
|
+
|
550
|
+
it "should clear the session when no argument is given to logout" do
|
551
|
+
@env['rack.session'].should_not be_nil
|
552
|
+
app = lambda do |e|
|
553
|
+
e['warden'].logout
|
554
|
+
valid_response
|
555
|
+
end
|
556
|
+
setup_rack(app).call(@env)
|
557
|
+
@env['rack.session'].should be_empty
|
558
|
+
end
|
559
|
+
|
560
|
+
it "should not raise exception if raw_session is nil" do
|
561
|
+
@app = setup_rack(@app, { nil_session: true })
|
562
|
+
@env['rack.session'] = nil
|
563
|
+
@env['warden.spec.which_logout'] = :foo
|
564
|
+
expect { @app.call(@env) }.to_not raise_error(NoMethodError)
|
565
|
+
end
|
566
|
+
|
567
|
+
it "should clear the user when logging out" do
|
568
|
+
@env['rack.session'].should_not be_nil
|
569
|
+
app = lambda do |e|
|
570
|
+
e['warden'].user.should_not be_nil
|
571
|
+
e['warden'].logout
|
572
|
+
e['warden'].should_not be_authenticated
|
573
|
+
e['warden'].user.should be_nil
|
574
|
+
valid_response
|
575
|
+
end
|
576
|
+
setup_rack(app).call(@env)
|
577
|
+
@env['warden'].user.should be_nil
|
578
|
+
end
|
579
|
+
|
580
|
+
it "should clear the session data when logging out" do
|
581
|
+
@env['rack.session'].should_not be_nil
|
582
|
+
app = lambda do |e|
|
583
|
+
e['warden'].user.should_not be_nil
|
584
|
+
e['warden'].session[:foo] = :bar
|
585
|
+
e['warden'].logout
|
586
|
+
valid_response
|
587
|
+
end
|
588
|
+
setup_rack(app).call(@env)
|
589
|
+
end
|
590
|
+
|
591
|
+
it "should clear out the session by calling reset_session! so that plugins can setup their own session clearing" do
|
592
|
+
@env['rack.session'].should_not be_nil
|
593
|
+
app = lambda do |e|
|
594
|
+
e['warden'].user.should_not be_nil
|
595
|
+
e['warden'].should_receive(:reset_session!)
|
596
|
+
e['warden'].logout
|
597
|
+
valid_response
|
598
|
+
end
|
599
|
+
setup_rack(app).call(@env)
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
describe "messages" do
|
604
|
+
it "should allow access to the failure message" do
|
605
|
+
failure = lambda do |e|
|
606
|
+
[401, {"Content-Type" => "text/plain"}, [e['warden'].message]]
|
607
|
+
end
|
608
|
+
app = lambda do |e|
|
609
|
+
e['warden'].authenticate! :failz
|
610
|
+
end
|
611
|
+
result = setup_rack(app, :failure_app => failure).call(@env)
|
612
|
+
result.last.should == ["The Fails Strategy Has Failed You"]
|
613
|
+
end
|
614
|
+
|
615
|
+
it "should allow access to the success message" do
|
616
|
+
success = lambda do |e|
|
617
|
+
[200, {"Content-Type" => "text/plain"}, [e['warden'].message]]
|
618
|
+
end
|
619
|
+
app = lambda do |e|
|
620
|
+
e['warden'].authenticate! :pass_with_message
|
621
|
+
success.call(e)
|
622
|
+
end
|
623
|
+
result = setup_rack(app).call(@env)
|
624
|
+
result.last.should == ["The Success Strategy Has Accepted You"]
|
625
|
+
end
|
626
|
+
|
627
|
+
it "should not die when accessing a message from a source where no authentication has occured" do
|
628
|
+
app = lambda do |e|
|
629
|
+
[200, {"Content-Type" => "text/plain"}, [e['warden'].message]]
|
630
|
+
end
|
631
|
+
result = setup_rack(app).call(@env)
|
632
|
+
result[2].should == [nil]
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
636
|
+
describe "when all strategies are not valid?" do
|
637
|
+
it "should return false for authenticated? when there are no valid? strategies" do
|
638
|
+
@env['rack.session'] = {}
|
639
|
+
app = lambda do |e|
|
640
|
+
e['warden'].authenticate(:invalid).should be_nil
|
641
|
+
e['warden'].should_not be_authenticated
|
642
|
+
end
|
643
|
+
setup_rack(app).call(@env)
|
644
|
+
end
|
645
|
+
|
646
|
+
it "should return nil for authenticate when there are no valid strategies" do
|
647
|
+
@env['rack.session'] = {}
|
648
|
+
app = lambda do |e|
|
649
|
+
e['warden'].authenticate(:invalid).should be_nil
|
650
|
+
end
|
651
|
+
setup_rack(app).call(@env)
|
652
|
+
end
|
653
|
+
|
654
|
+
it "should return false for authenticate? when there are no valid strategies" do
|
655
|
+
@env['rack.session'] = {}
|
656
|
+
app = lambda do |e|
|
657
|
+
e['warden'].authenticate?(:invalid).should be_false
|
658
|
+
end
|
659
|
+
setup_rack(app).call(@env)
|
660
|
+
end
|
661
|
+
|
662
|
+
it "should respond with a 401 when authenticate! cannot find any valid strategies" do
|
663
|
+
@env['rack.session'] = {}
|
664
|
+
app = lambda do |e|
|
665
|
+
e['warden'].authenticate!(:invalid)
|
666
|
+
end
|
667
|
+
result = setup_rack(app).call(@env)
|
668
|
+
result.first.should == 401
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
describe "authenticated?" do
|
673
|
+
describe "positive authentication" do
|
674
|
+
before do
|
675
|
+
@env['rack.session'] = {'warden.user.default.key' => 'defult_key'}
|
676
|
+
$captures = []
|
677
|
+
end
|
678
|
+
|
679
|
+
it "should return true when authenticated in the session" do
|
680
|
+
app = lambda do |e|
|
681
|
+
e['warden'].should be_authenticated
|
682
|
+
end
|
683
|
+
setup_rack(app).call(@env)
|
684
|
+
end
|
685
|
+
|
686
|
+
it "should yield to a block when the block is passed and authenticated" do
|
687
|
+
app = lambda do |e|
|
688
|
+
e['warden'].authenticated? do
|
689
|
+
$captures << :in_the_block
|
690
|
+
end
|
691
|
+
end
|
692
|
+
setup_rack(app).call(@env)
|
693
|
+
$captures.should == [:in_the_block]
|
694
|
+
end
|
695
|
+
|
696
|
+
it "should authenticate for a user in a different scope" do
|
697
|
+
@env['rack.session'] = {'warden.user.foo.key' => 'foo_key'}
|
698
|
+
app = lambda do |e|
|
699
|
+
e['warden'].authenticated?(:foo) do
|
700
|
+
$captures << :in_the_foo_block
|
701
|
+
end
|
702
|
+
end
|
703
|
+
setup_rack(app).call(@env)
|
704
|
+
$captures.should == [:in_the_foo_block]
|
705
|
+
end
|
706
|
+
end
|
707
|
+
|
708
|
+
describe "negative authentication" do
|
709
|
+
before do
|
710
|
+
@env['rack.session'] = {'warden.foo.default.key' => 'foo_key'}
|
711
|
+
$captures = []
|
712
|
+
end
|
713
|
+
|
714
|
+
it "should return false when authenticated in the session" do
|
715
|
+
app = lambda do |e|
|
716
|
+
e['warden'].should_not be_authenticated
|
717
|
+
end
|
718
|
+
setup_rack(app).call(@env)
|
719
|
+
end
|
720
|
+
|
721
|
+
it "should return false if scope cannot be retrieved from session" do
|
722
|
+
begin
|
723
|
+
Warden::Manager.serialize_from_session { |k| nil }
|
724
|
+
app = lambda do |env|
|
725
|
+
env['rack.session']['warden.user.foo_scope.key'] = "a foo user"
|
726
|
+
env['warden'].authenticated?(:foo_scope)
|
727
|
+
valid_response
|
728
|
+
end
|
729
|
+
setup_rack(app).call(@env)
|
730
|
+
@env['warden'].user(:foo_scope).should be_nil
|
731
|
+
ensure
|
732
|
+
Warden::Manager.serialize_from_session { |k| k }
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
it "should not yield to a block when the block is passed and authenticated" do
|
737
|
+
app = lambda do |e|
|
738
|
+
e['warden'].authenticated? do
|
739
|
+
$captures << :in_the_block
|
740
|
+
end
|
741
|
+
end
|
742
|
+
setup_rack(app).call(@env)
|
743
|
+
$captures.should == []
|
744
|
+
end
|
745
|
+
|
746
|
+
it "should not yield for a user in a different scope" do
|
747
|
+
app = lambda do |e|
|
748
|
+
e['warden'].authenticated?(:bar) do
|
749
|
+
$captures << :in_the_bar_block
|
750
|
+
end
|
751
|
+
end
|
752
|
+
setup_rack(app).call(@env)
|
753
|
+
$captures.should == []
|
754
|
+
end
|
755
|
+
end
|
756
|
+
end
|
757
|
+
|
758
|
+
describe "unauthenticated?" do
|
759
|
+
describe "negative unauthentication" do
|
760
|
+
before do
|
761
|
+
@env['rack.session'] = {'warden.user.default.key' => 'defult_key'}
|
762
|
+
$captures = []
|
763
|
+
end
|
764
|
+
|
765
|
+
it "should return false when authenticated in the session" do
|
766
|
+
app = lambda do |e|
|
767
|
+
e['warden'].should_not be_unauthenticated
|
768
|
+
end
|
769
|
+
result = setup_rack(app).call(@env)
|
770
|
+
end
|
771
|
+
|
772
|
+
it "should not yield to a block when the block is passed and authenticated" do
|
773
|
+
app = lambda do |e|
|
774
|
+
e['warden'].unauthenticated? do
|
775
|
+
$captures << :in_the_block
|
776
|
+
end
|
777
|
+
end
|
778
|
+
setup_rack(app).call(@env)
|
779
|
+
$captures.should == []
|
780
|
+
end
|
781
|
+
|
782
|
+
it "should not yield to the block for a user in a different scope" do
|
783
|
+
@env['rack.session'] = {'warden.user.foo.key' => 'foo_key'}
|
784
|
+
app = lambda do |e|
|
785
|
+
e['warden'].unauthenticated?(:foo) do
|
786
|
+
$captures << :in_the_foo_block
|
787
|
+
end
|
788
|
+
end
|
789
|
+
setup_rack(app).call(@env)
|
790
|
+
$captures.should == []
|
791
|
+
end
|
792
|
+
end
|
793
|
+
|
794
|
+
describe "positive unauthentication" do
|
795
|
+
before do
|
796
|
+
@env['rack.session'] = {'warden.foo.default.key' => 'foo_key'}
|
797
|
+
$captures = []
|
798
|
+
end
|
799
|
+
|
800
|
+
it "should return false when unauthenticated in the session" do
|
801
|
+
app = lambda do |e|
|
802
|
+
e['warden'].should be_unauthenticated
|
803
|
+
end
|
804
|
+
setup_rack(app).call(@env)
|
805
|
+
end
|
806
|
+
|
807
|
+
it "should yield to a block when the block is passed and authenticated" do
|
808
|
+
app = lambda do |e|
|
809
|
+
e['warden'].unauthenticated? do
|
810
|
+
$captures << :in_the_block
|
811
|
+
end
|
812
|
+
end
|
813
|
+
setup_rack(app).call(@env)
|
814
|
+
$captures.should == [:in_the_block]
|
815
|
+
end
|
816
|
+
|
817
|
+
it "should yield for a user in a different scope" do
|
818
|
+
app = lambda do |e|
|
819
|
+
e['warden'].unauthenticated?(:bar) do
|
820
|
+
$captures << :in_the_bar_block
|
821
|
+
end
|
822
|
+
end
|
823
|
+
setup_rack(app).call(@env)
|
824
|
+
$captures.should == [:in_the_bar_block]
|
825
|
+
end
|
826
|
+
end
|
827
|
+
end
|
828
|
+
|
829
|
+
describe "attributes" do
|
830
|
+
def def_app(&blk)
|
831
|
+
@app = setup_rack(blk)
|
832
|
+
end
|
833
|
+
|
834
|
+
it "should have a config attribute" do
|
835
|
+
app = def_app do |e|
|
836
|
+
e['warden'].config.should be_a_kind_of(Hash)
|
837
|
+
valid_response
|
838
|
+
end
|
839
|
+
app.call(@env)
|
840
|
+
end
|
841
|
+
end
|
842
|
+
end
|
843
|
+
|
844
|
+
describe "dynamic default_strategies" do
|
845
|
+
before(:all) do
|
846
|
+
load_strategies
|
847
|
+
|
848
|
+
class ::DynamicDefaultStrategies
|
849
|
+
def initialize(app, &blk)
|
850
|
+
@app, @blk = app, blk
|
851
|
+
end
|
852
|
+
|
853
|
+
def call(env)
|
854
|
+
@blk.call(env)
|
855
|
+
@app.call(env)
|
856
|
+
end
|
857
|
+
end
|
858
|
+
|
859
|
+
Warden::Strategies.add(:one) do
|
860
|
+
def authenticate!; $captures << :one; success!("User") end
|
861
|
+
end
|
862
|
+
|
863
|
+
Warden::Strategies.add(:two) do
|
864
|
+
def authenticate!; $captures << :two; fail("User not found") end
|
865
|
+
end
|
866
|
+
end
|
867
|
+
|
868
|
+
before(:each) do
|
869
|
+
@app = lambda{|e| e['warden'].authenticate! }
|
870
|
+
@env = env_with_params("/")
|
871
|
+
$captures = []
|
872
|
+
end
|
873
|
+
|
874
|
+
def wrap_app(app, &blk)
|
875
|
+
builder = Rack::Builder.new do
|
876
|
+
use DynamicDefaultStrategies, &blk
|
877
|
+
run app
|
878
|
+
end
|
879
|
+
builder.to_app
|
880
|
+
end
|
881
|
+
|
882
|
+
it "should allow me to change the default strategies on the fly" do
|
883
|
+
app = wrap_app(@app) do |e|
|
884
|
+
e['warden'].default_strategies.should == [:password]
|
885
|
+
e['warden'].config.default_strategies.should == [:password]
|
886
|
+
e['warden'].default_strategies :one
|
887
|
+
e['warden'].authenticate!
|
888
|
+
Rack::Response.new("OK").finish
|
889
|
+
end
|
890
|
+
setup_rack(app).call(@env)
|
891
|
+
|
892
|
+
$captures.should == [:one]
|
893
|
+
end
|
894
|
+
|
895
|
+
it "should allow me to append to the default strategies on the fly" do
|
896
|
+
app = wrap_app(@app) do |e|
|
897
|
+
e['warden'].default_strategies << :one
|
898
|
+
e['warden'].default_strategies.should == [:password, :one]
|
899
|
+
e['warden'].authenticate!
|
900
|
+
Rack::Response.new("OK").finish
|
901
|
+
end
|
902
|
+
setup_rack(app).call(@env)
|
903
|
+
|
904
|
+
$captures.should == [:one]
|
905
|
+
end
|
906
|
+
|
907
|
+
it "should allow me to set the default strategies on a per scope basis" do
|
908
|
+
app = wrap_app(@app) do |e|
|
909
|
+
w = e['warden']
|
910
|
+
w.default_strategies(:two, :one, :scope => :foo)
|
911
|
+
w.default_strategies(:two, :scope => :default)
|
912
|
+
w.default_strategies(:scope => :foo).should == [:two, :one]
|
913
|
+
w.authenticate(:scope => :foo)
|
914
|
+
$captures.should == [:two, :one]
|
915
|
+
$captures.clear
|
916
|
+
w.authenticate
|
917
|
+
$captures.should == [:two]
|
918
|
+
end
|
919
|
+
setup_rack(app).call(@env)
|
920
|
+
$captures.should == [:two]
|
921
|
+
end
|
922
|
+
|
923
|
+
it "should allow me to setup default strategies for each scope on the manager" do
|
924
|
+
builder = Rack::Builder.new do
|
925
|
+
use Warden::Spec::Helpers::Session
|
926
|
+
use Warden::Manager do |config|
|
927
|
+
config.default_strategies :one
|
928
|
+
config.default_strategies :two, :one, :scope => :foo
|
929
|
+
config.failure_app = Warden::Spec::Helpers::FAILURE_APP
|
930
|
+
end
|
931
|
+
run(lambda do |e|
|
932
|
+
w = e['warden']
|
933
|
+
w.authenticate
|
934
|
+
$captures.should == [:one]
|
935
|
+
$captures.clear
|
936
|
+
w.authenticate(:scope => :foo)
|
937
|
+
$captures.should == [:two, :one]
|
938
|
+
$captures << :complete
|
939
|
+
end)
|
940
|
+
end
|
941
|
+
builder.to_app.call(@env)
|
942
|
+
$captures.should include(:complete)
|
943
|
+
end
|
944
|
+
|
945
|
+
it "should not change the master configurations strategies when I change them" do
|
946
|
+
app = wrap_app(@app) do |e|
|
947
|
+
e['warden'].default_strategies << :one
|
948
|
+
e['warden'].default_strategies.should == [:password, :one]
|
949
|
+
e['warden'].manager.config.default_strategies.should == [:password]
|
950
|
+
e['warden'].authenticate!
|
951
|
+
Rack::Response.new("OK").finish
|
952
|
+
end
|
953
|
+
setup_rack(app).call(@env)
|
954
|
+
|
955
|
+
$captures.should == [:one]
|
956
|
+
end
|
957
|
+
|
958
|
+
describe "default scope options" do
|
959
|
+
|
960
|
+
it "should allow me to set a default action for a given scope" do
|
961
|
+
$captures = []
|
962
|
+
builder = Rack::Builder.new do
|
963
|
+
use Warden::Manager do |config|
|
964
|
+
config.scope_defaults :foo, :strategies => [:two], :action => "some_bad_action"
|
965
|
+
config.failure_app = Warden::Spec::Helpers::FAILURE_APP
|
966
|
+
end
|
967
|
+
|
968
|
+
run(lambda do |e|
|
969
|
+
e['warden'].authenticate!(:scope => :foo)
|
970
|
+
end)
|
971
|
+
end
|
972
|
+
|
973
|
+
env = env_with_params("/foo")
|
974
|
+
env["rack.session"] = {}
|
975
|
+
builder.to_app.call(env)
|
976
|
+
request = Rack::Request.new(env)
|
977
|
+
request.path.should == "/some_bad_action"
|
978
|
+
end
|
979
|
+
|
980
|
+
it "should allow me to set store, false on a given scope" do
|
981
|
+
$captures = []
|
982
|
+
builder = Rack::Builder.new do
|
983
|
+
use Warden::Manager do |config|
|
984
|
+
config.default_strategies :one
|
985
|
+
config.default_strategies :two, :one, :scope => :foo
|
986
|
+
config.default_strategies :two, :one, :scope => :bar
|
987
|
+
|
988
|
+
config.scope_defaults :bar, :store => false
|
989
|
+
config.scope_defaults :baz, :store => false
|
990
|
+
config.failure_app = Warden::Spec::Helpers::FAILURE_APP
|
991
|
+
end
|
992
|
+
run(lambda do |e|
|
993
|
+
w = e['warden']
|
994
|
+
w.authenticate
|
995
|
+
w.authenticate(:scope => :foo)
|
996
|
+
w.authenticate(:one, :scope => :bar)
|
997
|
+
w.authenticate(:one, :scope => :baz, :store => true)
|
998
|
+
w.user.should == "User"
|
999
|
+
w.user(:foo).should == "User"
|
1000
|
+
w.user(:bar).should == "User"
|
1001
|
+
w.user(:baz).should == "User"
|
1002
|
+
$captures << :complete
|
1003
|
+
Rack::Response.new("OK").finish
|
1004
|
+
end)
|
1005
|
+
end
|
1006
|
+
session = @env["rack.session"] = {}
|
1007
|
+
builder.to_app.call(@env)
|
1008
|
+
$captures.should include(:complete)
|
1009
|
+
session['warden.user.default.key'].should == "User"
|
1010
|
+
session['warden.user.foo.key'].should == "User"
|
1011
|
+
session.key?('warden.user.bar.key').should be_false
|
1012
|
+
session['warden.user.bar.key'].should be_nil
|
1013
|
+
session['warden.user.baz.key'].should == "User"
|
1014
|
+
end
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
describe "#asset_request?" do
|
1018
|
+
before(:each) do
|
1019
|
+
@asset_regex = /^\/assets\//
|
1020
|
+
::Warden.asset_paths = @asset_regex
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
it "should return true if PATH_INFO is in asset list" do
|
1024
|
+
env = env_with_params('/assets/fun.gif')
|
1025
|
+
setup_rack(success_app).call(env)
|
1026
|
+
proxy = env["warden"]
|
1027
|
+
|
1028
|
+
proxy.env['PATH_INFO'].should match(@asset_regex)
|
1029
|
+
proxy.should be_asset_request
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
it "should return false if PATH_INFO is not in asset list" do
|
1033
|
+
env = env_with_params('/home')
|
1034
|
+
setup_rack(success_app).call(env)
|
1035
|
+
proxy = env["warden"]
|
1036
|
+
|
1037
|
+
proxy.env['PATH_INFO'].should_not match(@asset_regex)
|
1038
|
+
proxy.should_not be_asset_request
|
1039
|
+
end
|
1040
|
+
end
|
1041
|
+
end
|