merb-auth-core 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,13 +2,13 @@ module Merb
2
2
  class Authentication
3
3
  cattr_reader :strategies, :default_strategy_order, :registered_strategies
4
4
  @@strategies, @@default_strategy_order, @@registered_strategies = [], [], {}
5
-
6
- # Use this to set the default order of strategies
5
+
6
+ # Use this to set the default order of strategies
7
7
  # if you need to in your application. You don't need to use all avaiable strategies
8
8
  # in this array, but you may not include a strategy that has not yet been defined.
9
- #
9
+ #
10
10
  # @params [Merb::Authentiation::Strategy,Merb::Authentication::Strategy]
11
- #
11
+ #
12
12
  # @public
13
13
  def self.default_strategy_order=(*order)
14
14
  order = order.flatten
@@ -16,18 +16,18 @@ module Merb
16
16
  raise ArgumentError, "#{bad.join(",")} do not inherit from Merb::Authentication::Strategy" unless bad.empty?
17
17
  @@default_strategy_order = order
18
18
  end
19
-
19
+
20
20
  # Allows for the registration of strategies.
21
21
  # @params <Symbol, String>
22
22
  # +label+ The label is the label to identify this strategy
23
23
  # +path+ The path to the file containing the strategy. This must be an absolute path!
24
- #
24
+ #
25
25
  # Registering a strategy does not add it to the list of strategies to use
26
26
  # it simply makes it available through the Merb::Authentication.activate method
27
- #
27
+ #
28
28
  # This is for plugin writers to make a strategy availalbe but this should not
29
29
  # stop you from declaring your own strategies
30
- #
30
+ #
31
31
  # @plugin
32
32
  def self.register(label, path)
33
33
  self.registered_strategies[label] = path
@@ -42,7 +42,7 @@ module Merb
42
42
  raise "The #{label} Strategy is not registered" unless path
43
43
  require path
44
44
  end
45
-
45
+
46
46
  # The Merb::Authentication::Strategy is where all the action happens in the merb-auth framework.
47
47
  # Inherit from this class to setup your own strategy. The strategy will automatically
48
48
  # be placed in the default_strategy_order array, and will be included in the strategy runs.
@@ -64,13 +64,13 @@ module Merb
64
64
  class Strategy
65
65
  attr_accessor :request
66
66
  attr_writer :body
67
-
67
+
68
68
  class << self
69
69
  def inherited(klass)
70
70
  Merb::Authentication.strategies << klass
71
71
  Merb::Authentication.default_strategy_order << klass
72
72
  end
73
-
73
+
74
74
  # Use this to declare the strategy should run before another strategy
75
75
  def before(strategy)
76
76
  order = Merb::Authentication.default_strategy_order
@@ -78,7 +78,7 @@ module Merb
78
78
  index = order.index(strategy)
79
79
  order.insert(index,self)
80
80
  end
81
-
81
+
82
82
  # Use this to declare the strategy should run after another strategy
83
83
  def after(strategy)
84
84
  order = Merb::Authentication.default_strategy_order
@@ -86,50 +86,50 @@ module Merb
86
86
  index = order.index(strategy)
87
87
  index == order.size ? order << self : order.insert(index + 1, self)
88
88
  end
89
-
89
+
90
90
  # Mark a strategy as abstract. This means that a strategy will not
91
- # ever be run as part of the authentication. Instead this
91
+ # ever be run as part of the authentication. Instead this
92
92
  # will be available to inherit from as a way to share code.
93
- #
93
+ #
94
94
  # You could for example setup a strategy to check for a particular kind of login
95
95
  # and then have a subclass for each class type of user in your system.
96
96
  # i.e. Customer / Staff, Student / Staff etc
97
97
  def abstract!
98
98
  @abstract = true
99
99
  end
100
-
100
+
101
101
  # Asks is this strategy abstract. i.e. can it be run as part of the authentication
102
102
  def abstract?
103
103
  !!@abstract
104
104
  end
105
-
105
+
106
106
  end # End class << self
107
-
107
+
108
108
  def initialize(request, params)
109
109
  @request = request
110
110
  @params = params
111
111
  end
112
-
112
+
113
113
  # An alias to the request.params hash
