<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,19 +1,19 @@
 # encoding: utf-8
 module Warden
   class Manager
-    
+
     class &lt;&lt; self
       # A callback hook set to run every time after a user is set.
       # This will happen the first time the user is either authenticated, accessed or manually set
       # during a request.  You can supply as many hooks as you like, and they will be run in order of decleration
-      # 
-      # Parameters: 
+      #
+      # Parameters:
       # &lt;block&gt; A block where you can set arbitrary logic to run every time a user is set
       #   Block Parameters: |user, auth, opts|
       #     user - The user object that is being set
-      #     auth - The raw authentication proxy object.  
+      #     auth - The raw authentication proxy object.
       #     opts - any options passed into the set_user call includeing :scope
-      # 
+      #
       # Example:
       #   Warden::Manager.after_set_user do |user,auth,opts|
       #     scope = opts[:scope]
@@ -29,23 +29,23 @@ module Warden
         raise BlockNotGiven unless block_given?
         _after_set_user &lt;&lt; block
       end
-      
+
       # Provides access to the array of after_set_user blocks to run
       # :api: private
       def _after_set_user # :nodoc:
         @_after_set_user ||= []
       end
-      
-      # A callback hook set to run after the first authentiation of a session.  
+
+      # A callback hook set to run after the first authentiation of a session.
       # This will only happenwhen the session is first authenticated
-      # 
+      #
       # Parameters:
       # &lt;block&gt; A block to contain logic for the callback
       #   Block Parameters: |user, auth, opts|
       #     user - The user object that is being set
-      #     auth - The raw authentication proxy object.  
+      #     auth - The raw authentication proxy object.
       #     opts - any options passed into the authenticate call includeing :scope
-      # 
+      #
       # Example:
       #
       #   Warden::Manager.after_authentication do |user, auth, opts|
@@ -57,18 +57,18 @@ module Warden
         raise BlockNotGiven unless block_given?
         _after_authentication &lt;&lt; block
       end
-      
+
       # Provides access to the array of after_authentication blocks
       # :api: private
       def _after_authentication
         @_after_authentication ||= []
       end
-      
-      # A callback that runs just prior to the failur application being called.  
+
+      # A callback that runs just prior to the failur application being called.
       # This callback occurs after PATH_INFO has been modified for the failure (default /unauthenticated)
       # In this callback you can mutate the environment as required by the failure application
       # If a Rails controller were used for the failure_app for example, you would need to set request[:params][:action] = :unauthenticated
-      # 
+      #
       # Parameters:
       # &lt;block&gt; A block to contain logic for the callback
       #   Block Parameters: |user, auth, opts|
@@ -81,22 +81,22 @@ module Warden
       #     params[:action] = :unauthenticated
       #     params[:warden_failure] = opts
       #   end
-      # 
+      #
       # :api: public
       def before_failure(&amp;block)
         _before_failure &lt;&lt; block
       end
-      
+
       # Provides access to the callback array for before_failure
       # :api: private
       def _before_failure
         @_before_failure ||= []
       end
-      
-      # A callback that runs just after to the failur application being called.  
+
+      # A callback that runs just after to the failure application being called.
       # This callback is primarily included for Rails 2.3 since Rails 2.3 controllers are not pure Rack Applications
       # Return whatever you want to be returned for the actual rack response array
-      # 
+      #
       # Parameters:
       # &lt;block&gt; A block to contain logic for the callback
       #   Block Parameters: |user, auth, opts|
@@ -108,19 +108,44 @@ module Warden
       #   Warden::Manager.after_failure do |result|
       #    result.to_a
       #   end
-      # 
+      #
       # :api: public
       def after_failure(&amp;block)
         _after_failure &lt;&lt; block
       end
-      
+
       # Provides access to the callback array for after_failure
       # :api: private
       def _after_failure
         @_after_failure ||= []
       end
-      
+
+      # A callback that runs just prior to the logout of each scope.
+      #
+      # Parameters:
+      # &lt;block&gt; A block to contain logic for the callback
+      #   Block Parameters: |user, auth, scope|
+      #     user - The authenticated user for the current scope
+      #     auth - The warden proxy object
+      #     scope - current logout scope
+      #
+      # Example:
+      #   Warden::Manager.before_logout do |user, auth, scope|
+      #     user.forget_me!
+      #   end
+      #
+      # :api: public
+      def before_logout(&amp;block)
+        _before_logout &lt;&lt; block
+      end
+
+      # Provides access to the callback array for before_logout
+      # :api: private
+      def _before_logout
+        @_before_logout ||= []
+      end
+
     end
-    
+
   end # Manager
-end # Warden
\ No newline at end of file
+end # Warden</diff>
      <filename>lib/warden/authentication/hooks.rb</filename>
    </modified>
    <modified>
      <diff>@@ -135,10 +135,14 @@ module Warden
     # :api: public
     def logout(*scopes)
       if scopes.empty?
+        # Run before_logout hooks
+        Warden::Manager._before_logout.each{|hook| hook.call(user, self, :default)}
         reset_session!
         @users.clear
       else
         scopes.each do |s|
+          # Run before_logout hooks
+          Warden::Manager._before_logout.each{|hook| hook.call(user(s), self, s)}
           raw_session[&quot;warden.user.#{s}.key&quot;] = nil
           raw_session[&quot;warden.user.#{s}.session&quot;] = nil
           @users.delete(s)</diff>
      <filename>lib/warden/proxy.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,13 +4,16 @@ require 'rack'
 $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
 require 'warden'
 
-Dir[File.join(File.dirname(__FILE__), &quot;warden&quot;, &quot;strategies&quot;, &quot;**/*.rb&quot;)].each do |f|
-  require f
-end
 Dir[File.join(File.dirname(__FILE__), &quot;helpers&quot;, &quot;**/*.rb&quot;)].each do |f|
   require f
 end
 
 Spec::Runner.configure do |config|
   config.include(Warden::Spec::Helpers)
+
+  def load_strategies
+    Dir[File.join(File.dirname(__FILE__), &quot;warden&quot;, &quot;strategies&quot;, &quot;**/*.rb&quot;)].each do |f|
+      require f
+    end
+  end
 end</diff>
      <filename>spec/spec_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,30 +1,34 @@
 require File.dirname(__FILE__) + '/../spec_helper'
 
 describe &quot;standard authentication hooks&quot; do
-  
+
+  before(:all) do
+    load_strategies
+  end
+
   describe &quot;after_set_user&quot; do
     before(:each) do
       RAM = Warden::Manager unless defined?(RAM)
       RAM._after_set_user.clear
     end
-    
+
     after(:each) do
       RAM._after_set_user.clear
     end
-    
+
     it &quot;should allow me to add an after_set_user hook&quot; do
       RAM.after_set_user do |user, auth, opts|
         &quot;boo&quot;
       end
       RAM._after_set_user.should have(1).item
     end
-    
+
     it &quot;should allow me to add multiple after_set_user hooks&quot; do
       RAM.after_set_user{|user, auth, opts| &quot;foo&quot;}
       RAM.after_set_user{|u,a| &quot;bar&quot;}
       RAM._after_set_user.should have(2).items
     end
-    
+
     it &quot;should run each after_set_user hook after the user is set&quot; do
       RAM.after_set_user{|u,a,o| a.env['warden.spec.hook.foo'] = &quot;run foo&quot;}
       RAM.after_set_user{|u,a,o| a.env['warden.spec.hook.bar'] = &quot;run bar&quot;}
@@ -35,28 +39,28 @@ describe &quot;standard authentication hooks&quot; do
       env['warden.spec.hook.bar'].should == &quot;run bar&quot;
     end
   end
-  
-  describe &quot;after_authenticate&quot; do
+
+  describe &quot;after_authentication&quot; do
     before(:each) do
       RAM = Warden::Manager unless defined?(RAM)
       RAM._after_authentication.clear
     end
-    
+
     after(:each) do
       RAM._after_authentication.clear
     end
-    
-    it &quot;should allow me to add an after_authetnication hook&quot; do
+
+    it &quot;should allow me to add an after_authentication hook&quot; do
       RAM.after_authentication{|user, auth, opts| &quot;foo&quot;}
       RAM._after_authentication.should have(1).item
     end
-    
-    it &quot;should allow me to add multiple after_authetnication hooks&quot; do
+
+    it &quot;should allow me to add multiple after_authentication hooks&quot; do
       RAM.after_authentication{|u,a,o| &quot;bar&quot;}
       RAM.after_authentication{|u,a,o| &quot;baz&quot;}
       RAM._after_authentication.should have(2).items
     end
-    
+
     it &quot;should run each after_authentication hook after authentication is run&quot; do
       RAM.after_authentication{|u,a,o| a.env['warden.spec.hook.baz'] = &quot;run baz&quot;}
       RAM.after_authentication{|u,a,o| a.env['warden.spec.hook.paz'] = &quot;run paz&quot;}
@@ -67,28 +71,28 @@ describe &quot;standard authentication hooks&quot; do
       env['warden.spec.hook.paz'].should == 'run paz'
     end
   end
-  
+
   describe &quot;before_failure&quot; do
     before(:each) do
       RAM = Warden::Manager unless defined?(RAM)
       RAM._before_failure.clear
     end
-    
+
     after(:each) do
       RAM._before_failure.clear
     end
-    
+
     it &quot;should allow me to add a before_failure hook&quot; do
       RAM.before_failure{|env, opts| &quot;foo&quot;}
       RAM._before_failure.should have(1).item
     end
-    
+
     it &quot;should allow me to add multiple before_failure hooks&quot; do
       RAM.before_failure{|env, opts| &quot;foo&quot;}
       RAM.before_failure{|env, opts| &quot;bar&quot;}
       RAM._before_failure.should have(2).items
     end
-    
+
     it &quot;should run each before_failure hooks before failing&quot; do
       RAM.before_failure{|e,o| e['warden.spec.before_failure.foo'] = &quot;foo&quot;}
       RAM.before_failure{|e,o| e['warden.spec.before_failure.bar'] = &quot;bar&quot;}
@@ -99,5 +103,52 @@ describe &quot;standard authentication hooks&quot; do
       env['warden.spec.before_failure.bar'].should  == &quot;bar&quot;
     end
   end
-  
-end
\ No newline at end of file
+
+  describe &quot;before_logout&quot; do
+    before(:each) do
+      RAM = Warden::Manager unless defined?(RAM)
+      RAM._before_logout.clear
+    end
+
+    after(:each) do
+      RAM._before_logout.clear
+    end
+
+    it &quot;should allow me to add an before_logout hook&quot; do
+      RAM.before_logout{|user, auth, scopes| &quot;foo&quot;}
+      RAM._before_logout.should have(1).item
+    end
+
+    it &quot;should allow me to add multiple after_authetnication hooks&quot; do
+      RAM.before_logout{|u,a,s| &quot;bar&quot;}
+      RAM.before_logout{|u,a,s| &quot;baz&quot;}
+      RAM._before_logout.should have(2).items
+    end
+
+    it &quot;should run each before_logout hook before logout is run&quot; do
+      RAM.before_logout{|u,a,s| a.env['warden.spec.hook.lorem'] = &quot;run lorem&quot;}
+      RAM.before_logout{|u,a,s| a.env['warden.spec.hook.ipsum'] = &quot;run ipsum&quot;}
+      app = lambda{|e| e['warden'].authenticate(:pass); valid_response}
+      env = env_with_params
+      debugger
+      setup_rack(app).call(env)
+      env['warden'].logout
+      env['warden.spec.hook.lorem'].should == 'run lorem'
+      env['warden.spec.hook.ipsum'].should == 'run ipsum'
+    end
+
+    it &quot;should run before_logout hook on different scopes&quot; do
+      RAM.before_logout{|u,a,s| a.env[&quot;warden.spec.hook.scope1&quot;] = &quot;run scope1&quot; if s == :scope1}
+      RAM.before_logout{|u,a,s| a.env[&quot;warden.spec.hook.scope2&quot;] = &quot;run scope2&quot; if s == :scope2}
+      app = lambda{|e| e['warden'].authenticate(:pass); valid_response}
+      env = env_with_params
+      setup_rack(app).call(env)
+      env['warden'].logout(:scope1)
+      env['warden.spec.hook.scope1'].should == 'run scope1'
+      env['warden.spec.hook.scope2'].should == nil
+      env['warden'].logout(:scope2)
+      env['warden.spec.hook.scope2'].should == 'run scope2'
+    end
+  end
+
+end</diff>
      <filename>spec/warden/hooks_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/../spec_helper'
 describe Warden::Proxy do
 
   before(:all) do
-    Dir[File.join(File.dirname(__FILE__), &quot;strategies/**/*.rb&quot;)].each{|f| load f}
+    load_strategies
   end
 
   before(:each) do</diff>
      <filename>spec/warden/proxy_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>927894063ccfb6907e7db32e5aa3e1a1dfe36215</id>
    </parent>
  </parents>
  <author>
    <name>Carlos A. da Silva</name>
    <email>carlosantoniodasilva@gmail.com</email>
  </author>
  <url>http://github.com/carlosantoniodasilva/warden/commit/876eea52e9a787874572afbc987df400819c12b9</url>
  <id>876eea52e9a787874572afbc987df400819c12b9</id>
  <committed-date>2009-10-20T11:55:54-07:00</committed-date>
  <authored-date>2009-10-19T17:15:55-07:00</authored-date>
  <message>Adding before_logout hook and fixing hook tests.</message>
  <tree>e5d26d0982f69bbc9855978df4a7e3e8baba4db6</tree>
  <committer>
    <name>Jos&#233; Valim</name>
    <email>jose.valim@gmail.com</email>
  </committer>
</commit>
