merb-auth-core 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,318 @@
1
+ require File.join(File.dirname(__FILE__), "..", 'spec_helper.rb')
2
+
3
+ describe "Merb::Authentication Session" do
4
+
5
+ before(:each) do
6
+ @session_class = Merb::CookieSession
7
+ @session = @session_class.generate
8
+ end
9
+
10
+ describe "module methods" do
11
+ before(:each) do
12
+ @m = mock("mock")
13
+ clear_strategies!
14
+ end
15
+
16
+ after(:all) do
17
+ clear_strategies!
18
+ end
19
+
20
+ describe "store_user" do
21
+ it{@session.authentication.should respond_to(:store_user)}
22
+
23
+ it "should raise a NotImplemented error by default" do
24
+ pending "How to spec this when we need to overwrite it for the specs to work?"
25
+ lambda do
26
+ @session.authentication.store_user("THE USER")
27
+ end.should raise_error(Merb::Authentication::NotImplemented)
28
+ end
29
+ end
30
+
31
+ describe "fetch_user" do
32
+ it{@session.authentication.should respond_to(:fetch_user)}
33
+
34
+ it "should raise a NotImplemented error by defualt" do
35
+ pending "How to spec this when we need to overwrite it for the specs to work?"
36
+ lambda do
37
+ @session.authentication.fetch_user
38
+ end.should raise_error(Merb::Authentication::NotImplemented)
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "error_message" do
44
+
45
+ before(:each) do
46
+ @request = fake_request
47
+ @auth = Merb::Authentication.new(@request.session)
48
+ end
49
+
50
+ it "should be 'Could not log in' by default" do
51
+ @auth.error_message.should == "Could not log in"
52
+ end
53
+
54
+ it "should allow a user to set the error message" do
55
+ @auth.error_message = "No You Don't"
56
+ @auth.error_message.should == "No You Don't"
57
+ end
58
+ end
59
+
60
+ describe "user" do
61
+ it "should call fetch_user with the session contents to load the user" do
62
+ @session[:user] = 42
63
+ @session.authentication.should_receive(:fetch_user).with(42)
64
+ @session.user
65
+ end
66
+
67
+ it "should set the @user instance variable" do
68
+ @session[:user] = 42
69
+ @session.authentication.should_receive(:fetch_user).and_return("THE USER")
70
+ @session.user
71
+ @session.authentication.assigns(:user).should == "THE USER"
72
+ end
73
+
74
+ it "should cache the user in an instance variable" do
75
+ @session[:user] = 42
76
+ @session.authentication.should_receive(:fetch_user).once.and_return("THE USER")
77
+ @session.user
78
+ @session.authentication.assigns(:user).should == "THE USER"
79
+ @session.user
80
+ end
81
+
82
+ it "should set the ivar to nil if the session is nil" do
83
+ @session[:user] = nil
84
+ @session.user.should be_nil
85
+ end
86
+
87
+ end
88
+
89
+ describe "user=" do
90
+ before(:each) do
91
+ @user = mock("user")
92
+ @session.authentication.stub!(:fetch_user).and_return(@user)
93
+ end
94
+
95
+ it "should call store_user on the session to get the value to store in the session" do
96
+ @session.authentication.should_receive(:store_user).with(@user)
97
+ @session.user = @user
98
+ end
99
+
100
+ it "should set the instance variable to nil if the return of store_user is nil" do
101
+ @session.authentication.should_receive(:store_user).and_return(nil)
102
+ @session.user = @user
103
+ @session.user.should be_nil
104
+ end
105
+
106
+ it "should set the instance varaible to nil if the return of store_user is false" do
107
+ @session.authentication.should_receive(:store_user).and_return(false)
108
+ @session.user = @user
109
+ @session.user.should be_nil
110
+ end
111
+
112
+ it "should set the instance variable to the value of user if store_user is not nil or false" do
113
+ @session.authentication.should_receive(:store_user).and_return(42)
114
+ @session.user = @user
115
+ @session.user.should == @user
116
+ @session[:user].should == 42
117
+ end
118
+ end
119
+
120
+ describe "abandon!" do
121
+
122
+ before(:each) do
123
+ @user = mock("user")
124
+ @session.authentication.stub!(:fetch_user).and_return(@user)
125
+ @session.authentication.stub!(:store_user).and_return(42)
126
+ @session[:user] = 42
127
+ @session.user
128
+ end
129
+
130
+ it "should delete the session" do
131
+ @session.should_receive(:clear)
132
+ @session.abandon!
133
+ end
134
+
135
+ it "should not have a user after it is abandoned" do
136
+ @session.user.should == @user
137
+ @session.abandon!
138
+ @session.user.should be_nil
139
+ end
140
+ end
141
+
142
+ describe "Merb::Authentication" do
143
+ it "Should be hookable" do
144
+ Merb::Authentication.should include(Extlib::Hook)
145
+ end
146
+
147
+ end
148
+
149
+ describe "#authenticate" do
150
+
151
+ before(:all) do
152
+ clear_strategies!
153
+ end
154
+
155
+ after(:all) do
156
+ clear_strategies!
157
+ end
158
+
159
+ before(:each) do
160
+ class Sone < Merb::Authentication::Strategy
161
+ def run!
162
+ Viking.capture(Sone)
163
+ params[:pass_1]
164
+ end
165
+ end
166
+ class Stwo < Merb::Authentication::Strategy
167
+ def run!
168
+ Viking.capture(Stwo)
169
+ params[:pass_2]
170
+ end
171
+ end
172
+ class Sthree < Merb::Authentication::Strategy
173
+ def run!
174
+ Viking.capture(Sthree)
175
+ params[:pass_3]
176
+ end
177
+ end
178
+ class Sfour < Merb::Authentication::Strategy
179
+ abstract!
180
+
181
+ def run!
182
+ "BAD MAN"
183
+ end
184
+ end
185
+
186
+ Sfour.should_not_receive(:run!)
187
+ @request = Users.new(fake_request)
188
+ @auth = Merb::Authentication.new(@request.session)
189
+ Viking.captures.clear
190
+ end
191
+
192
+ it "should execute the strategies in the default order" do
193
+ @request.params[:pass_3] = true
194
+ @auth.authenticate!(@request, @request.params)
195
+ Viking.captures.should == %w( Sone Stwo Sthree )
196
+ end
197
+
198
+ it "should run the strategeis until if finds a non nil non false" do
199
+ @request.params[:pass_2] = true
200
+ @auth.authenticate!(@request, @request.params)
201
+ Viking.captures.should == %w( Sone Stwo )
202
+ end
203
+
204
+ it "should raise an Unauthenticated exception if no 'user' is found" do
205
+ lambda do
206
+ @auth.authenticate!(@request, @request.params)
207
+ end.should raise_error(Merb::Controller::Unauthenticated)
208
+ end
209
+
210
+ it "should store the user into the session if one is found" do
211
+ @auth.should_receive(:user=).with("WINNA")
212
+ @request.params[:pass_1] = "WINNA"
213
+ @auth.authenticate!(@request, @request.params)
214
+ end
215
+
216
+ it "should use the Authentiation#error_message as the error message" do
217
+ @auth.should_receive(:error_message).and_return("BAD BAD BAD")
218
+ lambda do
219
+ @auth.authenticate!(@request, @request.params)
220
+ end.should raise_error(Merb::Controller::Unauthenticated, "BAD BAD BAD")
221
+ end
222
+
223
+ it "should execute the strategies as passed into the authenticate! method" do
224
+ @request.params[:pass_1] = true
225
+ @auth.authenticate!(@request, @request.params, Stwo, Sone)
226
+ Viking.captures.should == ["Stwo", "Sone"]
227
+ end
228
+
229
+ end
230
+
231
+ describe "user_class" do
232
+ it "should have User as the default user class if requested" do
233
+ Merb::Authentication.user_class.should == User
234
+ end
235
+ end
236
+
237
+ describe "redirection" do
238
+
239
+ before(:all) do
240
+ class FooController < Merb::Controller
241
+ before :ensure_authenticated
242
+ def index; "FooController#index" end
243
+ end
244
+ end
245
+
246
+ before(:each) do
247
+ class MyStrategy < Merb::Authentication::Strategy
248
+ def run!
249
+ if params[:url]
250
+ self.body = "this is the body"
251
+ params[:status] ? redirect!(params[:url], :status => params[:status]) : redirect!(params[:url])
252
+ else
253
+ "WINNA"
254
+ end
255
+ end
256
+ end # MyStrategy
257
+
258
+ class FailStrategy < Merb::Authentication::Strategy
259
+ def run!
260
+ request.params[:should_not_be_here] = true
261
+ end
262
+ end
263
+
264
+ Merb::Router.reset!
265
+ Merb::Router.prepare{ match("/").to(:controller => "foo_controller")}
266
+ @request = mock_request("/")
267
+ @s = MyStrategy.new(@request, @request.params)
268
+ @a = Merb::Authentication.new(@request.session)
269
+ end
270
+
271
+ it "should answer redirected false if the strategy did not redirect" do
272
+ @a.authenticate! @request, @request.params
273
+ @a.should_not be_redirected
274
+ end
275
+
276
+ it "should answer redirected true if the strategy did redirect" do
277
+ @request.params[:url] = "/some/url"
278
+ @a.authenticate! @request, @request.params
279
+ @a.halted?
280
+ end
281
+
282
+ it "should provide access to the Headers" do
283
+ @request.params[:url] = "/some/url"
284
+ @a.authenticate! @request, @request.params
285
+ @a.headers.should == {"Location" => "/some/url"}
286
+ end
287
+
288
+ it "should provide access to the status" do
289
+ @request.params[:url] = "/some/url"
290
+ @request.params[:status] = 401
291
+ @a.authenticate! @request, @request.params
292
+ @a.should be_halted
293
+ @a.status.should == 401
294
+ end
295
+
296
+ it "should stop processing the strategies if one redirects" do
297
+ @request.params[:url] = "/some/url"
298
+ lambda do
299
+ @a.authenticate! @request, @request.params, MyStrategy, FailStrategy
300
+ end.should_not raise_error(Merb::Controller::NotFound)
301
+ @a.should be_halted
302
+ @request.params[:should_not_be_here].should be_nil
303
+ end
304
+
305
+ it "should allow you to set the body" do
306
+ @a.body = "body"
307
+ @a.body.should == "body"
308
+ end
309
+
310
+ it "should put the body of the strategy as the response body of the controller" do
311
+ controller = request "/", :params => {:url => "/some/url"}
312
+ controller.should redirect_to("/some/url")
313
+ end
314
+ end
315
+
316
+
317
+
318
+ end
@@ -0,0 +1,22 @@
1
+ require File.join(File.dirname(__FILE__), "..", 'spec_helper.rb')
2
+
3
+ describe "Merb::Authentication.customizations" do
4
+
5
+ before(:each) do
6
+ Merb::Authentication.default_customizations.clear
7
+ end
8
+
9
+ it "should allow addition to the customizations" do
10
+ Merb::Authentication.customize_default { "ONE" }
11
+ Merb::Authentication.default_customizations.first.call.should == "ONE"
12
+ end
13
+
14
+ it "should allow multiple additions to the customizations" do
15
+ Merb::Authentication.customize_default {"ONE"}
16
+ Merb::Authentication.customize_default {"TWO"}
17
+
18
+ Merb::Authentication.default_customizations.first.call.should == "ONE"
19
+ Merb::Authentication.default_customizations.last.call.should == "TWO"
20
+ end
21
+
22
+ end
@@ -0,0 +1,51 @@
1
+ require File.join(File.dirname(__FILE__), "..", 'spec_helper.rb')
2
+
3
+ describe Merb::Authentication::Errors do
4
+
5
+ before(:each) do
6
+ @errors = Merb::Authentication::Errors.new
7
+ end
8
+
9
+ it "should report that it is empty on first creation" do
10
+ @errors.empty?.should == true
11
+ end
12
+
13
+ it "should continue to report that it is empty even after being checked" do
14
+ @errors.on(:foo)
15
+ @errors.empty?.should == true
16
+ end
17
+
18
+ it "should add an error" do
19
+ @errors.add(:login, "Login or password incorrect")
20
+ @errors[:login].should == ["Login or password incorrect"]
21
+ end
22
+
23
+ it "should allow many errors to be added to the same field" do
24
+ @errors.add(:login, "bad 1")
25
+ @errors.add(:login, "bad 2")
26
+ @errors.on(:login).should == ["bad 1", "bad 2"]
27
+ end
28
+
29
+ it "should give the full messages for an error" do
30
+ @errors.add(:login, "login wrong")
31
+ @errors.add(:password, "password wrong")
32
+ ["password wrong", "login wrong"].each do |msg|
33
+ @errors.full_messages.should include(msg)
34
+ end
35
+ end
36
+
37
+ it "should return the error for a specific field / label" do
38
+ @errors.add(:login, "wrong")
39
+ @errors.on(:login).should == ["wrong"]
40
+ end
41
+
42
+ it "should return nil for a specific field if it's not been set" do
43
+ @errors.on(:not_there).should be_nil
44
+ end
45
+
46
+ it "should provide an errors instance method on the Authenticaiton instance" do
47
+ a = Merb::Authentication.new(Merb::CookieSession.generate)
48
+ a.errors.should be_a_kind_of(Merb::Authentication::Errors)
49
+ end
50
+
51
+ end
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "merb-auth-core" do
4
+ it "should ensure_authentication" do
5
+ dispatch_to(Users, :index) do |controller|
6
+ controller.should_receive(:ensure_authenticated)
7
+ end
8
+ end
9
+
10
+ it "should not ensure_authenticated when skipped" do
11
+ dispatch_to(Dingbats, :index) do |controller|
12
+ controller.should_not_receive(:ensure_authenticated)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,114 @@
1
+ require File.join(File.dirname(__FILE__), "..", 'spec_helper.rb')
2
+ require 'ruby-debug'
3
+
4
+ describe "router protection" do
5
+
6
+ before(:each) do
7
+ class Foo < Merb::Controller
8
+ def index; "INDEX"; end
9
+ end
10
+
11
+ clear_strategies!
12
+
13
+ Object.class_eval do
14
+ remove_const("Mone") if defined?(Mone)
15
+ remove_const("Mtwo") if defined?(Mtwo)
16
+ remove_const("Mthree") if defined?(Mthree)
17
+ end
18
+
19
+ Viking.captures.clear
20
+
21
+ class Mone < Merb::Authentication::Strategy
22
+ def run!
23
+ Viking.capture self.class
24
+ if request.params[self.class.name]
25
+ request.params[self.class.name]
26
+ elsif request.params[:url]
27
+ redirect!(request.params[:url])
28
+ end
29
+ end
30
+ end
31
+
32
+ class Mthree < Mone; end
33
+ class Mtwo < Mone; end
34
+
35
+
36
+
37
+ Merb::Router.prepare do
38
+ to(:controller => "foo") do
39
+ authenticate do
40
+ match("/single_level_default").register
41
+
42
+ authenticate(Mtwo) do
43
+ match("/nested_specific").register
44
+ end
45
+ end
46
+
47
+ authenticate(Mtwo, Mone) do
48
+ match("/single_level_specific").register
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "single level default" do
55
+
56
+ it "should allow access to the controller if the strategy passes" do
57
+ result = request("/single_level_default", :params => {"Mtwo" => true})
58
+ result.body.should == "INDEX"
59
+ Viking.captures.should == %w(Mone Mthree Mtwo)
60
+ end
61
+
62
+ it "should fail if no strategies match" do
63
+ result = request("/single_level_default")
64
+ result.status.should == Merb::Controller::Unauthenticated.status
65
+ end
66
+
67
+ it "should set return a rack array if the strategy redirects" do
68
+ result = request("/single_level_default", :params => {"url" => "/some/url"})
69
+ result.status.should == 302
70
+ result.body.should_not =="INDEX"
71
+ end
72
+ end
73
+
74
+ describe "nested_specific" do
75
+
76
+ it "should allow access to the controller if the strategy passes" do
77
+ result = request("/nested_specific", :params => {"Mtwo" => true})
78
+ result.body.should == "INDEX"
79
+ Viking.captures.should == %w(Mone Mthree Mtwo)
80
+ end
81
+
82
+ it "should fail if no strategies match" do
83
+ result = request("/nested_specific")
84
+ result.status.should == Merb::Controller::Unauthenticated.status
85
+ end
86
+
87
+ it "should set return a rack array if the strategy redirects" do
88
+ result = request("/nested_specific", :params => {"url" => "/some/url"})
89
+ result.status.should == 302
90
+ result.body.should_not =="INDEX"
91
+ end
92
+ end
93
+
94
+ describe "single_level_specific" do
95
+
96
+ it "should allow access to the controller if the strategy passes" do
97
+ result = request("/single_level_specific", :params => {"Mone" => true})
98
+ result.body.should == "INDEX"
99
+ Viking.captures.should == %w(Mtwo Mone)
100
+ end
101
+
102
+ it "should fail if no strategies match" do
103
+ result = request("/single_level_specific")
104
+ result.status.should == Merb::Controller::Unauthenticated.status
105
+ end
106
+
107
+ it "should set return a rack array if the strategy redirects" do
108
+ result = request("/single_level_specific", :params => {"url" => "/some/url"})
109
+ result.status.should == 302
110
+ result.body.should_not =="INDEX"
111
+ end
112
+ end
113
+
114
+ end