114
114
  # Only rely on this hash to find any router params you are looking for.
115
115
  # If looking for paramteres use request.params
116
116
  def params
117
117
  @params
118
118
  end
119
-
119
+
120
120
  # An alials to the request.cookies hash
121
121
  def cookies
122
122
  request.cookies
123
123
  end
124
-
124
+
125
125
  # An alias to the request.session hash
126
126
  def session
127
127
  request.session
128
128
  end
129
-
129
+
130
130
  # Redirects causes the strategy to signal a redirect
131
131
  # to the provided url.
132
- #
132
+ #
133
133
  # ====Parameters
134
134
  # url<String>:: The url to redirect to
135
135
  # options<Hash>:: An options hash with the following keys:
@@ -143,64 +143,64 @@ module Merb
143
143
  halt!
144
144
  return true
145
145
  end
146
-
146
+
147
147
  # Returns ture if the strategy redirected
148
148
  def redirected?
149
149
  !!headers["Location"]
150
150
  end
151
-
151
+
152
152
  # Provides a place to put the status of the response
153
153
  attr_accessor :status
154
-
154
+
155
155
  # Provides a place to put headers
156
156
  def headers
157
157
  @headers ||={}
158
158
  end
159
-
159
+
160
160
  # Mark this strategy as complete for this request. Will cause that no other
161
- # strategies will be executed.
161
+ # strategies will be executed.
162
162
  def halt!
163
163
  @halt = true
164
164
  end
165
-
165
+
166
166
  # Checks to see if this strategy has been halted
167
167
  def halted?
168
168
  !!@halt
169
169
  end
170
-
171
-
170
+
171
+
172
172
  # Allows you to provide a body of content to return when halting
173
173
  def body
174
174
  @body || ""
175
175
  end
176
-
176
+
177
177
  # This is the method that is called as the test for authentication and is where
178
178
  # you put your code.
179
- #
179
+ #
180
180
  # You must overwrite this method in your strategy
181
181
  #
182
182
  # @api overwritable
183
183
  def run!
184
184
  raise NotImplemented
185
185
  end
186
-
186
+
187
187
  # Overwrite this method to scope a strategy to a particular user type
188
188
  # you can use this with inheritance for example to try the same strategy
189
189
  # on different user types
190
190
  #
191
- # By default, Merb::Authentication.user_class is used. This method allows for
191
+ # By default, Merb::Authentication.user_class is used. This method allows for
192
192
  # particular strategies to deal with a different type of user class.
193
193
  #
194
194
  # For example. If Merb::Authentication.user_class is Customer
195
195
  # and you have a PasswordStrategy, you can subclass the PasswordStrategy
196
196
  # and change this method to return Staff. Giving you a PasswordStrategy strategy
197
- # for first Customer(s) and then Staff.
197
+ # for first Customer(s) and then Staff.
198
198
  #
199
199
  # @api overwritable
200
200
  def user_class
201
201
  Merb::Authentication.user_class
202
202
  end
203
-
203
+
204
204
  end # Strategy
205
205
  end # Merb::Authentication
206
206
  end # Merb
@@ -1,7 +1,7 @@
1
1
  module Merb
2
2
  module Auth
3
3
  module Core
4
- VERSION = '1.1.0'.freeze
4
+ VERSION = '1.1.1'.freeze
5
5
  end
6
6
  end
7
7
  end
@@ -1,11 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Merb::AuthenticationHelper" do
4
-
4
+
5
5
  class ControllerMock < Merb::Controller
6
6
  before :ensure_authenticated
7
7
  end
8
-
8
+
9
9
  before(:each) do
10
10
  clear_strategies!
11
11
  @controller = ControllerMock.new(fake_request)
@@ -13,31 +13,31 @@ describe "Merb::AuthenticationHelper" do
13
13
  @session = @controller.session
14
14
  @session.user = "WINNA"
15
15
  Viking.captures.clear
16
-
16
+
17
17
  class Kone < Merb::Authentication::Strategy
18
18
  def run!
19
19
  Viking.capture(self.class)
20
20
  params[self.class.name]
21
21
  end
22
22
  end
23
-
23
+
24
24
  class Ktwo < Kone; end
25
-
25
+
26
26
  end
27
-
27
+
28
28
  it "should not raise and Unauthenticated error" do
29
29
  lambda do
30
30
  @controller.send(:ensure_authenticated)
31
31
  end.should_not raise_error(Merb::Controller::Unauthenticated)
32
32
  end
33
-
33
+
34
34
  it "should raise an Unauthenticated error" do
35
35
  @controller = ControllerMock.new(Merb::Request.new({}))
36
36
  lambda do
37
37
  @controller.send(:ensure_authenticated)
38
38
  end.should raise_error(Merb::Controller::Unauthenticated)
39
39
  end
40
-
40
+
41
41
  it "should run the authentication when testing if it is authenticated" do
42
42
  @controller = ControllerMock.new(fake_request)
43
43
  @controller.session.should_receive(:authenticated?).and_return(false)
@@ -45,7 +45,7 @@ describe "Merb::AuthenticationHelper" do
45
45
  @controller.session.authentication.should_receive(:authenticate!).and_return("WINNA")
46
46
  @controller.send(:ensure_authenticated)
47
47
  end
48
-
48
+
49
49
  it "should accept and execute the provided strategies" do
50
50
  # This allows using a before filter with specific arguments
51
51
  # before :ensure_authenticated, :with => [Authenticaiton::OAuth, Merb::Authentication::BasicAuth]
@@ -54,17 +54,17 @@ describe "Merb::AuthenticationHelper" do
54
54
  controller.send(:ensure_authenticated, Kone, Ktwo)
55
55
  Viking.captures.should == %w( Kone Ktwo )
56
56
  end
57
-
57
+
58
58
  describe "redirection" do
59
-
59
+
60
60
  before(:all) do
61
61
  class FooController < Merb::Controller
62
62
  before :ensure_authenticated
63
-
63
+
64
64
  def index; "FooController#index" end
65
65
  end
66
66
  end
67
-
67
+
68
68
  before(:each) do
69
69
  class MyStrategy < Merb::Authentication::Strategy
70
70
  def run!
@@ -80,32 +80,32 @@ describe "Merb::AuthenticationHelper" do
80
80
  end
81
81
  end
82
82
  end # MyStrategy
83
-
83
+
84
84
  Merb::Router.reset!
85
85
  Merb::Router.prepare{ match("/").to(:controller => "foo_controller")}
86
86
  end
87
-
87
+
88
88
  it "should redirect the controller to a Location if the strategy redirects" do
89
- controller = get "/", :url => "/some/url"
89
+ controller = get "/", :url => "/some/url"
90
90
  controller.headers["Location"].should == "/some/url"
91
91
  end
92
-
92
+
93
93
  it "should use a 302 redirection by default" do
94
94
  c = get "/", :url => "/some/url"
95
95
  c.status.should == 302
96
96
  end
97
-
97
+
98
98
  it "should use a 301 when marked as permanent" do
99
99
  c = get "/", :url => "/some/url", :permanent => "true"
100
100
  c.status.should == 301
101
101
  end
102
-
102
+
103
103
  it "should use a custom status" do
104
104
  c = get "/", :url => "/some/url", :status => 401
105
105
  c.status.should == 401
106
106
  end
107
-
108
-
107
+
108
+
109
109
  end
110
-
110
+
111
111
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Merb::Authentication Session" do
4
-
4
+
5
5
  before(:each) do
6
6
  @session_class = Merb::CookieSession
7
7
  @session = @session_class.generate
@@ -12,14 +12,14 @@ describe "Merb::Authentication Session" do
12
12
  @m = mock("mock")
13
13
  clear_strategies!
14
14
  end
15
-
15
+
16
16
  after(:all) do
17
17
  clear_strategies!
18
18
  end
19
-
19
+
20
20
  describe "store_user" do
21
21
  it{@session.authentication.should respond_to(:store_user)}
22
-
22
+
23
23
  it "should raise a NotImplemented error by default" do
24
24
  pending "How to spec this when we need to overwrite it for the specs to work?"
25
25
  lambda do
@@ -27,50 +27,50 @@ describe "Merb::Authentication Session" do
27
27
  end.should raise_error(Merb::Authentication::NotImplemented)
