2009-11-16 11:58:14 -05:00
|
|
|
module Devise
|
2010-09-21 04:50:01 -04:00
|
|
|
# Devise::TestHelpers provides a facility to test controllers in isolation
|
|
|
|
# when using ActionController::TestCase allowing you to quickly sign_in or
|
2011-02-06 10:34:31 -05:00
|
|
|
# sign_out a user. Do not use Devise::TestHelpers in integration tests.
|
2010-09-21 04:50:01 -04:00
|
|
|
#
|
|
|
|
# Notice you should not test Warden specific behavior (like Warden callbacks)
|
|
|
|
# using Devise::TestHelpers since it is a stub of the actual behavior. Such
|
|
|
|
# callbacks should be tested in your integration suite instead.
|
2009-11-16 11:58:14 -05:00
|
|
|
module TestHelpers
|
|
|
|
def self.included(base)
|
|
|
|
base.class_eval do
|
|
|
|
setup :setup_controller_for_warden, :warden if respond_to?(:setup)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-04-17 13:37:19 -04:00
|
|
|
# Override process to consider warden.
|
|
|
|
def process(*)
|
2012-01-02 20:09:49 -05:00
|
|
|
# Make sure we always return @response, a la ActionController::TestCase::Behaviour#process, even if warden interrupts
|
|
|
|
_catch_warden { super } || @response
|
2009-11-16 11:58:14 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# We need to setup the environment variables and the response in the controller.
|
|
|
|
def setup_controller_for_warden #:nodoc:
|
2010-02-16 11:00:36 -05:00
|
|
|
@request.env['action_controller.instance'] = @controller
|
2009-11-16 11:58:14 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Quick access to Warden::Proxy.
|
|
|
|
def warden #:nodoc:
|
2011-04-17 13:37:19 -04:00
|
|
|
@warden ||= begin
|
|
|
|
manager = Warden::Manager.new(nil) do |config|
|
|
|
|
config.merge! Devise.warden_config
|
|
|
|
end
|
|
|
|
@request.env['warden'] = Warden::Proxy.new(@request.env, manager)
|
|
|
|
end
|
2009-11-16 11:58:14 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# sign_in a given resource by storing its keys in the session.
|
2010-09-21 04:50:01 -04:00
|
|
|
# This method bypass any warden authentication callback.
|
2009-11-16 11:58:14 -05:00
|
|
|
#
|
|
|
|
# Examples:
|
|
|
|
#
|
|
|
|
# sign_in :user, @user # sign_in(scope, resource)
|
|
|
|
# sign_in @user # sign_in(resource)
|
|
|
|
#
|
|
|
|
def sign_in(resource_or_scope, resource=nil)
|
2009-11-16 12:07:01 -05:00
|
|
|
scope ||= Devise::Mapping.find_scope!(resource_or_scope)
|
2009-11-16 11:58:14 -05:00
|
|
|
resource ||= resource_or_scope
|
2010-01-14 07:38:02 -05:00
|
|
|
warden.session_serializer.store(resource, scope)
|
2009-11-16 11:58:14 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Sign out a given resource or scope by calling logout on Warden.
|
2010-09-21 04:50:01 -04:00
|
|
|
# This method bypass any warden logout callback.
|
2009-11-16 11:58:14 -05:00
|
|
|
#
|
|
|
|
# Examples:
|
|
|
|
#
|
|
|
|
# sign_out :user # sign_out(scope)
|
|
|
|
# sign_out @user # sign_out(resource)
|
|
|
|
#
|
|
|
|
def sign_out(resource_or_scope)
|
2009-11-16 12:07:01 -05:00
|
|
|
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
2009-12-14 16:48:15 -05:00
|
|
|
@controller.instance_variable_set(:"@current_#{scope}", nil)
|
2010-09-21 04:50:01 -04:00
|
|
|
user = warden.instance_variable_get(:@users).delete(scope)
|
|
|
|
warden.session_serializer.delete(scope, user)
|
2009-11-16 11:58:14 -05:00
|
|
|
end
|
|
|
|
|
2011-04-17 13:37:19 -04:00
|
|
|
protected
|
|
|
|
|
2012-01-02 20:09:49 -05:00
|
|
|
# Catch warden continuations and handle like the middleware would.
|
|
|
|
# Returns nil when interrupted, otherwise the normal result of the block.
|
2011-04-17 13:37:19 -04:00
|
|
|
def _catch_warden(&block)
|
|
|
|
result = catch(:warden, &block)
|
|
|
|
|
|
|
|
if result.is_a?(Hash) && !warden.custom_failure? && !@controller.send(:performed?)
|
|
|
|
result[:action] ||= :unauthenticated
|
|
|
|
|
|
|
|
env = @controller.request.env
|
|
|
|
env["PATH_INFO"] = "/#{result[:action]}"
|
|
|
|
env["warden.options"] = result
|
|
|
|
Warden::Manager._run_callbacks(:before_failure, env, result)
|
|
|
|
|
|
|
|
status, headers, body = Devise.warden_config[:failure_app].call(env).to_a
|
|
|
|
@controller.send :render, :status => status, :text => body,
|
|
|
|
:content_type => headers["Content-Type"], :location => headers["Location"]
|
|
|
|
|
|
|
|
nil
|
|
|
|
else
|
|
|
|
result
|
|
|
|
end
|
|
|
|
end
|
2009-11-16 11:58:14 -05:00
|
|
|
end
|
|
|
|
end
|