warden 0.10.1 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
data/History.rdoc CHANGED
@@ -1,3 +1,7 @@
1
+ == Version 0.10.1 / 2010-03-23
2
+ * Merge previous from master
3
+ * tag
4
+
1
5
  == Version 0.10.0 / 2010-03-22
2
6
  * Allow default strategies to be set on the proxy
3
7
  * Provide each scope with it's own default strategies
data/lib/warden/config.rb CHANGED
@@ -36,9 +36,15 @@ module Warden
36
36
 
37
37
  def initialize(other={})
38
38
  merge!(other)
39
- self[:default_scope] ||= :default
40
- self[:default_scope_options] ||= {}
41
- self[:default_strategies] ||= {}
39
+ self[:default_scope] ||= :default
40
+ self[:scope_defaults] ||= {}
41
+ self[:default_strategies] ||= {}
42
+ end
43
+
44
+ def initialize_copy(other)
45
+ super
46
+ deep_dup(:scope_defaults, other)
47
+ deep_dup(:default_strategies, other)
42
48
  end
43
49
 
44
50
  # Do not raise an error if a missing strategy is given by default.
@@ -54,33 +60,27 @@ module Warden
54
60
  # Set the default strategies to use.
55
61
  # :api: public
56
62
  def default_strategies(*strategies)
57
- opts = Hash === strategies.last ? strategies.pop : {}
58
- scope = opts[:scope] || default_scope
59
- if strategies.empty?
60
- self[:default_strategies][scope]
61
- else
62
- self[:default_strategies][scope] = strategies.flatten
63
- end
64
- end
63
+ opts = Hash === strategies.last ? strategies.pop : {}
64
+ hash = self[:default_strategies]
65
+ scope = opts[:scope] || :_all
65
66
 
66
- # Set the default options that are passed to set_user. This is configured
67
- # during the setup phase and is used throughout.
68
- def default_scope_options(scope = default_scope, opts = nil)
69
- if opts.nil?
70
- # We're reading the default options for this scope
71
- self[:default_scope_options][scope] ||= {}
72
- else
73
- # We're setting the default options forthe scope
74
- self[:default_scope_options][scope] = opts
75
- end
67
+ hash[scope] = strategies.flatten unless strategies.empty?
68
+ hash[scope] || hash[:_all]
76
69
  end
77
70
 
78
71
  # A short hand way to set up a particular scope
72
+ # :api: public
79
73
  def scope_defaults(scope, opts = {})
80
- strategies = opts.delete(:strategies) || []
81
- default_strategies(strategies, :scope => scope)
82
- default_scope_options(scope, opts)
83
- true
74
+ if strategies = opts.delete(:strategies)
75
+ default_strategies(strategies, :scope => scope)
76
+ end
77
+
78
+ if opts.empty?
79
+ self[:scope_defaults][scope] || {}
80
+ else
81
+ self[:scope_defaults][scope] ||= {}
82
+ self[:scope_defaults][scope].merge!(opts)
83
+ end
84
84
  end
85
85
 
86
86
  # Quick accessor to strategies from manager
@@ -100,5 +100,12 @@ module Warden
100
100
  def serialize_from_session(*args, &block)
101
101
  Warden::Manager.serialize_from_session(*args, &block)
102
102
  end
103
+
104
+ protected
105
+
106
+ def deep_dup(key, other)
107
+ self[key] = hash = other[key].dup
108
+ hash.each { |k, v| hash[k] = v.dup }
109
+ end
103
110
  end
104
111
  end
@@ -30,7 +30,7 @@ module Warden
30
30
  # If this is downstream from another warden instance, don't do anything.
31
31
  # :api: private
32
32
  def call(env) # :nodoc:
33
- return @app.call(env) unless env['warden'].nil?
33
+ return @app.call(env) unless env['warden'].nil? || env['warden'].manager == self
34
34
 
35
35
  env['warden'] = Proxy.new(env, self)
36
36
  result = catch(:warden) do
data/lib/warden/proxy.rb CHANGED
@@ -12,7 +12,7 @@ module Warden
12
12
 
13
13
  # An accessor to the rack env hash, the proxy owner and its config
14
14
  # :api: public
15
- attr_reader :env, :manager, :config
15
+ attr_reader :env, :manager, :config, :winning_strategies
16
16
 
17
17
  extend ::Forwardable
18
18
  include ::Warden::Mixins::Common
@@ -20,10 +20,13 @@ module Warden
20
20
  # :api: private
21
21
  def_delegators :winning_strategy, :headers, :status, :custom_response
22
22
 
23
+ # :api: public
24
+ def_delegators :config, :default_strategies
25
+
23
26
  def initialize(env, manager) #:nodoc:
24
- @env, @users = env, {}
25
- @strategies = Hash.new { |h,k| h[k] = {} }
26
- @manager, @config = manager, manager.config
27
+ @env, @users, @winning_strategies = env, {}, {}
28
+ @manager, @config = manager, manager.config.dup
29
+ @strategies = Hash.new { |h,k| h[k] = {} }
27
30
  errors # setup the error object in the session
28
31
  manager._run_callbacks(:on_request, self)
29
32
  end
@@ -58,36 +61,12 @@ module Warden
58
61
  def clear_strategies_cache!(*args)
59
62
  scope, opts = _retrieve_scope_and_opts(args)
60
63
 
64
+ @winning_strategies.delete(scope)
61
65
  @strategies[scope].each do |k, v|
62
66
  v.clear! if args.empty? || args.include?(k)
63
67
  end
64
68
  end
65
69
 
66
- # Provides access to the currently defined default strategies for the proxy.
67
- # This can change as it moves throughout the rack graph
68
- # Any changes to this are reflected only for the duration of the request
69
- # By changing this value, you can change the default strategies for a downstream branch of you rack graph.
70
- #
71
- # @api public
72
- def default_strategies(*strategies)
73
- scope, opts = _retrieve_scope_and_opts(strategies)
74
- if strategies.empty?
75
- _default_strategies[scope] ||= begin
76
- (
77
- @config.default_strategies(:scope => scope) ||
78
- @config.default_strategies(:scope => @config.default_scope)
79
- ).dup
80
- end
81
- else
82
- _default_strategies[scope] = strategies.flatten
83
- end
84
- _default_strategies[scope]
85
- end
86
-
87
- def _default_strategies
88
- @default_strategies ||= {}
89
- end
90
-
91
70
  # Run the authentiation strategies for the given strategies.
92
71
  # If there is already a user logged in for a given scope, the strategies are not run
93
72
  # This does not halt the flow of control and is a passive attempt to authenticate only
@@ -167,10 +146,7 @@ module Warden
167
146
  scope = (opts[:scope] ||= @config.default_scope)
168
147
 
169
148
  # Get the default options from the master configuration for the given scope
170
- opts = opts.dup
171
- if @config.default_scope_options(scope)
172
- opts = @config.default_scope_options(scope).merge(opts)
173
- end
149
+ opts = @config.scope_defaults(scope).merge(opts)
174
150
 
175
151
  @users[scope] = user
176
152
  session_serializer.store(user, scope) unless opts[:store] == false
@@ -298,15 +274,14 @@ module Warden
298
274
 
299
275
  # Run the strategies for a given scope
300
276
  def _run_strategies_for(scope, args) #:nodoc:
301
- self.winning_strategy = nil
277
+ self.winning_strategy = @winning_strategies[scope]
302
278
  strategies = args.empty? ? default_strategies(:scope => scope) : args
303
- puts strategies.inspect
304
279
 
305
280
  strategies.each do |name|
306
281
  strategy = _fetch_strategy(name, scope)
307
282
  next unless strategy && !strategy.performed? && strategy.valid?
308
283
 
309
- self.winning_strategy = strategy
284
+ self.winning_strategy = @winning_strategies[scope] = strategy
310
285
  strategy._run!