28
28
  end
29
29
  end
30
-
30
+
31
31
  describe "fetch_user" do
32
32
  it{@session.authentication.should respond_to(:fetch_user)}
33
-
33
+
34
34
  it "should raise a NotImplemented error by defualt" do
35
35
  pending "How to spec this when we need to overwrite it for the specs to work?"
36
- lambda do
36
+ lambda do
37
37
  @session.authentication.fetch_user
38
38
  end.should raise_error(Merb::Authentication::NotImplemented)
39
39
  end
40
40
  end
41
41
  end
42
-
42
+
43
43
  describe "error_message" do
44
-
44
+
45
45
  before(:each) do
46
46
  @request = fake_request
47
47
  @auth = Merb::Authentication.new(@request.session)
48
48
  end
49
-
49
+
50
50
  it "should be 'Could not log in' by default" do
51
51
  @auth.error_message.should == "Could not log in"
52
52
  end
53
-
53
+
54
54
  it "should allow a user to set the error message" do
55
55
  @auth.error_message = "No You Don't"
56
56
  @auth.error_message.should == "No You Don't"
57
57
  end
58
58
  end
59
-
59
+
60
60
  describe "user" do
61
61
  it "should call fetch_user with the session contents to load the user" do
62
62
  @session[:user] = 42
63
63
  @session.authentication.should_receive(:fetch_user).with(42)
64
64
  @session.user
65
65
  end
66
-
66
+
67
67
  it "should set the @user instance variable" do
68
68
  @session[:user] = 42
69
69
  @session.authentication.should_receive(:fetch_user).and_return("THE USER")
70
70
  @session.user
71
71
  @session.authentication.assigns(:user).should == "THE USER"
72
72
  end
73
-
73
+
74
74
  it "should cache the user in an instance variable" do
75
75
  @session[:user] = 42
76
76
  @session.authentication.should_receive(:fetch_user).once.and_return("THE USER")
@@ -78,37 +78,37 @@ describe "Merb::Authentication Session" do
78
78
  @session.authentication.assigns(:user).should == "THE USER"
79
79
  @session.user
80
80
  end
81
-
81
+
82
82
  it "should set the ivar to nil if the session is nil" do
83
83
  @session[:user] = nil
84
84
  @session.user.should be_nil
85
85
  end
86
-
86
+
87
87
  end
88
-
88
+
89
89
  describe "user=" do
90
90
  before(:each) do
91
91
  @user = mock("user")
92
92
  @session.authentication.stub!(:fetch_user).and_return(@user)
93
93
  end
94
-
94
+
95
95
  it "should call store_user on the session to get the value to store in the session" do
96
96
  @session.authentication.should_receive(:store_user).with(@user)
97
97
  @session.user = @user
98
98
  end
99
-
99
+
100
100
  it "should set the instance variable to nil if the return of store_user is nil" do
101
101
  @session.authentication.should_receive(:store_user).and_return(nil)
102
102
  @session.user = @user
103
103
  @session.user.should be_nil
104
104
  end
105
-
105
+
106
106
  it "should set the instance varaible to nil if the return of store_user is false" do
107
107
  @session.authentication.should_receive(:store_user).and_return(false)
108
108
  @session.user = @user
109
109
  @session.user.should be_nil
110
110
  end
111
-
111
+
112
112
  it "should set the instance variable to the value of user if store_user is not nil or false" do
113
113
  @session.authentication.should_receive(:store_user).and_return(42)
114
114
  @session.user = @user
@@ -116,9 +116,9 @@ describe "Merb::Authentication Session" do
116
116
  @session[:user].should == 42
117
117
  end
118
118
  end
119
-
119
+
120
120
  describe "abandon!" do
121
-
121
+
122
122
  before(:each) do
123
123
  @user = mock("user")
124
124
  @session.authentication.stub!(:fetch_user).and_return(@user)
@@ -126,36 +126,36 @@ describe "Merb::Authentication Session" do
126
126
  @session[:user] = 42
127
127
  @session.user
128
128
  end
129
-
129
+
130
130
  it "should delete the session" do
131
131
  @session.should_receive(:clear)
132
132
  @session.abandon!
133
133
  end
