warden 0.5.3 → 0.6.0
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/History.rdoc +8 -5
- data/README.textile +1 -1
- data/lib/warden.rb +7 -4
- data/lib/warden/declarable.rb +43 -0
- data/lib/warden/hooks.rb +121 -0
- data/lib/warden/manager.rb +52 -21
- data/lib/warden/mixins/common.rb +11 -2
- data/lib/warden/proxy.rb +88 -32
- data/lib/warden/serializers.rb +20 -0
- data/lib/warden/serializers/base.rb +38 -0
- data/lib/warden/serializers/cookie.rb +34 -0
- data/lib/warden/serializers/session.rb +30 -0
- data/lib/warden/strategies.rb +18 -0
- data/lib/warden/{authentication/strategy_base.rb → strategies/base.rb} +27 -2
- data/lib/warden/version.rb +1 -1
- data/spec/helpers/request_helper.rb +14 -12
- data/spec/{warden → helpers}/strategies/failz.rb +0 -0
- data/spec/{warden → helpers}/strategies/invalid.rb +0 -0
- data/spec/{warden → helpers}/strategies/pass.rb +0 -0
- data/spec/{warden → helpers}/strategies/pass_without_user.rb +0 -0
- data/spec/{warden → helpers}/strategies/password.rb +0 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/warden/authenticated_data_store_spec.rb +4 -4
- data/spec/warden/manager_spec.rb +0 -8
- data/spec/warden/proxy_spec.rb +61 -10
- data/spec/warden/serializers/cookie_spec.rb +60 -0
- data/spec/warden/serializers/session_spec.rb +47 -0
- data/spec/warden/serializers_spec.rb +96 -0
- data/spec/warden/{strategy_base_spec.rb → strategies/base_spec.rb} +1 -1
- data/spec/warden/strategies_spec.rb +19 -15
- data/warden.gemspec +28 -18
- metadata +28 -18
- data/VERSION +0 -1
- data/lib/warden/authentication/hooks.rb +0 -124
- data/lib/warden/authentication/strategies.rb +0 -59
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'warden/declarable'
|
3
|
+
|
4
|
+
module Warden
|
5
|
+
module Serializers
|
6
|
+
extend Warden::Declarable
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def check_validity!(label, serializer)
|
10
|
+
[:fetch, :store, :stored?, :delete].each do |method|
|
11
|
+
next if serializer.method_defined?(method)
|
12
|
+
raise NoMethodError, "#{method} is not declared in the #{label.inspect} serializer"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
alias :_serializers :_declarations
|
17
|
+
end # << self
|
18
|
+
|
19
|
+
end # Serializers
|
20
|
+
end # Warden
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Warden
|
3
|
+
module Serializers
|
4
|
+
# A serializer is a place where you put the logic to serializing and deserializing an user. All serializers
|
5
|
+
# inherits from Warden::Serializers::Base.
|
6
|
+
#
|
7
|
+
# The Warden::Serializers.add method is a simple way to provide custom serializers. In order to do so,
|
8
|
+
# you _must_ declare @store@, @fetch@, @delete@ and @stored?@ methods.
|
9
|
+
#
|
10
|
+
# The parameters for Warden::Serializers.add method is:
|
11
|
+
# <label: Symbol> The label is the name given to a serializer. Use the label to refer to the serializer when authenticating
|
12
|
+
# <serializer: Class|nil> The optional serializer argument if set _must_ be a class that inherits from Warden::Serializers::Base
|
13
|
+
# <block> The block acts as a convinient way to declare your serializer. Inside is the class definition of a serializer.
|
14
|
+
#
|
15
|
+
# Check Session and Cookie serializers for more information.
|
16
|
+
#
|
17
|
+
class Base
|
18
|
+
attr_accessor :env
|
19
|
+
include ::Warden::Mixins::Common
|
20
|
+
|
21
|
+
def initialize(env)
|
22
|
+
@env = env
|
23
|
+
end
|
24
|
+
|
25
|
+
def key_for(scope)
|
26
|
+
"warden.user.#{scope}.key"
|
27
|
+
end
|
28
|
+
|
29
|
+
def serialize(user)
|
30
|
+
user
|
31
|
+
end
|
32
|
+
|
33
|
+
def deserialize(key)
|
34
|
+
key
|
35
|
+
end
|
36
|
+
end # Base
|
37
|
+
end # Serializers
|
38
|
+
end # Warden
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Warden
|
3
|
+
module Serializers
|
4
|
+
# A cookie serializer provided by Warden. You need to implement the serialize and deserialize
|
5
|
+
# methods in order to use it.
|
6
|
+
class Cookie < Base
|
7
|
+
def store(user, scope)
|
8
|
+
response.set_cookie key_for(scope), default_options(user)
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch(scope)
|
12
|
+
key = request.cookies[key_for(scope)]
|
13
|
+
return nil unless key
|
14
|
+
user = deserialize(key)
|
15
|
+
delete(scope) unless user
|
16
|
+
user
|
17
|
+
end
|
18
|
+
|
19
|
+
def stored?(scope)
|
20
|
+
!!request.cookies[key_for(scope)]
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete(scope, user=nil)
|
24
|
+
response.delete_cookie(key_for(scope))
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_options(user)
|
28
|
+
{ :value => serialize(user), :expires => (Time.now + 7 * 24 * 3600), :path => "/" }
|
29
|
+
end
|
30
|
+
end # Cookie
|
31
|
+
|
32
|
+
Serializers.add(:cookie, Cookie)
|
33
|
+
end # Serializers
|
34
|
+
end # Warden
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Warden
|
3
|
+
module Serializers
|
4
|
+
# A session serializer provided by Warden. You need to implement the serialize and deserialize
|
5
|
+
# methods in order to use it.
|
6
|
+
class Session < Base
|
7
|
+
def store(user, scope)
|
8
|
+
session[key_for(scope)] = serialize(user)
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch(scope)
|
12
|
+
key = session[key_for(scope)]
|
13
|
+
return nil unless key
|
14
|
+
user = deserialize(key)
|
15
|
+
delete(scope) unless user
|
16
|
+
user
|
17
|
+
end
|
18
|
+
|
19
|
+
def stored?(scope)
|
20
|
+
!!session[key_for(scope)]
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete(scope, user=nil)
|
24
|
+
session.delete(key_for(scope))
|
25
|
+
end
|
26
|
+
end # Session
|
27
|
+
|
28
|
+
Serializers.add(:session, Session)
|
29
|
+
end # Serializers
|
30
|
+
end # Warden
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'warden/declarable'
|
3
|
+
|
4
|
+
module Warden
|
5
|
+
module Strategies
|
6
|
+
extend Warden::Declarable
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def check_validity!(label, strategy)
|
10
|
+
return if strategy.method_defined?(:authenticate!)
|
11
|
+
raise NoMethodError, "authenticate! is not declared in the #{label.inspect} strategy"
|
12
|
+
end
|
13
|
+
|
14
|
+
alias :_strategies :_declarations
|
15
|
+
end # << self
|
16
|
+
|
17
|
+
end # Strategies
|
18
|
+
end # Warden
|
@@ -1,6 +1,32 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Warden
|
3
3
|
module Strategies
|
4
|
+
# A strategy is a place where you can put logic related to authentication. Any strategy inherits
|
5
|
+
# from Warden::Strategies::Base.
|
6
|
+
#
|
7
|
+
# The Warden::Strategies.add method is a simple way to provide custom strategies.
|
8
|
+
# You _must_ declare an @authenticate!@ method.
|
9
|
+
# You _may_ provide a @valid?@ method.
|
10
|
+
# The valid method should return true or false depending on if the strategy is a valid one for the request.
|
11
|
+
#
|
12
|
+
# The parameters for Warden::Strategies.add method is:
|
13
|
+
# <label: Symbol> The label is the name given to a strategy. Use the label to refer to the strategy when authenticating
|
14
|
+
# <strategy: Class|nil> The optional stragtegy argument if set _must_ be a class that inherits from Warden::Strategies::Base and _must_
|
15
|
+
# implement an @authenticate!@ method
|
16
|
+
# <block> The block acts as a convinient way to declare your strategy. Inside is the class definition of a strategy.
|
17
|
+
#
|
18
|
+
# Examples:
|
19
|
+
#
|
20
|
+
# Block Declared Strategy:
|
21
|
+
# Warden::Strategies.add(:foo) do
|
22
|
+
# def authenticate!
|
23
|
+
# # authentication logic
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# Class Declared Strategy:
|
28
|
+
# Warden::Strategies.add(:foo, MyStrategy)
|
29
|
+
#
|
4
30
|
class Base
|
5
31
|
# :api: public
|
6
32
|
attr_accessor :user, :message
|
@@ -24,7 +50,7 @@ module Warden
|
|
24
50
|
@halted = false
|
25
51
|
end
|
26
52
|
|
27
|
-
# The method that is called from above.
|
53
|
+
# The method that is called from above. This method calls the underlying authenticate! method
|
28
54
|
# :api: private
|
29
55
|
def _run! # :nodoc:
|
30
56
|
result = authenticate!
|
@@ -107,7 +133,6 @@ module Warden
|
|
107
133
|
headers["Content-Type"] = opts[:content_type] || 'text/plain'
|
108
134
|
|
109
135
|
@message = opts[:message].nil? ? "You are being redirected to #{headers["Location"]}" : opts[:message]
|
110
|
-
|
111
136
|
@result = :redirect
|
112
137
|
|
113
138
|
headers["Location"]
|
data/lib/warden/version.rb
CHANGED
@@ -1,49 +1,51 @@
|
|
1
1
|
module Warden::Spec
|
2
2
|
module Helpers
|
3
|
-
|
3
|
+
|
4
4
|
FAILURE_APP = lambda{|e|[401, {"Content-Type" => "text/plain"}, ["You Fail!"]] }
|
5
|
-
|
5
|
+
|
6
6
|
def env_with_params(path = "/", params = {})
|
7
7
|
method = params.fetch(:method, "GET")
|
8
8
|
Rack::MockRequest.env_for(path, :input => Rack::Utils.build_query(params),
|
9
9
|
'HTTP_VERSION' => '1.1',
|
10
10
|
'REQUEST_METHOD' => "#{method}")
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def setup_rack(app = nil, opts = {}, &block)
|
14
14
|
app ||= block if block_given?
|
15
|
-
opts[:default_strategies]
|
15
|
+
opts[:default_strategies] ||= [:password]
|
16
|
+
opts[:default_serializers] ||= [:session]
|
16
17
|
opts[:failure_app] ||= Warden::Spec::Helpers::FAILURE_APP
|
17
|
-
Rack::Builder.new do
|
18
|
+
Rack::Builder.new do
|
18
19
|
use Warden::Spec::Helpers::Session
|
19
20
|
use Warden::Manager, opts do |manager|
|
20
21
|
manager.failure_app = Warden::Spec::Helpers::FAILURE_APP
|
21
22
|
manager.default_strategies *opts[:default_strategies]
|
23
|
+
manager.default_serializers *opts[:default_serializers]
|
22
24
|
end
|
23
25
|
run app
|
24
26
|
end
|
25
27
|
end
|
26
|
-
|
28
|
+
|
27
29
|
def valid_response
|
28
|
-
|
30
|
+
Rack::Response.new("OK").finish
|
29
31
|
end
|
30
|
-
|
32
|
+
|
31
33
|
def failure_app
|
32
34
|
Warden::Spec::Helpers::FAILURE_APP
|
33
35
|
end
|
34
|
-
|
36
|
+
|
35
37
|
def success_app
|
36
38
|
lambda{|e| [200, {"Content-Type" => "text/plain"}, ["You Win"]]}
|
37
39
|
end
|
38
|
-
|
40
|
+
|
39
41
|
class Session
|
40
42
|
attr_accessor :app
|
41
43
|
def initialize(app,configs = {})
|
42
44
|
@app = app
|
43
45
|
end
|
44
|
-
|
46
|
+
|
45
47
|
def call(e)
|
46
|
-
e['rack.session'] ||= {}
|
48
|
+
e['rack.session'] ||= {}
|
47
49
|
@app.call(e)
|
48
50
|
end
|
49
51
|
end # session
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/spec/spec_helper.rb
CHANGED
@@ -12,7 +12,7 @@ Spec::Runner.configure do |config|
|
|
12
12
|
config.include(Warden::Spec::Helpers)
|
13
13
|
|
14
14
|
def load_strategies
|
15
|
-
Dir[File.join(File.dirname(__FILE__), "
|
15
|
+
Dir[File.join(File.dirname(__FILE__), "helpers", "strategies", "**/*.rb")].each do |f|
|
16
16
|
load f
|
17
17
|
end
|
18
18
|
end
|
@@ -5,9 +5,9 @@ describe "authenticated data store" do
|
|
5
5
|
before(:each) do
|
6
6
|
@env = env_with_params
|
7
7
|
@env['rack.session'] = {
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
"warden.user.foo.key" => "foo user",
|
9
|
+
"warden.user.default.key" => "default user",
|
10
|
+
:foo => "bar"
|
11
11
|
}
|
12
12
|
end
|
13
13
|
|
@@ -18,7 +18,7 @@ describe "authenticated data store" do
|
|
18
18
|
e['warden'].should be_authenticated
|
19
19
|
e['warden'].should be_authenticated(:foo)
|
20
20
|
|
21
|
-
# Store the data for :
|
21
|
+
# Store the data for :default
|
22
22
|
e['warden'].session[:key] = "value"
|
23
23
|
valid_response
|
24
24
|
end
|
data/spec/warden/manager_spec.rb
CHANGED
@@ -12,14 +12,6 @@ describe Warden::Manager do
|
|
12
12
|
env["warden"].should be_an_instance_of(Warden::Proxy)
|
13
13
|
end
|
14
14
|
|
15
|
-
describe "user storage" do
|
16
|
-
it "should take a user and store it in the provided session" do
|
17
|
-
session = {}
|
18
|
-
Warden::Manager._store_user("The User", session, "some_scope")
|
19
|
-
session["warden.user.some_scope.key"].should == "The User"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
15
|
describe "thrown auth" do
|
24
16
|
before(:each) do
|
25
17
|
@basic_app = lambda{|env| [200,{'Content-Type' => 'text/plain'},'OK']}
|
data/spec/warden/proxy_spec.rb
CHANGED
@@ -165,9 +165,9 @@ describe Warden::Proxy do
|
|
165
165
|
env['warden'].authenticate(:pass, :scope => :foo)
|
166
166
|
env['warden'].authenticate(:pass, :scope => :bar)
|
167
167
|
env['warden'].authenticate(:password)
|
168
|
-
env['warden'].authenticated?(:foo).should
|
169
|
-
env['warden'].authenticated?(:bar).should
|
170
|
-
env['warden'].authenticated?.should
|
168
|
+
env['warden'].authenticated?(:foo).should be_true
|
169
|
+
env['warden'].authenticated?(:bar).should be_true
|
170
|
+
env['warden'].authenticated?.should be_false
|
171
171
|
valid_response
|
172
172
|
end
|
173
173
|
env = env_with_params
|
@@ -195,7 +195,7 @@ describe Warden::Proxy do
|
|
195
195
|
end
|
196
196
|
end # describe "authentication"
|
197
197
|
|
198
|
-
describe "stored
|
198
|
+
describe "stored?" do
|
199
199
|
before(:each) do
|
200
200
|
@env['rack.session'] ||= {}
|
201
201
|
@env['rack.session']['warden.user.default.key'] = "User"
|
@@ -203,7 +203,7 @@ describe Warden::Proxy do
|
|
203
203
|
|
204
204
|
it "returns true if user key is stored in session" do
|
205
205
|
app = lambda do |env|
|
206
|
-
env['warden'].
|
206
|
+
env['warden'].stored?.should be_true
|
207
207
|
valid_response
|
208
208
|
end
|
209
209
|
setup_rack(app).call(@env)
|
@@ -212,11 +212,31 @@ describe Warden::Proxy do
|
|
212
212
|
it "returns false if user key is not stored in session" do
|
213
213
|
@env['rack.session'].delete("warden.user.default.key")
|
214
214
|
app = lambda do |env|
|
215
|
-
env['warden'].
|
215
|
+
env['warden'].stored?.should be_false
|
216
216
|
valid_response
|
217
217
|
end
|
218
218
|
setup_rack(app).call(@env)
|
219
219
|
end
|
220
|
+
|
221
|
+
it "returns false if scope given is not stored in session" do
|
222
|
+
app = lambda do |env|
|
223
|
+
env['warden'].stored?.should be_true
|
224
|
+
env['warden'].stored?(:another).should be_false
|
225
|
+
valid_response
|
226
|
+
end
|
227
|
+
setup_rack(app).call(@env)
|
228
|
+
end
|
229
|
+
|
230
|
+
it "returns based on the given store" do
|
231
|
+
@env['rack.session'].delete("warden.user.default.key")
|
232
|
+
@env["HTTP_COOKIE"] = "warden.user.default.key=user;"
|
233
|
+
app = lambda do |env|
|
234
|
+
env['warden'].stored?(:default, :session).should be_false
|
235
|
+
env['warden'].stored?(:default, :cookie).should be_true
|
236
|
+
valid_response
|
237
|
+
end
|
238
|
+
setup_rack(app, :default_serializers => [:session, :cookie]).call(@env)
|
239
|
+
end
|
220
240
|
end
|
221
241
|
|
222
242
|
describe "set user" do
|
@@ -232,6 +252,19 @@ describe Warden::Proxy do
|
|
232
252
|
setup_rack(app).call(env)
|
233
253
|
end
|
234
254
|
|
255
|
+
it "should store the user in all serializers" do
|
256
|
+
env = env_with_params("/")
|
257
|
+
app = lambda do |env|
|
258
|
+
env['warden'].authenticate(:pass)
|
259
|
+
env['warden'].should be_authenticated
|
260
|
+
env['warden'].user.should == "Valid User"
|
261
|
+
valid_response
|
262
|
+
end
|
263
|
+
setup_rack(app, :default_serializers => [:session, :cookie]).call(env)
|
264
|
+
headers = env['warden'].serializers.last.response.headers
|
265
|
+
headers['Set-Cookie'].split(";").first.should == "warden.user.default.key=Valid+User"
|
266
|
+
end
|
267
|
+
|
235
268
|
it "should not store the user if the :store option is set to false" do
|
236
269
|
env = env_with_params("/")
|
237
270
|
app = lambda do |e|
|
@@ -268,6 +301,15 @@ describe Warden::Proxy do
|
|
268
301
|
setup_rack(app).call(@env)
|
269
302
|
end
|
270
303
|
|
304
|
+
it "should load user from others serializers" do
|
305
|
+
@env["HTTP_COOKIE"] = "warden.user.default.key=user;"
|
306
|
+
app = lambda do |env|
|
307
|
+
env['warden'].user.should == "user"
|
308
|
+
valid_response
|
309
|
+
end
|
310
|
+
setup_rack(app, :default_serializers => [:session, :cookie]).call(@env)
|
311
|
+
end
|
312
|
+
|
271
313
|
describe "previously logged in" do
|
272
314
|
|
273
315
|
before(:each) do
|
@@ -299,14 +341,14 @@ describe Warden::Proxy do
|
|
299
341
|
before(:each) do
|
300
342
|
@env = env = env_with_params
|
301
343
|
@env['rack.session'] = {"warden.user.default.key" => "default key", "warden.user.foo.key" => "foo key", :foo => "bar"}
|
302
|
-
app = lambda do |e|
|
344
|
+
@app = lambda do |e|
|
303
345
|
e['warden'].logout(env['warden.spec.which_logout'])
|
304
346
|
valid_response
|
305
347
|
end
|
306
|
-
@app = setup_rack(app)
|
307
348
|
end
|
308
349
|
|
309
350
|
it "should logout only the scoped foo user" do
|
351
|
+
@app = setup_rack(@app)
|
310
352
|
@env['warden.spec.which_logout'] = :foo
|
311
353
|
@app.call(@env)
|
312
354
|
@env['rack.session']['warden.user.default.key'].should == "default key"
|
@@ -315,6 +357,7 @@ describe Warden::Proxy do
|
|
315
357
|
end
|
316
358
|
|
317
359
|
it "should logout only the scoped default user" do
|
360
|
+
@app = setup_rack(@app)
|
318
361
|
@env['warden.spec.which_logout'] = :default
|
319
362
|
@app.call(@env)
|
320
363
|
@env['rack.session']['warden.user.default.key'].should be_nil
|
@@ -343,7 +386,6 @@ describe Warden::Proxy do
|
|
343
386
|
end
|
344
387
|
setup_rack(app).call(@env)
|
345
388
|
@env['warden'].user.should be_nil
|
346
|
-
|
347
389
|
end
|
348
390
|
|
349
391
|
it "should clear the session data when logging out" do
|
@@ -357,6 +399,15 @@ describe Warden::Proxy do
|
|
357
399
|
setup_rack(app).call(@env)
|
358
400
|
end
|
359
401
|
|
402
|
+
it "should clear the session in all serializers" do
|
403
|
+
@app = setup_rack(@app, :default_serializers => [:session, :cookie])
|
404
|
+
@env['warden.spec.which_logout'] = :default
|
405
|
+
@app.call(@env)
|
406
|
+
@env['warden'].serializers.last.should_not be_nil
|
407
|
+
headers = @env['warden'].serializers.last.response.headers
|
408
|
+
headers['Set-Cookie'].first.split(";").first.should == "warden.user.default.key="
|
409
|
+
end
|
410
|
+
|
360
411
|
it "should clear out the session by calling reset_session! so that plugins can setup their own session clearing" do
|
361
412
|
@env['rack.session'].should_not be_nil
|
362
413
|
app = lambda do |e|
|
@@ -395,7 +446,7 @@ describe Warden::Proxy do
|
|
395
446
|
it "should return false for authenticated when there are no valid? strategies" do
|
396
447
|
@env['rack.session'] = {}
|
397
448
|
app = lambda do |e|
|
398
|
-
e['warden'].authenticated?(:invalid).should
|
449
|
+
e['warden'].authenticated?(:invalid).should be_false
|
399
450
|
end
|
400
451
|
setup_rack(app).call(@env)
|
401
452
|
end
|