merb-auth-core 1.1.0 → 1.1.1

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.
@@ -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