134
-
134
+
135
135
  it "should not have a user after it is abandoned" do
136
136
  @session.user.should == @user
137
137
  @session.abandon!
138
138
  @session.user.should be_nil
139
139
  end
140
140
  end
141
-
141
+
142
142
  describe "Merb::Authentication" do
143
143
  it "Should be hookable" do
144
144
  Merb::Authentication.should include(Extlib::Hook)
145
145
  end
146
-
146
+
147
147
  end
148
-
148
+
149
149
  describe "#authenticate" do
150
-
150
+
151
151
  before(:all) do
152
152
  clear_strategies!
153
153
  end
154
-
154
+
155
155
  after(:all) do
156
156
  clear_strategies!
157
157
  end
158
-
158
+
159
159
  before(:each) do
160
160
  class Sone < Merb::Authentication::Strategy
161
161
  def run!
@@ -165,119 +165,119 @@ describe "Merb::Authentication Session" do
165
165
  end
166
166
  class Stwo < Merb::Authentication::Strategy
167
167
  def run!
168
- Viking.capture(Stwo)
168
+ Viking.capture(Stwo)
169
169
  params[:pass_2]
170
170
  end
171
171
  end
172
172
  class Sthree < Merb::Authentication::Strategy
173
173
  def run!
174
174
  Viking.capture(Sthree)
175
- params[:pass_3]
175
+ params[:pass_3]
176
176
  end
177
177
  end
178
178
  class Sfour < Merb::Authentication::Strategy
179
179
  abstract!
180
-
180
+
181
181
  def run!
182
182
  "BAD MAN"
183
183
  end
184
184
  end
185
-
185
+
186
186
  Sfour.should_not_receive(:run!)
187
187
  @request = Users.new(fake_request)
188
188
  @auth = Merb::Authentication.new(@request.session)
189
189
  Viking.captures.clear
190
190
  end
191
-
191
+
192
192
  it "should execute the strategies in the default order" do
193
193
  @request.params[:pass_3] = true
194
194
  @auth.authenticate!(@request, @request.params)
195
195
  Viking.captures.should == %w( Sone Stwo Sthree )
196
196
  end
197
-
197
+
198
198
  it "should run the strategeis until if finds a non nil non false" do
199
199
  @request.params[:pass_2] = true
200
200
  @auth.authenticate!(@request, @request.params)
201
201
  Viking.captures.should == %w( Sone Stwo )
202
202
  end
203
-
203
+
204
204
  it "should raise an Unauthenticated exception if no 'user' is found" do
205
205
  lambda do
206
206
  @auth.authenticate!(@request, @request.params)
207
207
  end.should raise_error(Merb::Controller::Unauthenticated)
208
208
  end
209
-
209
+
210
210
  it "should store the user into the session if one is found" do
211
211
  @auth.should_receive(:user=).with("WINNA")
212
212
  @request.params[:pass_1] = "WINNA"
213
213
  @auth.authenticate!(@request, @request.params)
214
214
  end
215
-
215
+
216
216
  it "should use the Authentiation#error_message as the error message" do
217
217
  @auth.should_receive(:error_message).and_return("BAD BAD BAD")
218
218
  lambda do
219
219
  @auth.authenticate!(@request, @request.params)
220
220
  end.should raise_error(Merb::Controller::Unauthenticated, "BAD BAD BAD")
221
221
  end
222
-
222
+
223
223
  it "should execute the strategies as passed into the authenticate! method" do
224
224
  @request.params[:pass_1] = true
225
225
  @auth.authenticate!(@request, @request.params, Stwo, Sone)
226
226
  Viking.captures.should == ["Stwo", "Sone"]
227
227
  end
228
-
229
-
228
+
229
+
230
230
  describe "Strategy loading as strings" do
231
-
231
+
232
232
  before :each do
233
233
  Merb::Authentication.reset_strategy_lookup!
234
-
234
+
235
235
  class Merb::Authentication::Strategies::Zone < Merb::Authentication::Strategy
236
236
  def run!
237
237
  Viking.capture(Merb::Authentication::Strategies::Zone)
238
- params[:z_one]
238
+ params[:z_one]
239
239
  end
240
240
  end
241
241
  end
242
-
242
+
243
243
  it "should allow for loading the strategies as strings" do
244
244
  @request.params[:z_one] = "z_one"
245
245
  @request.session.authenticate!(@request, @request.params, "Zone")
246
246
  @request.session.user.should == "z_one"
247
247
  end
248
-
248
+
249
249
  it "should raise a const misisng error when the error is not namespaced" do
250
250
  @request.params[:pass_1] = "s_one"
251
251
  lambda do
252
252
  @request.session.authenticate!(@request, @request.params, "Sone")
253
253
  end.should raise_error(NameError)
254
254
  end
255
-
256
-
255
+
256
+
257
257
  it "should allow a mix of strategies as strings or classes" do
258
258
  @request.params[:pass_2] = "s_two"
259
259
  @request.session.authenticate!(@request, @request.params, "Zone", Sone, Stwo)
260
260
  Viking.captures.should == %w(Merb::Authentication::Strategies::Zone Sone Stwo)
261
261
  end
262
262
  end
263
-
263
+
264
264
  end
265
-
265
+
266
266
  describe "user_class" do
267
267
  it "should have User as the default user class if requested" do
268
268
  Merb::Authentication.user_class.should == User
269
- end
269
+ end
270
270
  end
271
-
271
+
272
272
  describe "redirection" do
273
-
273
+
274
274
  before(:all) do
275
275
  class FooController < Merb::Controller
276
276
  before :ensure_authenticated
277
277
  def index; "FooController#index" end
278
278
  end
279
279
  end
280
-
280
+
281
281
  before(:each) do
282
282
  class MyStrategy < Merb::Authentication::Strategy
283
283
  def run!
@@ -289,37 +289,37 @@ describe "Merb::Authentication Session" do
289
289
  end
290
290
  end
291
291
  end # MyStrategy
292
-
292
+
293
293
  class FailStrategy < Merb::Authentication::Strategy
294
294
  def run!
295
295
  request.params[:should_not_be_here] = true
296
296
  end
297
297
  end
298
-
298
+
299
299
  Merb::Router.reset!
300
300
  Merb::Router.prepare{ match("/").to(:controller => "foo_controller")}
301
301
  @request = mock_request("/")
302
302
  @s = MyStrategy.new(@request, @request.params)
303
303
  @a = Merb::Authentication.new(@request.session)
304
304
  end
305
-
305
+
306
306
  it "should answer redirected false if the strategy did not redirect" do
307
307
  @a.authenticate! @request, @request.params
308
308
  @a.should_not be_redirected
309
309
  end
310
-
310
+
311
311
  it "should answer redirected true if the strategy did redirect" do
312
312
  @request.params[:url] = "/some/url"
313
313
  @a.authenticate! @request, @request.params
314
314
  @a.halted?
315
315
  end
316
-
316
+
317
317
  it "should provide access to the Headers" do
318
318
  @request.params[:url] = "/some/url"
319
319
  @a.authenticate! @request, @request.params
320
320
  @a.headers.should == {"Location" => "/some/url"}
321
321
  end
322
-
322
+
323
323
  it "should provide access to the status" do
324
324
  @request.params[:url] = "/some/url"
325
325
  @request.params[:status] = 401
@@ -327,7 +327,7 @@ describe "Merb::Authentication Session" do
327
327
  @a.should be_halted
328
328
  @a.status.should == 401
329
329
  end
330
-
330
+
331
331
  it "should stop processing the strategies if one redirects" do
332
332
  @request.params[:url] = "/some/url"
333
333
  lambda do
@@ -336,18 +336,18 @@ describe "Merb::Authentication Session" do
336
336
  @a.should be_halted
337
337
  @request.params[:should_not_be_here].should be_nil
338
338
  end
339
-
339
+
340
340
  it "should allow you to set the body" do
341
341
  @a.body = "body"
342
342
  @a.body.should == "body"
343
343
  end
344
-
344
+
345
345
  it "should put the body of the strategy as the response body of the controller" do
346
346
  controller = request "/", :params => {:url => "/some/url"}
347
347
  controller.should redirect_to("/some/url")
348
348
  end
349
349
  end
350
-
350
+
351
351
 
352
352
 
353
353