mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
Extract Activatable from Confirmable, so if you need to active your account through other means, you can still do so and ensure cherry pick works as expected.
This commit is contained in:
parent
f26e6a269f
commit
e1c2e45f97
16 changed files with 143 additions and 38 deletions
|
@ -1,3 +1,7 @@
|
|||
* enhancements
|
||||
* Extract Activatable from Confirmable
|
||||
* Decouple Serializers from Devise modules
|
||||
|
||||
== 0.7.3
|
||||
|
||||
* bug fix
|
||||
|
|
|
@ -13,6 +13,7 @@ Right now it's composed of seven mainly modules:
|
|||
* Confirmable: responsible for verifying whether an account is already confirmed to sign in, and to send emails with confirmation instructions.
|
||||
* Recoverable: takes care of reseting the user password and send reset instructions.
|
||||
* Rememberable: manages generating and clearing token for remember the user from a saved cookie.
|
||||
* Activatable: if you need to activate accounts by other means, which are not through confirmation, use this module.
|
||||
* Timeoutable: expires sessions without activity in a certain period of time.
|
||||
* Trackable: tracks sign in count, timestamps and ip.
|
||||
* Validatable: creates all needed validations for email and password. It's totally optional, so you're able to to customize validations by yourself.
|
||||
|
|
4
TODO
4
TODO
|
@ -1,3 +1,5 @@
|
|||
* Make test run with different ORMs
|
||||
* Add registerable support
|
||||
* Add http authentication support
|
||||
* Add http authentication support
|
||||
* Extract SessionSerializer tests from Authenticatable
|
||||
* Extract Activatable tests from Confirmable
|
|
@ -1,10 +1,14 @@
|
|||
# Use this hook to configure devise mailer, warden hooks and so forth. The first
|
||||
# four configuration values can also be set straight in your models.
|
||||
Devise.setup do |config|
|
||||
# Configure the frameworks used by default. You should always set this value
|
||||
# because if Devise add a new strategy, it won't be added to your application
|
||||
# Configure Devise modules used by default. You should always set this value
|
||||
# because if Devise adds a new strategy, it won't be added to your application
|
||||
# by default, unless you configure it here.
|
||||
config.all = <%= Devise::ALL.inspect %>
|
||||
#
|
||||
# Remember that Devise includes other modules on its own (like :activatable
|
||||
# and :timeoutable) which are not included here and also plugins. So be sure
|
||||
# to check the docs for a complete set.
|
||||
config.all = [:authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :validatable]
|
||||
|
||||
# Invoke `rake secret` and use the printed value to setup a pepper to generate
|
||||
# the encrypted password. By default no pepper is used.
|
||||
|
|
|
@ -24,7 +24,7 @@ module Devise
|
|||
autoload :MongoMapper, 'devise/orm/mongo_mapper'
|
||||
end
|
||||
|
||||
ALL = [:authenticatable, :confirmable, :recoverable, :rememberable,
|
||||
ALL = [:authenticatable, :activatable, :confirmable, :recoverable, :rememberable,
|
||||
:timeoutable, :trackable, :validatable]
|
||||
|
||||
# Maps controller names to devise modules
|
||||
|
@ -38,9 +38,8 @@ module Devise
|
|||
SERIALIZERS = [:session, :cookie]
|
||||
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
|
||||
|
||||
# Maps the messages types that are used in flash message. This array is not
|
||||
# frozen, so you can add messages from your own strategies.
|
||||
FLASH_MESSAGES = [ :unauthenticated, :unconfirmed, :invalid, :timeout ]
|
||||
# Maps the messages types that are used in flash message.
|
||||
FLASH_MESSAGES = [ :unauthenticated, :unconfirmed, :invalid, :timeout, :inactive ]
|
||||
|
||||
# Declare encryptors length which are used in migrations.
|
||||
ENCRYPTORS_LENGTH = {
|
||||
|
@ -51,6 +50,9 @@ module Devise
|
|||
:authlogic_sha512 => 128
|
||||
}
|
||||
|
||||
# Email regex used to validate email formats. Retrieved from authlogic.
|
||||
EMAIL_REGEX = /\A[\w\.%\+\-]+@(?:[A-Z0-9\-]+\.)+(?:[A-Z]{2,4}|museum|travel)\z/i
|
||||
|
||||
# Used to encrypt password. Please generate one with rake secret.
|
||||
mattr_accessor :pepper
|
||||
@@pepper = nil
|
||||
|
|
|
@ -6,12 +6,13 @@ Warden::Manager.after_set_user do |record, warden, options|
|
|||
if record && record.respond_to?(:active?) && !record.active?
|
||||
scope = options[:scope]
|
||||
warden.logout(scope)
|
||||
|
||||
# If winning strategy was set, this is being called after authenticate and
|
||||
# there is no need to force a redirect.
|
||||
if warden.winning_strategy
|
||||
# If winning strategy was set, this is being called after authenticate and
|
||||
# there is no need to force a redirect.
|
||||
warden.winning_strategy.fail!(:unconfirmed)
|
||||
warden.winning_strategy.fail!(record.inactive_message)
|
||||
else
|
||||
throw :warden, :scope => scope, :message => :unconfirmed
|
||||
throw :warden, :scope => scope, :message => record.inactive_message
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,6 +7,7 @@ en:
|
|||
unconfirmed: 'You have to confirm your account before continuing.'
|
||||
invalid: 'Invalid email or password.'
|
||||
timeout: 'Your session expired, please sign in again to continue.'
|
||||
inactive: 'Your account was not activated yet.'
|
||||
passwords:
|
||||
send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.'
|
||||
updated: 'Your password was changed successfully. You are now signed in.'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
module Devise
|
||||
module Models
|
||||
autoload :Activatable, 'devise/models/activatable'
|
||||
autoload :Authenticatable, 'devise/models/authenticatable'
|
||||
autoload :Confirmable, 'devise/models/confirmable'
|
||||
autoload :Recoverable, 'devise/models/recoverable'
|
||||
|
@ -81,9 +82,9 @@ module Devise
|
|||
raise "You need to give at least one Devise module" if modules.empty?
|
||||
|
||||
options = modules.extract_options!
|
||||
modules = Devise.all if modules.include?(:all)
|
||||
modules += Devise.all if modules.delete(:all)
|
||||
modules -= Array(options.delete(:except))
|
||||
modules = Devise::ALL & modules
|
||||
modules = Devise::ALL & modules.uniq
|
||||
|
||||
Devise.orm_class.included_modules_hook(self, modules) do
|
||||
modules.each do |m|
|
||||
|
|
16
lib/devise/models/activatable.rb
Normal file
16
lib/devise/models/activatable.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
require 'devise/hooks/activatable'
|
||||
|
||||
module Devise
|
||||
module Models
|
||||
# This module implements the default API required in activatable hook.
|
||||
module Activatable
|
||||
def active?
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def inactive_message
|
||||
:inactive
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
require 'devise/hooks/confirmable'
|
||||
require 'devise/models/activatable'
|
||||
|
||||
module Devise
|
||||
module Models
|
||||
|
@ -29,6 +29,7 @@ module Devise
|
|||
# User.find(1).send_confirmation_instructions # manually send instructions
|
||||
# User.find(1).resend_confirmation! # generates a new token and resent it
|
||||
module Confirmable
|
||||
include Devise::Models::Activatable
|
||||
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
|
@ -70,14 +71,19 @@ module Devise
|
|||
end
|
||||
end
|
||||
|
||||
# Verify whether a user is active to sign in or not. If the user is
|
||||
# already confirmed, it should never be blocked. Otherwise we need to
|
||||
# calculate if the confirm time has not expired for this user, in other
|
||||
# words, if the confirmation is still valid.
|
||||
# Overwrites active? from Devise::Models::Activatable for confirmation
|
||||
# by verifying whether an user is active to sign in or not. If the user
|
||||
# is already confirmed, it should never be blocked. Otherwise we need to
|
||||
# calculate if the confirm time has not expired for this user.
|
||||
def active?
|
||||
confirmed? || confirmation_period_valid?
|
||||
end
|
||||
|
||||
# The message to be shown if the account is inactive.
|
||||
def inactive_message
|
||||
:unconfirmed
|
||||
end
|
||||
|
||||
# If you don't want confirmation to be sent on create, neither a code
|
||||
# to be generated, call skip_confirmation!
|
||||
def skip_confirmation!
|
||||
|
|
|
@ -6,10 +6,6 @@ module Devise
|
|||
# Automatically validate if the email is present, unique and it's format is
|
||||
# valid. Also tests presence of password, confirmation and length
|
||||
module Validatable
|
||||
|
||||
# Email regex used to validate email formats. Retrieved from authlogic.
|
||||
EMAIL_REGEX = /\A[\w\.%\+\-]+@(?:[A-Z0-9\-]+\.)+(?:[A-Z]{2,4}|museum|travel)\z/i
|
||||
|
||||
# All validations used by this module.
|
||||
VALIDATIONS = [ :validates_presence_of, :validates_uniqueness_of, :validates_format_of,
|
||||
:validates_confirmation_of, :validates_length_of ].freeze
|
||||
|
|
|
@ -37,11 +37,11 @@ class Exceptable < User
|
|||
end
|
||||
|
||||
class Configurable < User
|
||||
devise :all, :stretches => 15,
|
||||
:pepper => 'abcdef',
|
||||
:confirm_within => 5.days,
|
||||
:remember_for => 7.days,
|
||||
:timeout_in => 15.minutes
|
||||
devise :all, :timeoutable, :stretches => 15,
|
||||
:pepper => 'abcdef',
|
||||
:confirm_within => 5.days,
|
||||
:remember_for => 7.days,
|
||||
:timeout_in => 15.minutes
|
||||
end
|
||||
|
||||
class ActiveRecordTest < ActiveSupport::TestCase
|
||||
|
@ -60,7 +60,7 @@ class ActiveRecordTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
test 'include by default authenticatable only' do
|
||||
test 'add authenticatable module only' do
|
||||
assert_include_modules Authenticatable, :authenticatable
|
||||
end
|
||||
|
||||
|
@ -90,11 +90,11 @@ class ActiveRecordTest < ActiveSupport::TestCase
|
|||
|
||||
test 'add all modules' do
|
||||
assert_include_modules Devisable,
|
||||
:authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :timeoutable, :validatable
|
||||
:authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :validatable
|
||||
end
|
||||
|
||||
test 'configure modules with except option' do
|
||||
assert_include_modules Exceptable, :authenticatable, :confirmable, :trackable, :timeoutable
|
||||
assert_include_modules Exceptable, :authenticatable, :confirmable, :trackable
|
||||
end
|
||||
|
||||
test 'set a default value for stretches' do
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class Admin < ActiveRecord::Base
|
||||
devise :all, :except => [:recoverable, :confirmable, :rememberable, :validatable, :trackable]
|
||||
devise :all, :timeoutable, :except => [:recoverable, :confirmable, :rememberable, :validatable, :trackable]
|
||||
|
||||
def self.find_for_authentication(conditions)
|
||||
last(:conditions => conditions)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class User < ActiveRecord::Base
|
||||
devise :all
|
||||
devise :all, :timeoutable
|
||||
attr_accessible :username, :email, :password, :password_confirmation
|
||||
end
|
||||
|
|
76
test/rails_app/config/initializers/devise.rb
Normal file
76
test/rails_app/config/initializers/devise.rb
Normal file
|
@ -0,0 +1,76 @@
|
|||
# Use this hook to configure devise mailer, warden hooks and so forth. The first
|
||||
# four configuration values can also be set straight in your models.
|
||||
Devise.setup do |config|
|
||||
# Configure Devise modules used by default. You should always set this value
|
||||
# because if Devise adds a new strategy, it won't be added to your application
|
||||
# by default, unless you configure it here.
|
||||
#
|
||||
# Remember that Devise includes other modules on its own (like :activatable
|
||||
# and :timeoutable) which are not included here and also plugins. So be sure
|
||||
# to check the docs for a complete set.
|
||||
config.all = [:authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :validatable]
|
||||
|
||||
# Invoke `rake secret` and use the printed value to setup a pepper to generate
|
||||
# the encrypted password. By default no pepper is used.
|
||||
# config.pepper = "rake secret output"
|
||||
|
||||
# Configure how many times you want the password is reencrypted. Default is 10.
|
||||
# config.stretches = 10
|
||||
|
||||
# Define which will be the encryption algorithm. Supported algorithms are :sha1
|
||||
# (default) and :sha512. Devise also supports encryptors from others authentication
|
||||
# frameworks as :clearance_sha1, :authlogic_sha512 (then you should set stretches
|
||||
# above to 20 for default behavior) and :restful_authentication_sha1 (then you
|
||||
# should set stretches to 10, and copy REST_AUTH_SITE_KEY to pepper)
|
||||
# config.encryptor = :sha1
|
||||
|
||||
# Configure which keys are used when authenticating an user. By default is
|
||||
# just :email. You can configure it to use [:username, :subdomain], so for
|
||||
# authenticating an user, both parameters are required. Remember that those
|
||||
# parameters are used only when authenticating and not when retrieving from
|
||||
# session. If you need permissions, you should implement that in a before filter.
|
||||
# config.authentication_keys = [ :email ]
|
||||
|
||||
# The time you want give to your user to confirm his account. During this time
|
||||
# he will be able to access your application without confirming. Default is nil.
|
||||
# config.confirm_within = 2.days
|
||||
|
||||
# The time the user will be remembered without asking for credentials again.
|
||||
# config.remember_for = 2.weeks
|
||||
|
||||
# The time you want to timeout the user session without activity. After this
|
||||
# time the user will be asked for credentials again.
|
||||
# config.timeout_in = 10.minutes
|
||||
|
||||
# Configure the e-mail address which will be shown in DeviseMailer.
|
||||
# config.mailer_sender = "foo.bar@yourapp.com"
|
||||
|
||||
# Load and configure the ORM. Supports :active_record, :data_mapper and :mongo_mapper.
|
||||
# require 'devise/orm/mongo_mapper'
|
||||
# config.orm = :mongo_mapper
|
||||
|
||||
# Turn scoped views on. Before rendering "sessions/new", it will first check for
|
||||
# "sessions/users/new". It's turned off by default because it's slower if you
|
||||
# are using only default views.
|
||||
# config.scoped_views = true
|
||||
|
||||
# If you want to use other strategies, that are not (yet) supported by Devise,
|
||||
# you can configure them inside the config.warden block. The example below
|
||||
# allows you to setup OAuth, using http://github.com/roman/warden_oauth
|
||||
#
|
||||
# config.warden do |manager|
|
||||
# manager.oauth(:twitter) do |twitter|
|
||||
# twitter.consumer_secret = <YOUR CONSUMER SECRET>
|
||||
# twitter.consumer_key = <YOUR CONSUMER KEY>
|
||||
# twitter.options :site => 'http://twitter.com'
|
||||
# end
|
||||
# manager.default_strategies.unshift :twitter_oauth
|
||||
# end
|
||||
|
||||
# Configure default_url_options if you are using dynamic segments in :path_prefix
|
||||
# for devise_for.
|
||||
#
|
||||
# config.default_url_options do
|
||||
# { :locale => I18n.locale }
|
||||
# end
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
# Sample localization file for English. Add more files in this directory for other locales.
|
||||
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
|
||||
|
||||
en:
|
||||
hello: "Hello world"
|
Loading…
Reference in a new issue