Major refactoring. Allow Warden::Manager to be configured through Devise, undeprecate Devise.confirm_within, Devise.pepper and friends and move Rails hooks to their own file.
This commit is contained in:
parent
dc86a571ae
commit
371a9bb0d0
|
@ -2,7 +2,6 @@
|
|||
* Notifier is deprecated, use DeviseMailer instead. Remember to rename
|
||||
app/views/notifier to app/views/devise_mailer and I18n key from
|
||||
devise.notifier to devise.mailer
|
||||
* Model configuration is on Devise::Models.config and not on Devise.config anymore.
|
||||
|
||||
* enhancement
|
||||
* [#16] Allow devise to be more agnostic. Do not require ActiveRecord to be loaded.
|
||||
|
|
|
@ -8,27 +8,50 @@ module Devise
|
|||
:confirmations => :confirmable
|
||||
}.freeze
|
||||
|
||||
STRATEGIES = [:rememberable, :authenticatable].freeze
|
||||
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].freeze
|
||||
end
|
||||
|
||||
# Devise initialization process goes like this:
|
||||
#
|
||||
# 1) Includes in Devise::ActiveRecord and Devise::Migrations
|
||||
# 2) Load and config warden
|
||||
# 3) Load devise mapping structure
|
||||
# 4) Add routes extensions
|
||||
# 5) Load routes definitions
|
||||
# 6) Include filters and helpers in controllers and views
|
||||
#
|
||||
Rails.configuration.after_initialize do
|
||||
if defined?(ActiveRecord)
|
||||
ActiveRecord::Base.extend Devise::Models
|
||||
ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Devise::Migrations
|
||||
class << self
|
||||
# Default way to setup Devise. Run script/generate devise_install to create
|
||||
# a fresh initializer with all configuration values.
|
||||
def setup
|
||||
yield self
|
||||
end
|
||||
|
||||
I18n.load_path.unshift File.expand_path(File.join(File.dirname(__FILE__), 'devise', 'locales', 'en.yml'))
|
||||
# Sets the sender in DeviseMailer.
|
||||
def mail_sender=(value)
|
||||
DeviseMailer.sender = value
|
||||
end
|
||||
alias :sender= :mail_sender=
|
||||
|
||||
# Sets warden configuration using a block that will be invoked on warden
|
||||
# initialization.
|
||||
#
|
||||
# Devise.initialize do |config|
|
||||
# config.confirm_within = 2.days
|
||||
#
|
||||
# config.warden do |manager|
|
||||
# # Configure warden to use other strategies, like oauth.
|
||||
# manager.oauth(:twitter)
|
||||
# end
|
||||
# end
|
||||
def warden(&block)
|
||||
@warden_config = block
|
||||
end
|
||||
|
||||
# A method used internally to setup warden manager from the Rails initialize
|
||||
# block.
|
||||
def configure_warden_manager(manager) #:nodoc:
|
||||
manager.default_strategies *Devise::STRATEGIES
|
||||
manager.failure_app = Devise::Failure
|
||||
manager.silence_missing_strategies!
|
||||
|
||||
# If the user provided a warden hook, call it now.
|
||||
@warden_config.try :call, manager
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'devise/warden'
|
||||
require 'devise/mapping'
|
||||
require 'devise/routes'
|
||||
require 'devise/rails'
|
||||
|
|
|
@ -9,8 +9,11 @@ module Devise
|
|||
def self.call(env)
|
||||
options = env['warden.options']
|
||||
scope = options[:scope]
|
||||
params = if env['warden'].try(:message)
|
||||
params = case env['warden'].try(:message)
|
||||
when Symbol
|
||||
{ env['warden'].message => true }
|
||||
when String
|
||||
{ :message => env['warden'].message }
|
||||
else
|
||||
options[:params]
|
||||
end
|
||||
|
|
|
@ -26,13 +26,6 @@ module Devise
|
|||
string :password_salt, :limit => 20, :null => null
|
||||
end
|
||||
|
||||
# TODO Remove me in a next release.
|
||||
#
|
||||
def authenticable(*args)
|
||||
ActiveSupport::Deprecation.warn "authenticable in migrations is deprecated, use authenticatable instead"
|
||||
authenticatable(*args)
|
||||
end
|
||||
|
||||
# Creates confirmation_token, confirmed_at and confirmation_sent_at.
|
||||
#
|
||||
def confirmable
|
||||
|
|
|
@ -6,7 +6,7 @@ module Devise
|
|||
#
|
||||
# The line above creates:
|
||||
#
|
||||
# 1) An accessor called Devise::Models.stretches, which value is used by default;
|
||||
# 1) An accessor called Devise.stretches, which value is used by default;
|
||||
#
|
||||
# 2) Some class methods for your model Model.stretches and Model.stretches=
|
||||
# which have higher priority than Devise.stretches;
|
||||
|
@ -17,17 +17,8 @@ module Devise
|
|||
# inside the given class.
|
||||
#
|
||||
def self.config(mod, accessor, default=nil) #:nodoc:
|
||||
mattr_accessor accessor
|
||||
send(:"#{accessor}=", default)
|
||||
|
||||
# TODO Remove me in a next release
|
||||
Devise.class_eval <<-METHOD, __FILE__, __LINE__
|
||||
def self.#{accessor}=(value)
|
||||
ActiveSupport::Deprecation.warn "Devise.#{accessor}= is deprecated, " <<
|
||||
"use Devise::Models.#{accessor}= instead."
|
||||
Devise::Models.#{accessor} = value
|
||||
end
|
||||
METHOD
|
||||
Devise.send :mattr_accessor, accessor
|
||||
Devise.send :"#{accessor}=", default
|
||||
|
||||
mod.class_eval <<-METHOD, __FILE__, __LINE__
|
||||
def #{accessor}
|
||||
|
@ -42,7 +33,7 @@ module Devise
|
|||
elsif superclass.respond_to?(:#{accessor})
|
||||
superclass.#{accessor}
|
||||
else
|
||||
Devise::Models.#{accessor}
|
||||
Devise.#{accessor}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -111,13 +102,6 @@ module Devise
|
|||
def devise(*modules)
|
||||
options = modules.extract_options!
|
||||
|
||||
# TODO Remove me in a next release
|
||||
if modules.include?(:authenticable)
|
||||
modules.delete(:authenticable)
|
||||
modules.unshift(:authenticatable)
|
||||
ActiveSupport::Deprecation.warn "devise :authenticate is deprecated, use authenticatable instead"
|
||||
end
|
||||
|
||||
modules = Devise::ALL if modules.include?(:all)
|
||||
modules -= Array(options.delete(:except))
|
||||
modules = [:authenticatable] | modules
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
require 'devise/rails/routes'
|
||||
require 'devise/rails/warden_compat'
|
||||
|
||||
Rails.configuration.after_initialize do
|
||||
if defined?(ActiveRecord)
|
||||
ActiveRecord::Base.extend Devise::Models
|
||||
ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Devise::Migrations
|
||||
end
|
||||
|
||||
# Adds Warden Manager to Rails middleware stack, configuring default devise
|
||||
# strategy and also the failure app.
|
||||
Rails.configuration.middleware.use Warden::Manager do |manager|
|
||||
Devise.configure_warden_manager(manager)
|
||||
end
|
||||
|
||||
I18n.load_path.unshift File.expand_path(File.join(File.dirname(__FILE__), 'locales', 'en.yml'))
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
# Taken from RailsWarden, thanks to Hassox. http://github.com/hassox/rails_warden
|
||||
module Warden::Mixins::Common
|
||||
# Gets the rails request object by default if it's available
|
||||
def request
|
||||
return @request if @request
|
||||
if env['action_controller.rescue.request']
|
||||
@request = env['action_controller.rescue.request']
|
||||
else
|
||||
Rack::Request.new(env)
|
||||
end
|
||||
end
|
||||
|
||||
def raw_session
|
||||
request.session
|
||||
end
|
||||
|
||||
def reset_session!
|
||||
raw_session.inspect # why do I have to inspect it to get it to clear?
|
||||
raw_session.clear
|
||||
end
|
||||
|
||||
# Proxy to request cookies
|
||||
def cookies
|
||||
request.cookies
|
||||
end
|
||||
end
|
|
@ -5,33 +5,6 @@ rescue
|
|||
require 'warden'
|
||||
end
|
||||
|
||||
# Taken from RailsWarden, thanks to Hassox. http://github.com/hassox/rails_warden
|
||||
module Warden::Mixins::Common
|
||||
# Gets the rails request object by default if it's available
|
||||
def request
|
||||
return @request if @request
|
||||
if env['action_controller.rescue.request']
|
||||
@request = env['action_controller.rescue.request']
|
||||
else
|
||||
Rack::Request.new(env)
|
||||
end
|
||||
end
|
||||
|
||||
def raw_session
|
||||
request.session
|
||||
end
|
||||
|
||||
def reset_session!
|
||||
raw_session.inspect # why do I have to inspect it to get it to clear?
|
||||
raw_session.clear
|
||||
end
|
||||
|
||||
# Proxy to request cookies
|
||||
def cookies
|
||||
request.cookies
|
||||
end
|
||||
end
|
||||
|
||||
# Session Serialization in. This block determines how the user will be stored
|
||||
# in the session. If you're using a complex object like an ActiveRecord model,
|
||||
# it is not a good idea to store the complete object. An ID is sufficient.
|
||||
|
@ -43,19 +16,5 @@ Warden::Manager.serialize_from_session do |klass, id|
|
|||
klass.find(id)
|
||||
end
|
||||
|
||||
# Be a good citizen and always set the controller action, even if Devise is
|
||||
# never calling the failure app through warden.
|
||||
Warden::Manager.before_failure do |env, opts|
|
||||
env['warden'].request.params['action'] = 'new'
|
||||
end
|
||||
|
||||
# Setup devise strategies for Warden
|
||||
require 'devise/strategies/base'
|
||||
|
||||
# Adds Warden Manager to Rails middleware stack, configuring default devise
|
||||
# strategy and also the controller who will manage not authenticated users.
|
||||
Rails.configuration.middleware.use Warden::Manager do |manager|
|
||||
manager.default_strategies :rememberable, :authenticatable
|
||||
manager.failure_app = Devise::Failure
|
||||
manager.silence_missing_strategies!
|
||||
end
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
require 'test/test_helper'
|
||||
|
||||
module Devise
|
||||
def self.clean_warden_config!
|
||||
@warden_config = nil
|
||||
end
|
||||
end
|
||||
|
||||
class DeviseTest < ActiveSupport::TestCase
|
||||
class MockManager
|
||||
attr_accessor :failure_app
|
||||
attr_reader :default_strategies, :silence_missing_strategies
|
||||
|
||||
def silence_missing_strategies!
|
||||
@silence_missing_strategies = true
|
||||
end
|
||||
|
||||
def default_strategies(*args)
|
||||
if args.empty?
|
||||
@default_strategies
|
||||
else
|
||||
@default_strategies = args
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test 'DeviseMailer.sender can be configured through Devise' do
|
||||
swap DeviseMailer, :sender => "foo@bar" do
|
||||
assert_equal "foo@bar", DeviseMailer.sender
|
||||
Devise.mail_sender = "bar@foo"
|
||||
assert_equal "bar@foo", DeviseMailer.sender
|
||||
end
|
||||
end
|
||||
|
||||
test 'model options can be configured through Devise' do
|
||||
swap Devise, :confirm_within => 113, :pepper => "foo" do
|
||||
assert_equal 113, Devise.confirm_within
|
||||
assert_equal "foo", Devise.pepper
|
||||
end
|
||||
end
|
||||
|
||||
test 'setup block yields self' do
|
||||
Devise.setup do |config|
|
||||
assert_equal Devise, config
|
||||
end
|
||||
end
|
||||
|
||||
test 'warden manager configuration' do
|
||||
manager = MockManager.new
|
||||
Devise.configure_warden_manager(manager)
|
||||
|
||||
assert_equal Devise::Failure, manager.failure_app
|
||||
assert_equal [:rememberable, :authenticatable], manager.default_strategies
|
||||
assert manager.silence_missing_strategies
|
||||
end
|
||||
|
||||
test 'warden manager user configuration through a block' do
|
||||
begin
|
||||
@executed = false
|
||||
Devise.warden do |manager|
|
||||
@executed = true
|
||||
assert_kind_of MockManager, manager
|
||||
end
|
||||
|
||||
manager = MockManager.new
|
||||
Devise.configure_warden_manager(manager)
|
||||
assert @executed
|
||||
ensure
|
||||
Devise.clean_warden_config!
|
||||
end
|
||||
end
|
||||
end
|
|
@ -59,7 +59,7 @@ class ConfirmationTest < ActionController::IntegrationTest
|
|||
end
|
||||
|
||||
test 'not confirmed user and setup to block without confirmation should not be able to sign in' do
|
||||
Devise::Models.confirm_within = 0
|
||||
Devise.confirm_within = 0
|
||||
user = sign_in_as_user(:confirm => false)
|
||||
|
||||
assert_redirected_to new_user_session_path(:unconfirmed => true)
|
||||
|
@ -67,7 +67,7 @@ class ConfirmationTest < ActionController::IntegrationTest
|
|||
end
|
||||
|
||||
test 'not confirmed user but configured with some days to confirm should be able to sign in' do
|
||||
Devise::Models.confirm_within = 1
|
||||
Devise.confirm_within = 1
|
||||
user = sign_in_as_user(:confirm => false)
|
||||
|
||||
assert_response :success
|
||||
|
|
|
@ -3,7 +3,7 @@ require 'test/test_helper'
|
|||
class RememberMeTest < ActionController::IntegrationTest
|
||||
|
||||
def create_user_and_remember(add_to_token='')
|
||||
Devise::Models.remember_for = 1
|
||||
Devise.remember_for = 1
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
cookies['remember_token'] = User.serialize_into_cookie(user) + add_to_token
|
||||
|
@ -39,7 +39,7 @@ class RememberMeTest < ActionController::IntegrationTest
|
|||
|
||||
test 'do not remember with token expired' do
|
||||
user = create_user_and_remember
|
||||
Devise::Models.remember_for = 0
|
||||
Devise.remember_for = 0
|
||||
get users_path
|
||||
assert_response :success
|
||||
assert_not warden.authenticated?(:user)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require 'test/test_helper'
|
||||
|
||||
class MapTest < ActiveSupport::TestCase
|
||||
class MappingTest < ActiveSupport::TestCase
|
||||
|
||||
test 'store options' do
|
||||
mapping = Devise.mappings[:user]
|
||||
|
|
|
@ -66,28 +66,28 @@ class AuthenticatableTest < ActiveSupport::TestCase
|
|||
|
||||
test 'should fallback to devise pepper default configuring' do
|
||||
begin
|
||||
Devise::Models.pepper = ''
|
||||
Devise.pepper = ''
|
||||
user = new_user
|
||||
assert_equal encrypt_password(user), user.encrypted_password
|
||||
Devise::Models.pepper = 'new_pepper'
|
||||
Devise.pepper = 'new_pepper'
|
||||
user = new_user
|
||||
assert_equal encrypt_password(user, 'new_pepper'), user.encrypted_password
|
||||
Devise::Models.pepper = '123456'
|
||||
Devise.pepper = '123456'
|
||||
user = new_user
|
||||
assert_equal encrypt_password(user, '123456'), user.encrypted_password
|
||||
ensure
|
||||
Devise::Models.pepper = nil
|
||||
Devise.pepper = nil
|
||||
end
|
||||
end
|
||||
|
||||
test 'should fallback to devise stretches default configuring' do
|
||||
begin
|
||||
default_stretches = Devise::Models.stretches
|
||||
Devise::Models.stretches = 1
|
||||
default_stretches = Devise.stretches
|
||||
Devise.stretches = 1
|
||||
user = new_user
|
||||
assert_equal encrypt_password(user, nil, nil), user.encrypted_password
|
||||
ensure
|
||||
Devise::Models.stretches = default_stretches
|
||||
Devise.stretches = default_stretches
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -179,20 +179,20 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|||
|
||||
test 'confirm time should fallback to devise confirm in default configuration' do
|
||||
begin
|
||||
confirm_within = Devise::Models.confirm_within
|
||||
Devise::Models.confirm_within = 1.day
|
||||
confirm_within = Devise.confirm_within
|
||||
Devise.confirm_within = 1.day
|
||||
user = new_user
|
||||
user.confirmation_sent_at = 2.days.ago
|
||||
assert_not user.active?
|
||||
Devise::Models.confirm_within = 3.days
|
||||
Devise.confirm_within = 3.days
|
||||
assert user.active?
|
||||
ensure
|
||||
Devise::Models.confirm_within = confirm_within
|
||||
Devise.confirm_within = confirm_within
|
||||
end
|
||||
end
|
||||
|
||||
test 'should be active when confirmation sent at is not overpast' do
|
||||
Devise::Models.confirm_within = 5.days
|
||||
Devise.confirm_within = 5.days
|
||||
user = create_user
|
||||
user.confirmation_sent_at = 4.days.ago
|
||||
assert user.active?
|
||||
|
@ -208,21 +208,21 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
test 'should not be active when confirmation was sent within the limit' do
|
||||
Devise::Models.confirm_within = 5.days
|
||||
Devise.confirm_within = 5.days
|
||||
user = create_user
|
||||
user.confirmation_sent_at = 5.days.ago
|
||||
assert_not user.active?
|
||||
end
|
||||
|
||||
test 'should be active when confirm in is zero' do
|
||||
Devise::Models.confirm_within = 0.days
|
||||
Devise.confirm_within = 0.days
|
||||
user = create_user
|
||||
user.confirmation_sent_at = Date.today
|
||||
assert_not user.active?
|
||||
end
|
||||
|
||||
test 'should not be active when confirmation was sent before confirm in time' do
|
||||
Devise::Models.confirm_within = 4.days
|
||||
Devise.confirm_within = 4.days
|
||||
user = create_user
|
||||
user.confirmation_sent_at = 5.days.ago
|
||||
assert_not user.active?
|
||||
|
|
|
@ -3,7 +3,7 @@ require 'test/test_helper'
|
|||
class RememberableTest < ActiveSupport::TestCase
|
||||
|
||||
def setup
|
||||
Devise::Models.remember_for = 1
|
||||
Devise.remember_for = 1
|
||||
end
|
||||
|
||||
test 'should respond to remember_me attribute' do
|
||||
|
@ -83,37 +83,37 @@ class RememberableTest < ActiveSupport::TestCase
|
|||
|
||||
test 'remember for should fallback to devise remember for default configuration' do
|
||||
begin
|
||||
remember_for = Devise::Models.remember_for
|
||||
remember_for = Devise.remember_for
|
||||
user = create_user
|
||||
Devise::Models.remember_for = 1.day
|
||||
Devise.remember_for = 1.day
|
||||
user.remember_me!
|
||||
assert_not user.remember_expired?
|
||||
Devise::Models.remember_for = 0.days
|
||||
Devise.remember_for = 0.days
|
||||
user.remember_me!
|
||||
assert user.remember_expired?
|
||||
ensure
|
||||
Devise::Models.remember_for = remember_for
|
||||
Devise.remember_for = remember_for
|
||||
end
|
||||
end
|
||||
|
||||
test 'remember expires at should sum date of creation with remember for configuration' do
|
||||
Devise::Models.remember_for = 3.days
|
||||
Devise.remember_for = 3.days
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
assert_equal 3.days.from_now.to_date, user.remember_expires_at.to_date
|
||||
Devise::Models.remember_for = 5.days
|
||||
Devise.remember_for = 5.days
|
||||
assert_equal 5.days.from_now.to_date, user.remember_expires_at.to_date
|
||||
end
|
||||
|
||||
test 'remember should be expired if remember_for is zero' do
|
||||
Devise::Models.remember_for = 0.days
|
||||
Devise.remember_for = 0.days
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
assert user.remember_expired?
|
||||
end
|
||||
|
||||
test 'remember should be expired if it was created before limit time' do
|
||||
Devise::Models.remember_for = 1.day
|
||||
Devise.remember_for = 1.day
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
user.update_attribute(:remember_created_at, 2.days.ago)
|
||||
|
@ -121,7 +121,7 @@ class RememberableTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
test 'remember should not be expired if it was created whitin the limit time' do
|
||||
Devise::Models.remember_for = 30.days
|
||||
Devise.remember_for = 30.days
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
user.update_attribute(:remember_created_at, 30.days.ago + 2.minutes)
|
||||
|
|
|
@ -33,4 +33,19 @@ class ActiveSupport::TestCase
|
|||
def create_user(attributes={})
|
||||
User.create!(valid_attributes(attributes))
|
||||
end
|
||||
|
||||
# Execute the block setting the given values and restoring old values after
|
||||
# the block is executed.
|
||||
def swap(object, new_values)
|
||||
old_values = {}
|
||||
new_values.each do |key, value|
|
||||
old_values[key] = object.send key
|
||||
object.send :"#{key}=", value
|
||||
end
|
||||
yield
|
||||
ensure
|
||||
old_values.each do |key, value|
|
||||
object.send :"#{key}=", value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue