warden 1.2.0 → 1.2.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.
data/History.rdoc CHANGED
@@ -1,3 +1,8 @@
1
+ == Version 1.2.1 / 2012-06-16
2
+ * Minor caching and speed improvements
3
+ * Add support to #lock in the proxy
4
+ * Add support to after_failed_fetch callback
5
+
1
6
  == Version 1.2.0 / 2012-05-08
2
7
  * Deprecate warden_cookies since it was never functional
3
8
  * Add support to serialize_from_session and serialize_into_session per scope
data/lib/warden/hooks.rb CHANGED
@@ -117,6 +117,34 @@ module Warden
117
117
  @_before_failure ||= []
118
118
  end
119
119
 
120
+ # A callback that runs if no user could be fetched, meaning there is now no user logged in.
121
+ #
122
+ # Parameters:
123
+ # <options> Some options which specify when the callback should be executed
124
+ # scope - Executes the callback only if it maches the scope(s) given
125
+ # <block> A block to contain logic for the callback
126
+ # Block Parameters: |user, auth, scope|
127
+ # user - The authenticated user for the current scope
128
+ # auth - The warden proxy object
129
+ # opts - any options passed into the authenticate call including :scope
130
+ #
131
+ # Example:
132
+ # Warden::Manager.after_failed_fetch do |user, auth, opts|
133
+ # I18n.locale = :en
134
+ # end
135
+ #
136
+ # :api: public
137
+ def after_failed_fetch(options = {}, method = :push, &block)
138
+ raise BlockNotGiven unless block_given?
139
+ _after_failed_fetch.send(method, [block, options])
140
+ end
141
+
142
+ # Provides access to the callback array for after_failed_fetch
143
+ # :api: private
144
+ def _after_failed_fetch
145
+ @_after_failed_fetch ||= []
146
+ end
147
+
120
148
  # A callback that runs just prior to the logout of each scope.
121
149
  #
122
150
  # Parameters:
data/lib/warden/proxy.rb CHANGED
@@ -25,7 +25,7 @@ module Warden
25
25
  def_delegators :config, :default_strategies
26
26
 
27
27
  def initialize(env, manager) #:nodoc:
28
- @env, @users, @winning_strategies = env, {}, {}
28
+ @env, @users, @winning_strategies, @locked = env, {}, {}, false
29
29
  @manager, @config = manager, manager.config.dup
30
30
  @strategies = Hash.new { |h,k| h[k] = {} }
31
31
  manager._run_callbacks(:on_request, self)
@@ -45,9 +45,13 @@ module Warden
45
45
  @session_serializer ||= Warden::SessionSerializer.new(@env)
46
46
  end
47
47
 
48
- # Clear the cache of performed strategies so far. It has the same API
49
- # as authenticate, allowing you to clear an specific strategies for
50
- # given scope:
48
+ # Clear the cache of performed strategies so far. Warden runs each
49
+ # strategy just once during the request lifecycle. You can clear the
50
+ # strategies cache if you want to allow a strategy to be run more than
51
+ # once.
52
+ #
53
+ # This method has the same API as authenticate, allowing you to clear
54
+ # specific strategies for given scope:
51
55
  #
52
56
  # Parameters:
53
57
  # args - a list of symbols (labels) that name the strategies to attempt
@@ -73,6 +77,16 @@ module Warden
73
77
  end
74
78
  end
75
79
 
80
+ # Locks the proxy so new users cannot authenticate during the
81
+ # request lifecycle. This is useful when the request cannot
82
+ # be verified (for example, using a CSRF verification token).
83
+ # Notice that already authenticated users are kept as so.
84
+ #
85
+ # :api: public
86
+ def lock!
87
+ @locked = true
88
+ end
89
+
76
90
  # Run the authentiation strategies for the given strategies.
77
91
  # If there is already a user logged in for a given scope, the strategies are not run
78
92
  # This does not halt the flow of control and is a passive attempt to authenticate only
@@ -93,8 +107,8 @@ module Warden
93
107
 
94
108
  # Same API as authenticated, but returns a boolean instead of a user.
95
109
  # The difference between this method (authenticate?) and authenticated?
96
- # is that the former will run strategies if the user has not yet been authenticated,
97
- # and the second relies on already performed ones.
110
+ # is that the former will run strategies if the user has not yet been
111
+ # authenticated, and the second relies on already performed ones.
98
112
  # :api: public
99
113
  def authenticate?(*args)
100
114
  result = !!authenticate(*args)
@@ -192,10 +206,15 @@ module Warden
192
206
  opts = argument.is_a?(Hash) ? argument : { :scope => argument }
193
207
  scope = (opts[:scope] ||= @config.default_scope)
194
208
 
195
- @users[scope] ||= begin
196
- user = session_serializer.fetch(scope)
197
- opts[:event] = :fetch
198
- set_user(user, opts) if user
209
+ if @users.has_key?(scope)
210
+ @users[scope]
211
+ else
212
+ unless user = session_serializer.fetch(scope)
213
+ run_callbacks = opts.fetch(:run_callbacks, true)
214
+ manager._run_callbacks(:after_failed_fetch, user, self, :scope => scope) if run_callbacks
215
+ end
216
+
217
+ @users[scope] = user ? set_user(user, opts.merge(:event => :fetch)) : nil
199
218
  end
200
219
  end
201
220
 
@@ -296,7 +315,7 @@ module Warden
296
315
 
297
316
  # Look for an existing user in the session for this scope.
298
317
  # If there was no user in the session. See if we can get one from the request.
299
- return user, opts if user = user(scope)
318
+ return user, opts if user = user(opts.merge(:scope => scope))
300
319
  _run_strategies_for(scope, args)
301
320
 
302
321
  if winning_strategy && winning_strategy.user
@@ -319,6 +338,9 @@ module Warden
319
338
  self.winning_strategy = @winning_strategies[scope]
320
339
  return if winning_strategy && winning_strategy.halted?
321
340
 
341
+ # Do not run any strategy if locked
342
+ return if @locked
343
+
322
344
  if args.empty?
323
345
  defaults = @config[:default_strategies]
324
346
  strategies = defaults[scope] || defaults[:_all]
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Warden
3
- VERSION = "1.2.0".freeze
3
+ VERSION = "1.2.1".freeze
4
4
  end
data/spec/spec_helper.rb CHANGED
@@ -14,6 +14,7 @@ end
14
14
 
15
15
  RSpec.configure do |config|
16
16
  config.include(Warden::Spec::Helpers)
17
+ config.include(Warden::Test::Helpers)
17
18
 
18
19
  def load_strategies
19
20
  Dir[File.join(File.dirname(__FILE__), "helpers", "strategies", "**/*.rb")].each do |f|
@@ -177,7 +177,35 @@ describe "standard authentication hooks" do
177
177
  env['warden.spec.order'].should == [1,2,3]
178
178
  end
179
179
  end
180
+ end
181
+
182
+
183
+ describe "after_failed_fetch" do
184
+ before(:each) do
185
+ RAM = Warden::Manager unless defined?(RAM)
186
+ RAM._after_failed_fetch.clear
187
+ end
180
188
 
189
+ after(:each) do
190
+ RAM._after_failed_fetch.clear
191
+ end
192
+
193
+ it "should not be called when user is fetched" do
194
+ RAM.after_failed_fetch{|u,a,o| fail }
195
+ env = env_with_params
196
+ setup_rack(lambda { |e| valid_response }).call(env)
197
+ env['rack.session']['warden.user.default.key'] = "Foo"
198
+ env['warden'].user.should == "Foo"
199
+ end
200
+
201
+ it "should be called if fetched user is nil" do
202
+ calls = 0
203
+ RAM.after_failed_fetch{|u,a,o| calls += 1 }
204
+ env = env_with_params
205
+ setup_rack(lambda { |e| valid_response }).call(env)
206
+ env['warden'].user.should be_nil
207
+ calls.should == 1
208
+ end
181
209
  end
182
210
 
183
211
  describe "before_failure" do
@@ -377,7 +377,7 @@ describe Warden::Proxy do
377
377
 
378
378
  it "should run the callbacks when :run_callbacks is true" do
379
379
  app = lambda do |env|
380
- env['warden'].manager.should_receive(:_run_callbacks)
380
+ env['warden'].manager.should_receive(:_run_callbacks).at_least(:once)
381
381
  env['warden'].authenticate(:pass)
382
382
  valid_response
383
383
  end
@@ -386,7 +386,7 @@ describe Warden::Proxy do
386
386
 
387
387
  it "should run the callbacks by default" do
388
388
  app = lambda do |env|
389
- env['warden'].manager.should_receive(:_run_callbacks)
389
+ env['warden'].manager.should_receive(:_run_callbacks).at_least(:once)
390
390
  env['warden'].authenticate(:pass)
391
391
  valid_response
392
392
  end
@@ -394,6 +394,26 @@ describe Warden::Proxy do
394
394
  end
395
395
  end
396
396
 
397
+ describe "lock" do
398
+ it "should not run any strategy" do
399
+ app = lambda do |env|
400
+ env['warden'].lock!
401
+ env['warden'].authenticate(:pass)
402
+ env['warden'].user.should be_nil
403
+ valid_response
404
+ end
405
+ end
406
+
407
+ it "should keep already authenticated users" do
408
+ app = lambda do |env|
409
+ env['warden'].authenticate(:pass)
410
+ env['warden'].lock!
411
+ env['warden'].user.should be
412
+ valid_response
413
+ end
414
+ end
415
+ end
416
+
397
417
  describe "get user" do
398
418
  before(:each) do
399
419
  @env['rack.session'] ||= {}
@@ -417,6 +437,16 @@ describe Warden::Proxy do
417
437
  setup_rack(app).call(@env)
418
438
  end
419
439
 
440
+ it "should cache unfound user" do
441
+ Warden::SessionSerializer.any_instance.should_receive(:fetch).once
442
+ app = lambda do |env|
443
+ env['warden'].user.should be_nil
444
+ env['warden'].user.should be_nil
445
+ valid_response
446
+ end
447
+ setup_rack(app).call(@env)
448
+ end
449
+
420
450
  describe "previously logged in" do
421
451
  before(:each) do
422
452
  @env['rack.session']['warden.user.default.key'] = "A Previous User"
@@ -431,6 +461,16 @@ describe Warden::Proxy do
431
461
  setup_rack(app).call(@env)
432
462
  end
433
463
 
464
+ it "should cache found user" do
465
+ Warden::SessionSerializer.any_instance.should_receive(:fetch).once.and_return "A Previous User"
466
+ app = lambda do |env|
467
+ env['warden'].user.should == "A Previous User"
468
+ env['warden'].user.should == "A Previous User"
469
+ valid_response
470
+ end
471
+ setup_rack(app).call(@env)
472
+ end
473
+
434
474
  it "should not run strategies when the user exists in the session" do
435
475
  app = lambda do |env|
436
476
  env['warden'].authenticate!(:pass)
@@ -452,7 +492,7 @@ describe Warden::Proxy do
452
492
 
453
493
  it "should call run_callbacks when we pass a :run_callback => true" do
454
494
  app = lambda do |env|
455
- env['warden'].manager.should_receive(:_run_callbacks)
495
+ env['warden'].manager.should_receive(:_run_callbacks).at_least(:once)
456
496
  env['warden'].user(:run_callbacks => true)
457
497
  valid_response
458
498
  end
@@ -461,7 +501,7 @@ describe Warden::Proxy do
461
501
 
462
502
  it "should call run_callbacks by default" do
463
503
  app = lambda do |env|
464
- env['warden'].manager.should_receive(:_run_callbacks)
504
+ env['warden'].manager.should_receive(:_run_callbacks).at_least(:once)
465
505
  env['warden'].user
466
506
  valid_response
467
507
  end
@@ -2,8 +2,6 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  describe Warden::Test::Helpers do
5
- include Warden::Test::Helpers
6
-
7
5
  before{ $captures = [] }
8
6
  after{ Warden.test_reset! }
9
7
 
data/warden.gemspec CHANGED
@@ -6,7 +6,6 @@ Gem::Specification.new do |s|
6
6
  s.name = %q{warden}
7
7
  s.version = Warden::VERSION.dup
8
8
  s.authors = ["Daniel Neighman"]
9
- s.date = %q{2011-07-27}
10
9
  s.email = %q{has.sox@gmail.com}
11
10
  s.extra_rdoc_files = [
12
11
  "LICENSE",
metadata CHANGED
@@ -1,35 +1,48 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: warden
3
- version: !ruby/object:Gem::Version
4
- version: 1.2.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
5
  prerelease:
6
+ segments:
7
+ - 1
8
+ - 2
9
+ - 1
10
+ version: 1.2.1
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Daniel Neighman
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2011-07-27 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-06-16 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
15
22
  name: rack
16
- requirement: &2156244180 !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
17
25
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '1.0'
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 15
30
+ segments:
31
+ - 1
32
+ - 0
33
+ version: "1.0"
22
34
  type: :runtime
23
- prerelease: false
24
- version_requirements: *2156244180
35
+ version_requirements: *id001
25
36
  description:
26
37
  email: has.sox@gmail.com
27
38
  executables: []
39
+
28
40
  extensions: []
29
- extra_rdoc_files:
41
+
42
+ extra_rdoc_files:
30
43
  - LICENSE
31
44
  - README.textile
32
- files:
45
+ files:
33
46
  - Gemfile
34
47
  - History.rdoc
35
48
  - lib/warden/config.rb
@@ -69,30 +82,39 @@ files:
69
82
  - spec/warden/test/helpers_spec.rb
70
83
  - spec/warden/test/test_mode_spec.rb
71
84
  - warden.gemspec
85
+ has_rdoc: true
72
86
  homepage: http://github.com/hassox/warden
73
87
  licenses: []
88
+
74
89
  post_install_message:
75
- rdoc_options:
90
+ rdoc_options:
76
91
  - --charset=UTF-8
77
- require_paths:
92
+ require_paths:
78
93
  - lib
79
- required_ruby_version: !ruby/object:Gem::Requirement
94
+ required_ruby_version: !ruby/object:Gem::Requirement
80
95
  none: false
81
- requirements:
82
- - - ! '>='
83
- - !ruby/object:Gem::Version
84
- version: '0'
85
- required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
104
  none: false
87
- requirements:
88
- - - ! '>='
89
- - !ruby/object:Gem::Version
90
- version: '0'
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 3
109
+ segments:
110
+ - 0
111
+ version: "0"
91
112
  requirements: []
113
+
92
114
  rubyforge_project: warden
93
- rubygems_version: 1.8.15
115
+ rubygems_version: 1.5.3
94
116
  signing_key:
95
117
  specification_version: 3
96
118
  summary: Rack middleware that provides authentication for rack applications
97
119
  test_files: []
98
- has_rdoc:
120
+