311
286
  break if strategy.halted?
312
287
  end
@@ -3,9 +3,9 @@ module Warden
3
3
  # Sets up a place for deprecation of methods from the main proxy
4
4
  module ProxyDeprecation
5
5
  def default_strategies=(*strategies)
6
- warn "[DEPRECATION] warden.default_strateiges= is deprecated. Instead use warden.set_default_strategies(*strategies) with an optional :scope => :scope)"
6
+ warn "[DEPRECATION] warden.default_strategies= is deprecated. Instead use warden.default_strategies(*strategies) with an optional :scope => :scope)"
7
7
  strategies.push(:scope => @config.default_scope)
8
- set_default_strategies(*strategies)
8
+ default_strategies(*strategies)
9
9
  end
10
10
  end
11
11
  end
@@ -119,8 +119,17 @@ module Warden
119
119
 
120
120
  # This causes the strategy to fail. It does not throw an :warden symbol to drop the request out to the failure application
121
121
  # You must throw an :warden symbol somewhere in the application to enforce this
122
+ # Halts the strategies so that this is the last strategy checked
122
123
  # :api: public
123
124
  def fail!(message = "Failed to Login")
125
+ halt!
126
+ @message = message
127
+ @result = :failure
128
+ end
129
+
130
+ # Casuses the strategy to fail, but not halt. The strategies will cascade after this failure and warden will check the next strategy. The last strategy to fail will have it's message displayed.
131
+ # :api: public
132
+ def fail(message = "Failed to Login")
124
133
  @message = message
125
134
  @result = :failure
126
135
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Warden
3
- VERSION = "0.10.1".freeze
3
+ VERSION = "0.10.2".freeze
4
4
  end
@@ -43,6 +43,6 @@ describe Warden::Config do
43
43
  c = Warden::Config.new
44
44
  c.scope_defaults :foo, :strategies => [:foo, :bar], :store => false
45
45
  c.default_strategies(:scope => :foo).should == [:foo, :bar]
46
- c.default_scope_options(:foo).should == {:store => false}
46
+ c.scope_defaults(:foo).should == {:store => false}
47
47
  end
48
48
  end
@@ -7,7 +7,7 @@ describe Warden::Manager do
7
7
  load_strategies
8
8
  end
9
9
 
10
- it "should insert a Base object into the rack env" do
10
+ it "should insert a Proxy object into the rack env" do
11
11
  env = env_with_params
12
12
  setup_rack(success_app).call(env)
13
13
  env["warden"].should be_an_instance_of(Warden::Proxy)
@@ -80,8 +80,53 @@ describe Warden::Manager do
80
80
  result.first.should == 401
81
81
  env["warden.options"][:attempted_path].should == "/access/path"
82
82
  end
83
- end # failure
84
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
+ end # failure
85
130
  end
86
131
 
87
132
  describe "integrated strategies" do
@@ -220,6 +220,18 @@ describe Warden::Proxy do
220
220
  setup_rack(app).call(env)
221
221
  end
222
222
 
223
+ it "should store the last winning strategy per scope" do
224
+ env = env_with_params("/")
225
+ app = lambda do |env|
226
+ env['warden'].authenticate(:failz)
227
+ env['warden'].should_not be_authenticated
228
+ env['warden'].authenticate(:failz)
229
+ env['warden'].winning_strategy.message.should == "The Fails Strategy Has Failed You"
230
+ valid_response
231
+ end
232
+ setup_rack(app).call(env)
233
+ end
234
+
223
235
  it "should run strategies for a given scope several times if cache is cleaned" do
224
236
  env = env_with_params("/")
225
237
  app = lambda do |env|
@@ -667,7 +679,7 @@ describe "dynamic default_strategies" do
667
679
  end
668
680
 
669
681
  Warden::Strategies.add(:two) do
670
- def authenticate!; $captures << :two; fail!("User not found") end
682
+ def authenticate!; $captures << :two; fail("User not found") end
671
683
  end
672
684
  end
673
685
 
@@ -751,7 +763,7 @@ describe "dynamic default_strategies" do
751
763
  app = wrap_app(@app) do |e|
752
764
  e['warden'].default_strategies << :one
753
765
  e['warden'].default_strategies.should == [:password, :one]
754
- e['warden'].config.default_strategies.should == [:password]
766
+ e['warden'].manager.config.default_strategies.should == [:password]
755
767
  e['warden'].authenticate!
756
768
  Rack::Response.new("OK").finish
757
769
  end
@@ -769,8 +781,8 @@ describe "dynamic default_strategies" do
769
781
  config.default_strategies :two, :one, :scope => :foo
770
782
  config.default_strategies :two, :one, :scope => :bar
771
783
 
772
- config.default_scope_options :bar, :store => false
773
- config.default_scope_options :baz, :store => false
784
+ config.scope_defaults :bar, :store => false
785
+ config.scope_defaults :baz, :store => false
774
786
  config.failure_app = Warden::Spec::Helpers::FAILURE_APP
775
787
  end
776
788
  run(lambda do |e|
@@ -190,32 +190,59 @@ describe Warden::Strategies::Base do
190
190
  describe "failure" do
191
191
 
192
192
  before(:each) do
193
- RAS.add(:foobar) do
193
+ RAS.add(:hard_fail) do
194
194
  def authenticate!
195
195
  fail!("You are not cool enough")
196
196
  end
197
197
  end
198
- @str = RAS[:foobar].new(env_with_params)
198
+
199
+ RAS.add(:soft_fail) do
200
+ def authenticate!
201
+ fail("You are too soft")
202
+ end
203
+ end
204
+ @hard = RAS[:hard_fail].new(env_with_params)
205
+ @soft = RAS[:soft_fail].new(env_with_params)
199
206
  end
200
207
 
201
- it "should allow you to fail" do
202
- @str._run!
203
- @str.user.should be_nil
208
+ it "should allow you to fail hard" do
209
+ @hard._run!
210
+ @hard.user.should be_nil
204
211
  end
205
212
 
206
- it "should not halt the strategies when failing" do
207
- @str._run!
208
- @str.should_not be_halted
213
+ it "should halt the strategies when failing hard" do
214
+ @hard._run!
215
+ @hard.should be_halted
209
216
  end
210
217
 
211
- it "should allow you to set a message when failing" do
212
- @str._run!
213
- @str.message.should == "You are not cool enough"
218
+ it "should allow you to set a message when failing hard" do
219
+ @hard._run!
220
+ @hard.message.should == "You are not cool enough"
214
221
  end
215
222
 
216
- it "should set the action as :failure" do
217
- @str._run!
218
- @str.result.should == :failure
223
+ it "should set the action as :failure when failing hard" do
224
+ @hard._run!
225
+ @hard.result.should == :failure
226
+ end
227
+
228
+ it "should allow you to fail soft" do
229
+ @soft._run!
230
+ @soft.user.should be_nil
231
+ end
232
+
233
+ it "should not halt the strategies when failing soft" do
234
+ @soft._run!
235
+ @soft.should_not be_halted
236
+ end
237
+
238
+ it "should allow you to set a message when failing soft" do
239
+ @soft._run!
240
+ @soft.message.should == "You are too soft"
241
+ end
242
+
243
+ it "should set the action as :failure when failing soft" do
244
+ @soft._run!
245
+ @soft.result.should == :failure
219
246
  end
220
247
  end
221
248
 
data/warden.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{warden}
8
- s.version = "0.10.1"
8
+ s.version = "0.10.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Daniel Neighman"]
12
- s.date = %q{2010-03-23}
12
+ s.date = %q{2010-03-26}
13
13
  s.email = %q{has.sox@gmail.com}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE",
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 10
8
- - 1
9
- version: 0.10.1
8
+ - 2
9
+ version: 0.10.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Daniel Neighman
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-23 00:00:00 +11:00
17
+ date: 2010-03-26 00:00:00 +11:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency