mirror of
https://github.com/heartcombo/devise.git
synced 2026-01-09 23:58:06 -05:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94e5a589b6 | ||
|
|
2dbb23f973 | ||
|
|
b71028dc73 | ||
|
|
f5aab14766 | ||
|
|
273c5e99c1 | ||
|
|
7ba37b5dc0 | ||
|
|
059d3856cf | ||
|
|
9dbd265fdd | ||
|
|
09ae63f822 | ||
|
|
5a245b3d55 | ||
|
|
7d3b16fe73 | ||
|
|
fd85b25d29 | ||
|
|
5eebf74f69 | ||
|
|
5a11c6597c | ||
|
|
930b324c15 | ||
|
|
d952dea32b | ||
|
|
9a6ac7ab69 | ||
|
|
df43ee640d | ||
|
|
309b57f4ea | ||
|
|
cc839caba5 | ||
|
|
d734648b15 | ||
|
|
006400905b | ||
|
|
1e1e964d25 | ||
|
|
263e0b7692 | ||
|
|
01d4d0131b | ||
|
|
f41e4befde | ||
|
|
94fca31be8 | ||
|
|
19db459fca | ||
|
|
7693173ecd | ||
|
|
a0294cbae8 | ||
|
|
1cf008cbe3 | ||
|
|
87b84ffded | ||
|
|
035e56215d | ||
|
|
fa4d420fdb | ||
|
|
bd27bf7677 | ||
|
|
03d9ebb56e | ||
|
|
113b48a2ad | ||
|
|
6aed8f1c87 | ||
|
|
6d681c5b8a | ||
|
|
b3034292f2 | ||
|
|
7f754caba3 | ||
|
|
8c0f74f036 | ||
|
|
5a820262f9 | ||
|
|
3906456993 | ||
|
|
a1407565c8 | ||
|
|
a7c5a2e65d | ||
|
|
10ac4dbc35 | ||
|
|
6469cbc62a | ||
|
|
1961de6b5d |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -8,5 +8,3 @@ rdoc/*
|
||||
pkg
|
||||
log
|
||||
test/tmp/*
|
||||
Gemfile.lock
|
||||
|
||||
|
||||
@@ -1,8 +1,33 @@
|
||||
== 2.0.0.rc
|
||||
|
||||
Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.0
|
||||
|
||||
* enhancements
|
||||
* Add support for e-mail reconfirmation on change (by github.com/Mandaryn and github.com/heimidal)
|
||||
* Redirect users to sign in page after unlock (by github.com/nashby)
|
||||
|
||||
* deprecation
|
||||
* Devise.apply_schema is deprecated
|
||||
* Devise migration helpers are deprecated
|
||||
* Usage of Devise.remember_across_browsers was deprecated
|
||||
* Usage of Devise.confirm_within was deprecated in favor Devise.allow_unconfirmed_access_for
|
||||
* Usage of rememberable with remember_token was removed
|
||||
* Usage of recoverable without reset_password_sent_at was removed
|
||||
* Usage of Devise.case_insensitive_keys equals to false was removed
|
||||
* Usage of Devise.stateless_token= is deprecated in favor of appending :token_auth to Devise.skip_session_storage
|
||||
|
||||
== 1.5.3
|
||||
|
||||
* bug fix
|
||||
* Ensure delegator converts scope to symbol (by github.com/dmitriy-kiriyenko)
|
||||
* Ensure passing :format => false to devise_for is not permanent
|
||||
* Ensure path checker does not check invalid routes
|
||||
|
||||
== 1.5.2
|
||||
|
||||
* enhancements
|
||||
* Add support for rails 3.1 new mass assignment conventions (by github.com/kirs)
|
||||
* Add timeout_in method to Timeoutable, it can be overriden in a model (by github.com/lest)
|
||||
* Add support for Rails 3.1 new mass assignment conventions (by github.com/kirs)
|
||||
* Add timeout_in method to Timeoutable, it can be overridden in a model (by github.com/lest)
|
||||
|
||||
* bug fix
|
||||
* OmniAuth error message now shows the proper option (:strategy_class instead of :klass)
|
||||
|
||||
168
Gemfile.lock
Normal file
168
Gemfile.lock
Normal file
@@ -0,0 +1,168 @@
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
devise (1.5.2)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
orm_adapter (~> 0.0.3)
|
||||
warden (~> 1.1)
|
||||
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.1.3)
|
||||
actionpack (= 3.1.3)
|
||||
mail (~> 2.3.0)
|
||||
actionpack (3.1.3)
|
||||
activemodel (= 3.1.3)
|
||||
activesupport (= 3.1.3)
|
||||
builder (~> 3.0.0)
|
||||
erubis (~> 2.7.0)
|
||||
i18n (~> 0.6)
|
||||
rack (~> 1.3.5)
|
||||
rack-cache (~> 1.1)
|
||||
rack-mount (~> 0.8.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.0.3)
|
||||
activemodel (3.1.3)
|
||||
activesupport (= 3.1.3)
|
||||
builder (~> 3.0.0)
|
||||
i18n (~> 0.6)
|
||||
activerecord (3.1.3)
|
||||
activemodel (= 3.1.3)
|
||||
activesupport (= 3.1.3)
|
||||
arel (~> 2.2.1)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.1.3)
|
||||
activemodel (= 3.1.3)
|
||||
activesupport (= 3.1.3)
|
||||
activesupport (3.1.3)
|
||||
multi_json (~> 1.0)
|
||||
addressable (2.2.6)
|
||||
arel (2.2.1)
|
||||
bcrypt-ruby (3.0.1)
|
||||
bson (1.5.1)
|
||||
bson_ext (1.3.1)
|
||||
builder (3.0.0)
|
||||
columnize (0.3.5)
|
||||
erubis (2.7.0)
|
||||
faraday (0.7.5)
|
||||
addressable (~> 2.2.6)
|
||||
multipart-post (~> 1.1.3)
|
||||
rack (>= 1.1.0, < 2)
|
||||
hashie (1.2.0)
|
||||
hike (1.2.1)
|
||||
i18n (0.6.0)
|
||||
json (1.6.3)
|
||||
linecache (0.46)
|
||||
rbx-require-relative (> 0.0.4)
|
||||
mail (2.3.0)
|
||||
i18n (>= 0.4.0)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
metaclass (0.0.1)
|
||||
mime-types (1.17.2)
|
||||
mocha (0.10.0)
|
||||
metaclass (~> 0.0.1)
|
||||
mongo (1.3.1)
|
||||
bson (>= 1.3.1)
|
||||
mongoid (2.3.4)
|
||||
activemodel (~> 3.1)
|
||||
mongo (~> 1.3)
|
||||
tzinfo (~> 0.3.22)
|
||||
multi_json (1.0.4)
|
||||
multipart-post (1.1.4)
|
||||
nokogiri (1.5.0)
|
||||
oauth2 (0.5.1)
|
||||
faraday (~> 0.7.4)
|
||||
multi_json (~> 1.0.3)
|
||||
omniauth (1.0.1)
|
||||
hashie (~> 1.2)
|
||||
rack
|
||||
omniauth-facebook (1.0.0)
|
||||
omniauth-oauth2 (~> 1.0.0)
|
||||
omniauth-oauth2 (1.0.0)
|
||||
oauth2 (~> 0.5.0)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-openid (1.0.1)
|
||||
omniauth (~> 1.0)
|
||||
rack-openid (~> 1.3.1)
|
||||
orm_adapter (0.0.5)
|
||||
polyglot (0.3.3)
|
||||
rack (1.3.5)
|
||||
rack-cache (1.1)
|
||||
rack (>= 0.4)
|
||||
rack-mount (0.8.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-openid (1.3.1)
|
||||
rack (>= 1.1.0)
|
||||
ruby-openid (>= 2.1.8)
|
||||
rack-ssl (1.3.2)
|
||||
rack
|
||||
rack-test (0.6.1)
|
||||
rack (>= 1.0)
|
||||
rails (3.1.3)
|
||||
actionmailer (= 3.1.3)
|
||||
actionpack (= 3.1.3)
|
||||
activerecord (= 3.1.3)
|
||||
activeresource (= 3.1.3)
|
||||
activesupport (= 3.1.3)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.1.3)
|
||||
railties (3.1.3)
|
||||
actionpack (= 3.1.3)
|
||||
activesupport (= 3.1.3)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (~> 0.14.6)
|
||||
rake (0.9.2.2)
|
||||
rbx-require-relative (0.0.5)
|
||||
rdoc (3.11)
|
||||
json (~> 1.4)
|
||||
ruby-debug (0.10.4)
|
||||
columnize (>= 0.1)
|
||||
ruby-debug-base (~> 0.10.4.0)
|
||||
ruby-debug-base (0.10.4)
|
||||
linecache (>= 0.3)
|
||||
ruby-openid (2.1.8)
|
||||
sprockets (2.0.3)
|
||||
hike (~> 1.2)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sqlite3 (1.3.5)
|
||||
sqlite3-ruby (1.3.3)
|
||||
sqlite3 (>= 1.3.3)
|
||||
thor (0.14.6)
|
||||
tilt (1.3.3)
|
||||
treetop (1.4.10)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.31)
|
||||
warden (1.1.0)
|
||||
rack (>= 1.0)
|
||||
webrat (0.7.2)
|
||||
nokogiri (>= 1.2.0)
|
||||
rack (>= 1.0)
|
||||
rack-test (>= 0.5.3)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
activerecord-jdbc-adapter
|
||||
activerecord-jdbcsqlite3-adapter
|
||||
bson_ext (~> 1.3.0)
|
||||
devise!
|
||||
jruby-openssl
|
||||
mocha
|
||||
mongo (~> 1.3.0)
|
||||
mongoid (~> 2.0)
|
||||
omniauth (~> 1.0.0)
|
||||
omniauth-facebook
|
||||
omniauth-oauth2 (~> 1.0.0)
|
||||
omniauth-openid (~> 1.0.1)
|
||||
rails (~> 3.1.0)
|
||||
rdoc
|
||||
ruby-debug (>= 0.10.3)
|
||||
sqlite3-ruby
|
||||
webrat (= 0.7.2)
|
||||
@@ -1,3 +1,5 @@
|
||||
*IMPORTANT:* Devise 2.0.0.rc is out. If you are upgrading, please read: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.0
|
||||
|
||||
== Devise
|
||||
|
||||
{<img src="https://secure.travis-ci.org/plataformatec/devise.png" />}[http://travis-ci.org/plataformatec/devise]
|
||||
|
||||
@@ -41,7 +41,12 @@ class Devise::RegistrationsController < ApplicationController
|
||||
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
|
||||
|
||||
if resource.update_with_password(params[resource_name])
|
||||
set_flash_message :notice, :updated if is_navigational_format?
|
||||
if is_navigational_format?
|
||||
if resource.respond_to?(:pending_reconfirmation?) && resource.pending_reconfirmation?
|
||||
flash_key = :update_needs_confirmation
|
||||
end
|
||||
set_flash_message :notice, flash_key || :updated
|
||||
end
|
||||
sign_in resource_name, resource, :bypass => true
|
||||
respond_with resource, :location => after_update_path_for(resource)
|
||||
else
|
||||
|
||||
@@ -25,8 +25,7 @@ class Devise::UnlocksController < ApplicationController
|
||||
|
||||
if resource.errors.empty?
|
||||
set_flash_message :notice, :unlocked if is_navigational_format?
|
||||
sign_in(resource_name, resource)
|
||||
respond_with_navigational(resource){ redirect_to after_sign_in_path_for(resource) }
|
||||
respond_with_navigational(resource){ redirect_to new_session_path(resource) }
|
||||
else
|
||||
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render_with_scope :new }
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<p>Welcome <%= @resource.email %>!</p>
|
||||
|
||||
<p>You can confirm your account through the link below:</p>
|
||||
<p>You can confirm your account email through the link below:</p>
|
||||
|
||||
<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %></p>
|
||||
|
||||
@@ -37,6 +37,7 @@ en:
|
||||
signed_up: 'Welcome! You have signed up successfully.'
|
||||
inactive_signed_up: 'You have signed up successfully. However, we could not sign you in because your account is %{reason}.'
|
||||
updated: 'You updated your account successfully.'
|
||||
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address."
|
||||
destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.'
|
||||
reasons:
|
||||
inactive: 'inactive'
|
||||
|
||||
@@ -84,7 +84,7 @@ module Devise
|
||||
# False by default for backwards compatibility.
|
||||
mattr_accessor :case_insensitive_keys
|
||||
@@case_insensitive_keys = false
|
||||
|
||||
|
||||
# Keys that should have whitespace stripped.
|
||||
# False by default for backwards compatibility.
|
||||
mattr_accessor :strip_whitespace_keys
|
||||
@@ -120,27 +120,23 @@ module Devise
|
||||
mattr_accessor :remember_for
|
||||
@@remember_for = 2.weeks
|
||||
|
||||
# If true, a valid remember token can be re-used between multiple browsers.
|
||||
mattr_accessor :remember_across_browsers
|
||||
@@remember_across_browsers = true
|
||||
|
||||
# If true, extends the user's remember period when remembered via cookie.
|
||||
mattr_accessor :extend_remember_period
|
||||
@@extend_remember_period = false
|
||||
|
||||
# If true, uses salt as remember token and does not create it in the database.
|
||||
# By default is false for backwards compatibility.
|
||||
mattr_accessor :use_salt_as_remember_token
|
||||
@@use_salt_as_remember_token = false
|
||||
|
||||
# Time interval you can access your account before confirming your account.
|
||||
mattr_accessor :confirm_within
|
||||
@@confirm_within = 0.days
|
||||
mattr_accessor :allow_unconfirmed_access_for
|
||||
@@allow_unconfirmed_access_for = 0.days
|
||||
|
||||
# Defines which key will be used when confirming an account
|
||||
# Defines which key will be used when confirming an account.
|
||||
mattr_accessor :confirmation_keys
|
||||
@@confirmation_keys = [ :email ]
|
||||
|
||||
# Defines if email should be reconfirmable.
|
||||
# False by default for backwards compatibility.
|
||||
mattr_accessor :reconfirmable
|
||||
@@reconfirmable = false
|
||||
|
||||
# Time interval to timeout the user session without activity.
|
||||
mattr_accessor :timeout_in
|
||||
@@timeout_in = 30.minutes
|
||||
@@ -153,11 +149,6 @@ module Devise
|
||||
mattr_accessor :encryptor
|
||||
@@encryptor = nil
|
||||
|
||||
# Tells if devise should apply the schema in ORMs where devise declaration
|
||||
# and schema belongs to the same class (as Datamapper and Mongoid).
|
||||
mattr_accessor :apply_schema
|
||||
@@apply_schema = true
|
||||
|
||||
# Scoped views. Since it relies on fallbacks to render default views, it's
|
||||
# turned off by default.
|
||||
mattr_accessor :scoped_views
|
||||
@@ -190,6 +181,7 @@ module Devise
|
||||
@@reset_password_keys = [ :email ]
|
||||
|
||||
# Time interval you can reset your password with a reset password key
|
||||
# Nil by default for backwards compatibility.
|
||||
mattr_accessor :reset_password_within
|
||||
@@reset_password_within = nil
|
||||
|
||||
@@ -205,9 +197,9 @@ module Devise
|
||||
mattr_accessor :token_authentication_key
|
||||
@@token_authentication_key = :auth_token
|
||||
|
||||
# If true, authentication through token does not store user in session
|
||||
mattr_accessor :stateless_token
|
||||
@@stateless_token = false
|
||||
# Skip session storage for the following strategies
|
||||
mattr_accessor :skip_session_storage
|
||||
@@skip_session_storage = []
|
||||
|
||||
# Which formats should be treated as navigational.
|
||||
# We need both :"*/*" and "*/*" to work on different Rails versions.
|
||||
@@ -222,6 +214,33 @@ module Devise
|
||||
mattr_accessor :sign_out_via
|
||||
@@sign_out_via = :get
|
||||
|
||||
# DEPRECATED CONFIG
|
||||
|
||||
# If true, uses salt as remember token and does not create it in the database.
|
||||
# By default is false for backwards compatibility.
|
||||
mattr_accessor :use_salt_as_remember_token
|
||||
@@use_salt_as_remember_token = false
|
||||
|
||||
# Tells if devise should apply the schema in ORMs where devise declaration
|
||||
# and schema belongs to the same class (as Datamapper and Mongoid).
|
||||
mattr_accessor :apply_schema
|
||||
@@apply_schema = true
|
||||
|
||||
def self.remember_across_browsers=(value)
|
||||
warn "\n[DEVISE] Devise.remember_across_browsers is deprecated and has no effect. Please remove it.\n"
|
||||
end
|
||||
|
||||
def self.confirm_within=(value)
|
||||
warn "\n[DEVISE] Devise.confirm_within= is deprecated. Please set Devise.allow_unconfirmed_access_for= instead.\n"
|
||||
Devise.allow_unconfirmed_access_for = value
|
||||
end
|
||||
|
||||
def self.stateless_token=(value)
|
||||
warn "\n[DEVISE] Devise.stateless_token= is deprecated. Please append :token_auth to Devise.skip_session_storage " \
|
||||
"instead, for example: Devise.skip_session_storage << :token_auth\n"
|
||||
Devise.skip_session_storage << :token_auth
|
||||
end
|
||||
|
||||
# PRIVATE CONFIGURATION
|
||||
|
||||
# Store scopes mappings.
|
||||
@@ -361,7 +380,7 @@ module Devise
|
||||
# initialization.
|
||||
#
|
||||
# Devise.initialize do |config|
|
||||
# config.confirm_within = 2.days
|
||||
# config.allow_unconfirmed_access_for = 2.days
|
||||
#
|
||||
# config.warden do |manager|
|
||||
# # Configure warden to use other strategies, like oauth.
|
||||
|
||||
@@ -93,8 +93,15 @@ MESSAGE
|
||||
def require_no_authentication
|
||||
return unless is_navigational_format?
|
||||
no_input = devise_mapping.no_input_strategies
|
||||
args = no_input.dup.push :scope => resource_name
|
||||
if no_input.present? && warden.authenticate?(*args)
|
||||
|
||||
authenticated = if no_input.present?
|
||||
args = no_input.dup.push :scope => resource_name
|
||||
warden.authenticate?(*args)
|
||||
else
|
||||
warden.authenticated?(resource_name)
|
||||
end
|
||||
|
||||
if authenticated
|
||||
resource = warden.user(resource_name)
|
||||
flash[:alert] = I18n.t("devise.failure.already_authenticated")
|
||||
redirect_to after_sign_in_path_for(resource)
|
||||
|
||||
@@ -8,9 +8,9 @@ module Devise
|
||||
def failure_app(env)
|
||||
app = env["warden.options"] &&
|
||||
(scope = env["warden.options"][:scope]) &&
|
||||
Devise.mappings[scope].failure_app
|
||||
Devise.mappings[scope.to_sym].failure_app
|
||||
|
||||
app || Devise::FailureApp
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,8 +23,7 @@ module Devise
|
||||
#
|
||||
class Mapping #:nodoc:
|
||||
attr_reader :singular, :scoped_path, :path, :controllers, :path_names,
|
||||
:class_name, :sign_out_via, :format, :used_routes, :used_helpers,
|
||||
:constraints, :defaults, :failure_app
|
||||
:class_name, :sign_out_via, :format, :used_routes, :used_helpers, :failure_app
|
||||
|
||||
alias :name :singular
|
||||
|
||||
@@ -64,8 +63,6 @@ module Devise
|
||||
default_failure_app(options)
|
||||
default_controllers(options)
|
||||
default_path_names(options)
|
||||
default_constraints(options)
|
||||
default_defaults(options)
|
||||
default_used_route(options)
|
||||
default_used_helpers(options)
|
||||
end
|
||||
|
||||
@@ -25,6 +25,11 @@ module Devise
|
||||
# * +params_authenticatable+: if this model allows authentication through request params. By default true.
|
||||
# It also accepts an array specifying the strategies that should allow params authentication.
|
||||
#
|
||||
# * +skip_session_storage+: By default Devise will store the user in session.
|
||||
# You can skip storage for http and token auth by appending values to array:
|
||||
# :skip_session_storage => [:token_auth] or :skip_session_storage => [:http_auth, :token_auth],
|
||||
# by default is set to :skip_session_storage => [:http_auth].
|
||||
#
|
||||
# == active_for_authentication?
|
||||
#
|
||||
# After authenticating a user and in each request, Devise checks if your model is active by
|
||||
@@ -52,6 +57,9 @@ module Devise
|
||||
included do
|
||||
class_attribute :devise_modules, :instance_writer => false
|
||||
self.devise_modules ||= []
|
||||
|
||||
before_validation :downcase_keys
|
||||
before_validation :strip_whitespace
|
||||
end
|
||||
|
||||
# Check if the current object is valid for authentication. This method and
|
||||
@@ -79,8 +87,21 @@ module Devise
|
||||
Devise.mailer
|
||||
end
|
||||
|
||||
def headers_for(name)
|
||||
{}
|
||||
end
|
||||
|
||||
def downcase_keys
|
||||
(self.class.case_insensitive_keys || []).each { |k| self[k].try(:downcase!) }
|
||||
end
|
||||
|
||||
def strip_whitespace
|
||||
(self.class.strip_whitespace_keys || []).each { |k| self[k].try(:strip!) }
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
Devise::Models.config(self, :authentication_keys, :request_keys, :strip_whitespace_keys, :case_insensitive_keys, :http_authenticatable, :params_authenticatable)
|
||||
Devise::Models.config(self, :authentication_keys, :request_keys, :strip_whitespace_keys,
|
||||
:case_insensitive_keys, :http_authenticatable, :params_authenticatable, :skip_session_storage)
|
||||
|
||||
def serialize_into_session(record)
|
||||
[record.to_key, record.authenticatable_salt]
|
||||
|
||||
@@ -9,11 +9,16 @@ module Devise
|
||||
#
|
||||
# Confirmable adds the following options to devise_for:
|
||||
#
|
||||
# * +confirm_within+: the time you want to allow the user to access his account
|
||||
# * +allow_unconfirmed_access_for+: the time you want to allow the user to access his account
|
||||
# before confirming it. After this period, the user access is denied. You can
|
||||
# use this to let your user access some features of your application without
|
||||
# confirming the account, but blocking it after a certain period (ie 7 days).
|
||||
# By default confirm_within is zero, it means users always have to confirm to sign in.
|
||||
# By default allow_unconfirmed_access_for is zero, it means users always have to confirm to sign in.
|
||||
# * +reconfirmable+: requires any email changes to be confirmed (exactly the same way as
|
||||
# initial account confirmation) to be applied. Requires additional unconfirmed_email
|
||||
# db field to be setup (t.reconfirmable in migrations). Until confirmed new email is
|
||||
# stored in unconfirmed email column, and copied to email column on successful
|
||||
# confirmation.
|
||||
#
|
||||
# == Examples
|
||||
#
|
||||
@@ -27,15 +32,26 @@ module Devise
|
||||
included do
|
||||
before_create :generate_confirmation_token, :if => :confirmation_required?
|
||||
after_create :send_confirmation_instructions, :if => :confirmation_required?
|
||||
before_update :postpone_email_change_until_confirmation, :if => :postpone_email_change?
|
||||
after_update :send_confirmation_instructions, :if => :reconfirmation_required?
|
||||
end
|
||||
|
||||
# Confirm a user by setting its confirmed_at to actual time. If the user
|
||||
# is already confirmed, add en error to email field
|
||||
# Confirm a user by setting it's confirmed_at to actual time. If the user
|
||||
# is already confirmed, add an error to email field. If the user is invalid
|
||||
# add errors
|
||||
def confirm!
|
||||
unless_confirmed do
|
||||
self.confirmation_token = nil
|
||||
self.confirmed_at = Time.now.utc
|
||||
save(:validate => false)
|
||||
|
||||
if self.class.reconfirmable
|
||||
@bypass_postpone = true
|
||||
self.email = unconfirmed_email if unconfirmed_email.present?
|
||||
self.unconfirmed_email = nil
|
||||
save
|
||||
else
|
||||
save(:validate => false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -44,9 +60,14 @@ module Devise
|
||||
!!confirmed_at
|
||||
end
|
||||
|
||||
def pending_reconfirmation?
|
||||
self.class.reconfirmable && unconfirmed_email.present?
|
||||
end
|
||||
|
||||
# Send confirmation instructions by email
|
||||
def send_confirmation_instructions
|
||||
generate_confirmation_token! if self.confirmation_token.nil?
|
||||
@reconfirmation_required = false
|
||||
generate_confirmation_token! if self.confirmation_token.blank?
|
||||
self.devise_mailer.confirmation_instructions(self).deliver
|
||||
end
|
||||
|
||||
@@ -74,6 +95,14 @@ module Devise
|
||||
self.confirmed_at = Time.now.utc
|
||||
end
|
||||
|
||||
def headers_for(action)
|
||||
headers = super
|
||||
if action == :confirmation_instructions && pending_reconfirmation?
|
||||
headers[:to] = unconfirmed_email
|
||||
end
|
||||
headers
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Callback to overwrite if confirmation is required or not.
|
||||
@@ -88,26 +117,26 @@ module Devise
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# # confirm_within = 1.day and confirmation_sent_at = today
|
||||
# # allow_unconfirmed_access_for = 1.day and confirmation_sent_at = today
|
||||
# confirmation_period_valid? # returns true
|
||||
#
|
||||
# # confirm_within = 5.days and confirmation_sent_at = 4.days.ago
|
||||
# # allow_unconfirmed_access_for = 5.days and confirmation_sent_at = 4.days.ago
|
||||
# confirmation_period_valid? # returns true
|
||||
#
|
||||
# # confirm_within = 5.days and confirmation_sent_at = 5.days.ago
|
||||
# # allow_unconfirmed_access_for = 5.days and confirmation_sent_at = 5.days.ago
|
||||
# confirmation_period_valid? # returns false
|
||||
#
|
||||
# # confirm_within = 0.days
|
||||
# # allow_unconfirmed_access_for = 0.days
|
||||
# confirmation_period_valid? # will always return false
|
||||
#
|
||||
def confirmation_period_valid?
|
||||
confirmation_sent_at && confirmation_sent_at.utc >= self.class.confirm_within.ago
|
||||
confirmation_sent_at && confirmation_sent_at.utc >= self.class.allow_unconfirmed_access_for.ago
|
||||
end
|
||||
|
||||
# Checks whether the record is confirmed or not, yielding to the block
|
||||
# Checks whether the record is confirmed or not or a new email has been added, yielding to the block
|
||||
# if it's already confirmed, otherwise adds an error to email.
|
||||
def unless_confirmed
|
||||
unless confirmed?
|
||||
unless confirmed? && !pending_reconfirmation?
|
||||
yield
|
||||
else
|
||||
self.errors.add(:email, :already_confirmed)
|
||||
@@ -118,7 +147,6 @@ module Devise
|
||||
# Generates a new random token for confirmation, and stores the time
|
||||
# this token is being generated
|
||||
def generate_confirmation_token
|
||||
self.confirmed_at = nil
|
||||
self.confirmation_token = self.class.confirmation_token
|
||||
self.confirmation_sent_at = Time.now.utc
|
||||
end
|
||||
@@ -132,13 +160,32 @@ module Devise
|
||||
confirm! unless confirmed?
|
||||
end
|
||||
|
||||
def postpone_email_change_until_confirmation
|
||||
@reconfirmation_required = true
|
||||
self.unconfirmed_email = self.email
|
||||
self.email = self.email_was
|
||||
end
|
||||
|
||||
def postpone_email_change?
|
||||
postpone = self.class.reconfirmable && email_changed? && !@bypass_postpone
|
||||
@bypass_postpone = nil
|
||||
postpone
|
||||
end
|
||||
|
||||
def reconfirmation_required?
|
||||
self.class.reconfirmable && @reconfirmation_required
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# Attempt to find a user by its email. If a record is found, send new
|
||||
# confirmation instructions to it. If not user is found, returns a new user
|
||||
# with an email not found error.
|
||||
# confirmation instructions to it. If not, try searching for a user by unconfirmed_email
|
||||
# field. If no user is found, returns a new user with an email not found error.
|
||||
# Options must contain the user email
|
||||
def send_confirmation_instructions(attributes={})
|
||||
confirmable = find_or_initialize_with_errors(confirmation_keys, attributes, :not_found)
|
||||
confirmable = find_by_unconfirmed_email_with_errors(attributes) if reconfirmable
|
||||
unless confirmable.try(:persisted?)
|
||||
confirmable = find_or_initialize_with_errors(confirmation_keys, attributes, :not_found)
|
||||
end
|
||||
confirmable.resend_confirmation_token if confirmable.persisted?
|
||||
confirmable
|
||||
end
|
||||
@@ -158,7 +205,15 @@ module Devise
|
||||
generate_token(:confirmation_token)
|
||||
end
|
||||
|
||||
Devise::Models.config(self, :confirm_within, :confirmation_keys)
|
||||
# Find a record for confirmation by unconfirmed email field
|
||||
def find_by_unconfirmed_email_with_errors(attributes = {})
|
||||
unconfirmed_required_attributes = confirmation_keys.map { |k| k == :email ? :unconfirmed_email : k }
|
||||
unconfirmed_attributes = attributes.symbolize_keys
|
||||
unconfirmed_attributes[:unconfirmed_email] = unconfirmed_attributes.delete(:email)
|
||||
find_or_initialize_with_errors(unconfirmed_required_attributes, unconfirmed_attributes, :not_found)
|
||||
end
|
||||
|
||||
Devise::Models.config(self, :allow_unconfirmed_access_for, :confirmation_keys, :reconfirmable)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -25,8 +25,6 @@ module Devise
|
||||
included do
|
||||
attr_reader :password, :current_password
|
||||
attr_accessor :password_confirmation
|
||||
before_validation :downcase_keys
|
||||
before_validation :strip_whitespace
|
||||
end
|
||||
|
||||
# Generates password encryption based on the given value.
|
||||
@@ -103,15 +101,6 @@ module Devise
|
||||
|
||||
protected
|
||||
|
||||
# Downcase case-insensitive keys
|
||||
def downcase_keys
|
||||
(self.class.case_insensitive_keys || []).each { |k| self[k].try(:downcase!) }
|
||||
end
|
||||
|
||||
def strip_whitespace
|
||||
(self.class.strip_whitespace_keys || []).each { |k| self[k].try(:strip!) }
|
||||
end
|
||||
|
||||
# Digests the password using bcrypt.
|
||||
def password_digest(password)
|
||||
::BCrypt::Password.create("#{password}#{self.class.pepper}", :cost => self.class.stretches).to_s
|
||||
|
||||
@@ -29,6 +29,7 @@ module Devise
|
||||
def reset_password!(new_password, new_password_confirmation)
|
||||
self.password = new_password
|
||||
self.password_confirmation = new_password_confirmation
|
||||
|
||||
if valid?
|
||||
clear_reset_password_token
|
||||
after_password_reset
|
||||
@@ -39,7 +40,7 @@ module Devise
|
||||
|
||||
# Resets reset password token and send reset password instructions by email
|
||||
def send_reset_password_instructions
|
||||
generate_reset_password_token! if should_generate_token?
|
||||
generate_reset_password_token! if should_generate_reset_token?
|
||||
self.devise_mailer.reset_password_instructions(self).deliver
|
||||
end
|
||||
|
||||
@@ -64,20 +65,19 @@ module Devise
|
||||
# reset_password_period_valid? # will always return false
|
||||
#
|
||||
def reset_password_period_valid?
|
||||
return true unless respond_to?(:reset_password_sent_at)
|
||||
reset_password_sent_at && reset_password_sent_at.utc >= self.class.reset_password_within.ago
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def should_generate_token?
|
||||
def should_generate_reset_token?
|
||||
reset_password_token.nil? || !reset_password_period_valid?
|
||||
end
|
||||
|
||||
# Generates a new random token for reset password
|
||||
def generate_reset_password_token
|
||||
self.reset_password_token = self.class.reset_password_token
|
||||
self.reset_password_sent_at = Time.now.utc if respond_to?(:reset_password_sent_at=)
|
||||
self.reset_password_sent_at = Time.now.utc
|
||||
self.reset_password_token
|
||||
end
|
||||
|
||||
@@ -90,7 +90,7 @@ module Devise
|
||||
# Removes reset_password token
|
||||
def clear_reset_password_token
|
||||
self.reset_password_token = nil
|
||||
self.reset_password_sent_at = nil if respond_to?(:reset_password_sent_at=)
|
||||
self.reset_password_sent_at = nil
|
||||
end
|
||||
|
||||
def after_password_reset
|
||||
|
||||
@@ -21,11 +21,6 @@ module Devise
|
||||
# used to calculate the expires time for the cookie created to remember
|
||||
# the user. By default remember_for is 2.weeks.
|
||||
#
|
||||
# * +remember_across_browsers+: if a valid remember token can be re-used
|
||||
# between multiple browsers. By default remember_across_browsers is true
|
||||
# and cannot be turned off if you are using password salt instead of remember
|
||||
# token.
|
||||
#
|
||||
# * +extend_remember_period+: if true, extends the user's remember period
|
||||
# when remembered via cookie. False by default.
|
||||
#
|
||||
@@ -49,7 +44,6 @@ module Devise
|
||||
# Generate a new remember token and save the record without validations
|
||||
# unless remember_across_browsers is true and the user already has a valid token.
|
||||
def remember_me!(extend_period=false)
|
||||
self.remember_token = self.class.remember_token if respond_to?(:remember_token) && generate_remember_token?
|
||||
self.remember_created_at = Time.now.utc if generate_remember_timestamp?(extend_period)
|
||||
save(:validate => false)
|
||||
end
|
||||
@@ -75,14 +69,12 @@ module Devise
|
||||
end
|
||||
|
||||
def rememberable_value
|
||||
if respond_to?(:remember_token)
|
||||
remember_token
|
||||
elsif respond_to?(:authenticatable_salt) && (salt = authenticatable_salt)
|
||||
if salt = authenticatable_salt
|
||||
salt
|
||||
else
|
||||
raise "The #{self.class.name} class does not respond to remember_token and " <<
|
||||
"authenticatable_salt returns nil. In order to use rememberable, you must " <<
|
||||
"add a remember_token field to your model or ensure a password is always set."
|
||||
raise "authenticable_salt returned nil for the #{self.class.name} model. " \
|
||||
"In order to use rememberable, you must ensure a password is always set " \
|
||||
"or implement rememberable_value in your model with your own logic."
|
||||
end
|
||||
end
|
||||
|
||||
@@ -92,12 +84,6 @@ module Devise
|
||||
|
||||
protected
|
||||
|
||||
# Generate a token unless remember_across_browsers is true and there is
|
||||
# an existing remember_token or the existing remember_token has expried.
|
||||
def generate_remember_token? #:nodoc:
|
||||
!(self.class.remember_across_browsers && remember_token) || remember_expired?
|
||||
end
|
||||
|
||||
# Generate a timestamp if extend_remember_period is true, if no remember_token
|
||||
# exists, or if an existing remember token has expired.
|
||||
def generate_remember_timestamp?(extend_period) #:nodoc:
|
||||
@@ -121,8 +107,7 @@ module Devise
|
||||
generate_token(:remember_token)
|
||||
end
|
||||
|
||||
Devise::Models.config(self, :remember_for, :remember_across_browsers,
|
||||
:extend_remember_period, :cookie_options)
|
||||
Devise::Models.config(self, :remember_for, :extend_remember_period, :cookie_options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,7 +23,6 @@ module Devise
|
||||
# Checks whether the user session has expired based on configured time.
|
||||
def timedout?(last_access)
|
||||
return false if remember_exists_and_not_expired?
|
||||
|
||||
!timeout_in.nil? && last_access && last_access <= timeout_in.ago
|
||||
end
|
||||
|
||||
@@ -34,8 +33,7 @@ module Devise
|
||||
private
|
||||
|
||||
def remember_exists_and_not_expired?
|
||||
return false unless respond_to?(:remember_expired?)
|
||||
|
||||
return false unless respond_to?(:remember_created_at)
|
||||
remember_created_at && !remember_expired?
|
||||
end
|
||||
|
||||
|
||||
@@ -24,9 +24,6 @@ module Devise
|
||||
#
|
||||
# * +token_authentication_key+: Defines name of the authentication token params key. E.g. /users/sign_in?some_key=...
|
||||
#
|
||||
# * +stateless_token+: By default, when you sign up with a token, Devise will store the user in session
|
||||
# as any other authentication strategy. You can set stateless_token to true to avoid this.
|
||||
#
|
||||
module TokenAuthenticatable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
@@ -65,7 +62,7 @@ module Devise
|
||||
generate_token(:authentication_token)
|
||||
end
|
||||
|
||||
::Devise::Models.config(self, :token_authentication_key, :stateless_token)
|
||||
::Devise::Models.config(self, :token_authentication_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,7 +23,7 @@ module Devise
|
||||
|
||||
base.class_eval do
|
||||
validates_presence_of :email, :if => :email_required?
|
||||
validates_uniqueness_of :email, :case_sensitive => (case_insensitive_keys != false), :allow_blank => true, :if => :email_changed?
|
||||
validates_uniqueness_of :email, :allow_blank => true, :if => :email_changed?
|
||||
validates_format_of :email, :with => email_regexp, :allow_blank => true, :if => :email_changed?
|
||||
|
||||
validates_presence_of :password, :if => :password_required?
|
||||
|
||||
@@ -26,6 +26,12 @@ module Devise
|
||||
|
||||
# Tell how to apply schema methods.
|
||||
def apply_devise_schema(name, type, options={})
|
||||
@__devise_warning_raised ||= begin
|
||||
$stderr.puts "\n[DEVISE] You are using t.database_authenticatable and others in your migration " \
|
||||
"and this feature is deprecated. Please simply use Rails helpers instead as mentioned here:\n" \
|
||||
"https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.0-migration-schema-style\n\n"
|
||||
true
|
||||
end
|
||||
column name, type.to_s.downcase.to_sym, options
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,7 +12,8 @@ module Devise
|
||||
end
|
||||
|
||||
def signing_out?
|
||||
@current_path == send("destroy_#{@scope}_session_path")
|
||||
route = "destroy_#{@scope}_session_path"
|
||||
respond_to?(route) && @current_path == send(route)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -41,5 +41,36 @@ module Devise
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
initializer "devise.deprecations" do
|
||||
unless defined?(Rails::Generators)
|
||||
if Devise.case_insensitive_keys == false
|
||||
warn "\n[DEVISE] Devise.case_insensitive_keys is false which is no longer " \
|
||||
"supported. If you want to continue running on this mode, please ensure " \
|
||||
"you are not using validatable (you can copy the validations directly to your model) " \
|
||||
"and set case_insensitive_keys to an empty array.\n"
|
||||
end
|
||||
|
||||
if Devise.apply_schema && defined?(Mongoid)
|
||||
warn "\n[DEVISE] Devise.apply_schema is true. This means Devise was " \
|
||||
"automatically configuring your DB. This no longer happens. You should " \
|
||||
"set Devise.apply_schema to false and manually set the fields used by Devise as shown here: " \
|
||||
"https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.0-migration-schema-style\n"
|
||||
end
|
||||
|
||||
# TODO: Deprecate the true value of this option as well
|
||||
if Devise.use_salt_as_remember_token == false
|
||||
warn "\n[DEVISE] Devise.use_salt_as_remember_token is false which is no longer " \
|
||||
"supported. Devise now only uses the salt as remember token and the remember_token " \
|
||||
"column can be removed from your models.\n"
|
||||
end
|
||||
|
||||
if Devise.reset_password_within.nil?
|
||||
warn "\n[DEVISE] Devise.reset_password_within is nil. Please set this value to " \
|
||||
"an interval (for example, 6.hours) and add a reset_password_sent_at field to " \
|
||||
"your Devise models (if they don't have one already).\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -185,7 +185,7 @@ module ActionDispatch::Routing
|
||||
options[:path_names] = (@scope[:path_names] || {}).merge(options[:path_names] || {})
|
||||
options[:constraints] = (@scope[:constraints] || {}).merge(options[:constraints] || {})
|
||||
options[:defaults] = (@scope[:defaults] || {}).merge(options[:defaults] || {})
|
||||
@scope[:options] = (@scope[:options] || {}).merge({:format => false}) if options[:format] == false
|
||||
options[:options] = (@scope[:options] || {}).merge({:format => false}) if options[:format] == false
|
||||
|
||||
resources.map!(&:to_sym)
|
||||
|
||||
@@ -208,7 +208,7 @@ module ActionDispatch::Routing
|
||||
|
||||
devise_scope mapping.name do
|
||||
yield if block_given?
|
||||
with_devise_exclusive_scope mapping.fullpath, mapping.name, mapping.constraints, mapping.defaults do
|
||||
with_devise_exclusive_scope mapping.fullpath, mapping.name, options do
|
||||
routes.each { |mod| send("devise_#{mod}", mapping, mapping.controllers) }
|
||||
end
|
||||
end
|
||||
@@ -368,12 +368,15 @@ module ActionDispatch::Routing
|
||||
@scope[:path] = path
|
||||
end
|
||||
|
||||
def with_devise_exclusive_scope(new_path, new_as, new_constraints, new_defaults) #:nodoc:
|
||||
old_as, old_path, old_module, old_constraints, old_defaults = @scope[:as], @scope[:path], @scope[:module], @scope[:constraints], @scope[:defaults]
|
||||
@scope[:as], @scope[:path], @scope[:module], @scope[:constraints], @scope[:defaults] = new_as, new_path, nil, new_constraints, new_defaults
|
||||
def with_devise_exclusive_scope(new_path, new_as, options) #:nodoc:
|
||||
old_as, old_path, old_module, old_constraints, old_defaults, old_options =
|
||||
*@scope.values_at(:as, :path, :module, :constraints, :defaults, :options)
|
||||
@scope[:as], @scope[:path], @scope[:module], @scope[:constraints], @scope[:defaults], @scope[:options] =
|
||||
new_as, new_path, nil, *options.values_at(:constraints, :defaults, :options)
|
||||
yield
|
||||
ensure
|
||||
@scope[:as], @scope[:path], @scope[:module], @scope[:constraints], @scope[:defaults] = old_as, old_path, old_module, old_constraints, old_defaults
|
||||
@scope[:as], @scope[:path], @scope[:module], @scope[:constraints], @scope[:defaults], @scope[:options] =
|
||||
old_as, old_path, old_module, old_constraints, old_defaults, old_options
|
||||
end
|
||||
|
||||
def raise_no_devise_method_error!(klass) #:nodoc:
|
||||
|
||||
@@ -40,6 +40,11 @@ module Devise
|
||||
apply_devise_schema :confirmation_sent_at, DateTime
|
||||
end
|
||||
|
||||
# Creates unconfirmed_email
|
||||
def reconfirmable
|
||||
apply_devise_schema :unconfirmed_email, String
|
||||
end
|
||||
|
||||
# Creates reset_password_token and reset_password_sent_at.
|
||||
#
|
||||
# == Options
|
||||
|
||||
@@ -6,7 +6,11 @@ module Devise
|
||||
# parameters both from params or from http authorization headers. See database_authenticatable
|
||||
# for an example.
|
||||
class Authenticatable < Base
|
||||
attr_accessor :authentication_hash, :password
|
||||
attr_accessor :authentication_hash, :authentication_type, :password
|
||||
|
||||
def store?
|
||||
!mapping.to.skip_session_storage.include?(authentication_type)
|
||||
end
|
||||
|
||||
def valid?
|
||||
valid_for_params_auth? || valid_for_http_auth?
|
||||
@@ -47,7 +51,7 @@ module Devise
|
||||
# * If all authentication keys are present;
|
||||
#
|
||||
def valid_for_http_auth?
|
||||
http_authenticatable? && request.authorization && with_authentication_hash(http_auth_hash)
|
||||
http_authenticatable? && request.authorization && with_authentication_hash(:http_auth, http_auth_hash)
|
||||
end
|
||||
|
||||
# Check if this is strategy is valid for params authentication by:
|
||||
@@ -58,8 +62,8 @@ module Devise
|
||||
# * If all authentication keys are present;
|
||||
#
|
||||
def valid_for_params_auth?
|
||||
params_authenticatable? && valid_request? &&
|
||||
valid_params? && with_authentication_hash(params_auth_hash)
|
||||
params_authenticatable? && valid_params_request? &&
|
||||
valid_params? && with_authentication_hash(:params_auth, params_auth_hash)
|
||||
end
|
||||
|
||||
# Check if the model accepts this strategy as http authenticatable.
|
||||
@@ -83,8 +87,8 @@ module Devise
|
||||
Hash[*keys.zip(decode_credentials).flatten]
|
||||
end
|
||||
|
||||
# By default, a request is valid if the controller is allowed and the VERB is POST.
|
||||
def valid_request?
|
||||
# By default, a request is valid if the controller set the proper env variable.
|
||||
def valid_params_request?
|
||||
!!env["devise.allow_params_authentication"]
|
||||
end
|
||||
|
||||
@@ -105,8 +109,8 @@ module Devise
|
||||
end
|
||||
|
||||
# Sets the authentication hash and the password from params_auth_hash or http_auth_hash.
|
||||
def with_authentication_hash(auth_values)
|
||||
self.authentication_hash = {}
|
||||
def with_authentication_hash(auth_type, auth_values)
|
||||
self.authentication_hash, self.authentication_type = {}, auth_type
|
||||
self.password = auth_values[:password]
|
||||
|
||||
parse_authentication_key_values(auth_values, authentication_keys) &&
|
||||
|
||||
@@ -11,7 +11,7 @@ module Devise
|
||||
# a password, you can pass "X" as password and it will simply be ignored.
|
||||
class TokenAuthenticatable < Authenticatable
|
||||
def store?
|
||||
!mapping.to.stateless_token
|
||||
super && !mapping.to.skip_session_storage.include?(:token_auth)
|
||||
end
|
||||
|
||||
def authenticate!
|
||||
@@ -27,8 +27,8 @@ module Devise
|
||||
|
||||
private
|
||||
|
||||
# TokenAuthenticatable request is valid for any controller and any verb.
|
||||
def valid_request?
|
||||
# Token Authenticatable can be authenticated with params in any controller and any verb.
|
||||
def valid_params_request?
|
||||
true
|
||||
end
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
module Devise
|
||||
VERSION = "1.5.2".freeze
|
||||
VERSION = "2.0.0.rc".freeze
|
||||
end
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
require 'rails/generators/active_record'
|
||||
require 'generators/devise/orm_helpers'
|
||||
|
||||
|
||||
module ActiveRecord
|
||||
module Generators
|
||||
class DeviseGenerator < ActiveRecord::Generators::Base
|
||||
@@ -21,13 +20,52 @@ module ActiveRecord
|
||||
def generate_model
|
||||
invoke "active_record:model", [name], :migration => false unless model_exists? && behavior == :invoke
|
||||
end
|
||||
|
||||
|
||||
def inject_devise_content
|
||||
inject_into_class(model_path, class_name, model_contents + <<CONTENT) if model_exists?
|
||||
# Setup accessible (or protected) attributes for your model
|
||||
attr_accessible :email, :password, :password_confirmation, :remember_me
|
||||
CONTENT
|
||||
end
|
||||
|
||||
def migration_data
|
||||
<<RUBY
|
||||
## Database authenticatable
|
||||
t.string :email, :null => false, :default => ""
|
||||
t.string :encrypted_password, :null => false, :default => ""
|
||||
|
||||
## Recoverable
|
||||
t.string :reset_password_token
|
||||
t.datetime :reset_password_sent_at
|
||||
|
||||
## Rememberable
|
||||
t.datetime :remember_created_at
|
||||
|
||||
## Trackable
|
||||
t.integer :sign_in_count, :default => 0
|
||||
t.datetime :current_sign_in_at
|
||||
t.datetime :last_sign_in_at
|
||||
t.string :current_sign_in_ip
|
||||
t.string :last_sign_in_ip
|
||||
|
||||
## Encryptable
|
||||
# t.string :password_salt
|
||||
|
||||
## Confirmable
|
||||
# t.string :confirmation_token
|
||||
# t.datetime :confirmed_at
|
||||
# t.datetime :confirmation_sent_at
|
||||
# t.string :unconfirmed_email # Only if using reconfirmable
|
||||
|
||||
## Lockable
|
||||
# t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
|
||||
# t.string :unlock_token # Only if unlock strategy is :email or :both
|
||||
# t.datetime :locked_at
|
||||
|
||||
# Token authenticatable
|
||||
# t.string :authentication_token
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,15 +5,7 @@ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
|
||||
def self.up
|
||||
<% end -%>
|
||||
create_table(:<%= table_name %>) do |t|
|
||||
t.database_authenticatable :null => false
|
||||
t.recoverable
|
||||
t.rememberable
|
||||
t.trackable
|
||||
|
||||
# t.encryptable
|
||||
# t.confirmable
|
||||
# t.lockable :lock_strategy => :<%= Devise.lock_strategy %>, :unlock_strategy => :<%= Devise.unlock_strategy %>
|
||||
# t.token_authenticatable
|
||||
<%= migration_data -%>
|
||||
|
||||
<% attributes.each do |attribute| -%>
|
||||
t.<%= attribute.type %> :<%= attribute.name %>
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
class AddDeviseTo<%= table_name.camelize %> < ActiveRecord::Migration
|
||||
def self.up
|
||||
change_table(:<%= table_name %>) do |t|
|
||||
t.database_authenticatable :null => false
|
||||
t.recoverable
|
||||
t.rememberable
|
||||
t.trackable
|
||||
|
||||
# t.encryptable
|
||||
# t.confirmable
|
||||
# t.lockable :lock_strategy => :<%= Devise.lock_strategy %>, :unlock_strategy => :<%= Devise.unlock_strategy %>
|
||||
# t.token_authenticatable
|
||||
<%= migration_data -%>
|
||||
|
||||
<% attributes.each do |attribute| -%>
|
||||
t.<%= attribute.type %> :<%= attribute.name %>
|
||||
|
||||
@@ -9,9 +9,52 @@ module Mongoid
|
||||
invoke "mongoid:model", [name] unless model_exists? && behavior == :invoke
|
||||
end
|
||||
|
||||
def inject_field_types
|
||||
inject_into_file model_path, migration_data, :after => "include Mongoid::Document\n" if model_exists?
|
||||
end
|
||||
|
||||
def inject_devise_content
|
||||
inject_into_file model_path, model_contents, :after => "include Mongoid::Document\n" if model_exists?
|
||||
end
|
||||
|
||||
def migration_data
|
||||
<<RUBY
|
||||
## Database authenticatable
|
||||
field :email, :type => String, :null => false, :default => ""
|
||||
field :encrypted_password, :type => String, :null => false, :default => ""
|
||||
|
||||
## Recoverable
|
||||
field :reset_password_token, :type => String
|
||||
field :reset_password_sent_at, :type => Time
|
||||
|
||||
## Rememberable
|
||||
field :remember_created_at, :type => Time
|
||||
|
||||
## Trackable
|
||||
field :sign_in_count, :type => Integer, :default => 0
|
||||
field :current_sign_in_at, :type => Time
|
||||
field :last_sign_in_at, :type => Time
|
||||
field :current_sign_in_ip, :type => String
|
||||
field :last_sign_in_ip, :type => String
|
||||
|
||||
## Encryptable
|
||||
# field :password_salt, :type => String
|
||||
|
||||
## Confirmable
|
||||
# field :confirmation_token, :type => String
|
||||
# field :confirmed_at, :type => Time
|
||||
# field :confirmation_sent_at, :type => Time
|
||||
# field :unconfirmed_email, :type => String # Only if using reconfirmable
|
||||
|
||||
## Lockable
|
||||
# field :failed_attempts, :type => Integer, :default => 0 # Only if lock strategy is :failed_attempts
|
||||
# field :unlock_token, :type => String # Only if unlock strategy is :email or :both
|
||||
# field :locked_at, :type => Time
|
||||
|
||||
## Token authenticatable
|
||||
# field :authentication_token, :type => String
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -9,6 +9,9 @@ Devise.setup do |config|
|
||||
# Configure the class responsible to send e-mails.
|
||||
# config.mailer = "Devise::Mailer"
|
||||
|
||||
# Automatically apply schema changes in tableless databases
|
||||
config.apply_schema = false
|
||||
|
||||
# ==> ORM configuration
|
||||
# Load and configure the ORM. Supports :active_record (default) and
|
||||
# :mongoid (bson_ext recommended) by default. Other ORMs may be
|
||||
@@ -59,6 +62,10 @@ Devise.setup do |config|
|
||||
# Does not affect registerable.
|
||||
# config.paranoid = true
|
||||
|
||||
# By default Devise will store the user in session. You can skip storage for
|
||||
# :http_auth and :token_auth by adding those symbols to the array below.
|
||||
config.skip_session_storage = [:http_auth]
|
||||
|
||||
# ==> Configuration for :database_authenticatable
|
||||
# For bcrypt, this is the cost for hashing the password and defaults to 10. If
|
||||
# using other encryptors, it sets how many times you want the password re-encrypted.
|
||||
@@ -77,7 +84,13 @@ Devise.setup do |config|
|
||||
# able to access the website for two days without confirming his account,
|
||||
# access will be blocked just in the third day. Default is 0.days, meaning
|
||||
# the user cannot access the website without confirming his account.
|
||||
# config.confirm_within = 2.days
|
||||
# config.allow_unconfirmed_access_for = 2.days
|
||||
|
||||
# If true, requires any email changes to be confirmed (exctly the same way as
|
||||
# initial account confirmation) to be applied. Requires additional unconfirmed_email
|
||||
# db field (see migrations). Until confirmed new email is stored in
|
||||
# unconfirmed email column, and copied to email column on successful confirmation.
|
||||
config.reconfirmable = true
|
||||
|
||||
# Defines which key will be used when confirming an account
|
||||
# config.confirmation_keys = [ :email ]
|
||||
@@ -86,9 +99,6 @@ Devise.setup do |config|
|
||||
# The time the user will be remembered without asking for credentials again.
|
||||
# config.remember_for = 2.weeks
|
||||
|
||||
# If true, a valid remember token can be re-used between multiple browsers.
|
||||
# config.remember_across_browsers = true
|
||||
|
||||
# If true, extends the user's remember period when remembered via cookie.
|
||||
# config.extend_remember_period = false
|
||||
|
||||
@@ -145,7 +155,7 @@ Devise.setup do |config|
|
||||
# Time interval you can reset your password with a reset password key.
|
||||
# Don't put a too small interval or your users won't have the time to
|
||||
# change their passwords.
|
||||
config.reset_password_within = 2.hours
|
||||
config.reset_password_within = 6.hours
|
||||
|
||||
# ==> Configuration for :encryptable
|
||||
# Allow you to use another encryption algorithm besides bcrypt (default). You can use
|
||||
@@ -159,10 +169,6 @@ Devise.setup do |config|
|
||||
# Defines name of the authentication token params key
|
||||
# config.token_authentication_key = :auth_token
|
||||
|
||||
# If true, authentication through token does not store user in session and needs
|
||||
# to be supplied on each request. Useful if you are using the token as API token.
|
||||
# config.stateless_token = false
|
||||
|
||||
# ==> Scopes configuration
|
||||
# Turn scoped views on. Before rendering "sessions/new", it will first check for
|
||||
# "users/sessions/new". It's turned off by default because it's slower if you
|
||||
|
||||
@@ -45,10 +45,12 @@ class HelpersTest < ActionController::TestCase
|
||||
@controller.send :require_no_authentication
|
||||
end
|
||||
|
||||
test 'require no authentication skips if no inputs are available' do
|
||||
test 'require no authentication only checks if already authenticated if no inputs strategies are available' do
|
||||
Devise.mappings[:user].expects(:no_input_strategies).returns([])
|
||||
@mock_warden.expects(:authenticate?).never
|
||||
@controller.expects(:redirect_to).never
|
||||
@mock_warden.expects(:authenticated?).with(:user).once.returns(true)
|
||||
@mock_warden.expects(:user).with(:user).returns(User.new)
|
||||
@controller.expects(:redirect_to).with(root_path)
|
||||
@controller.send :require_no_authentication
|
||||
end
|
||||
|
||||
|
||||
19
test/delegator_test.rb
Normal file
19
test/delegator_test.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
require 'test_helper'
|
||||
|
||||
class DelegatorTest < ActiveSupport::TestCase
|
||||
def delegator
|
||||
Devise::Delegator.new
|
||||
end
|
||||
|
||||
test 'failure_app returns default failure app if no warden options in env' do
|
||||
assert_equal Devise::FailureApp, delegator.failure_app({})
|
||||
end
|
||||
|
||||
test 'failure_app returns default failure app if no scope in warden options' do
|
||||
assert_equal Devise::FailureApp, delegator.failure_app({"warden.options" => {}})
|
||||
end
|
||||
|
||||
test 'failure_app returns associated failure app by scope in the given environment' do
|
||||
assert_kind_of Proc, delegator.failure_app({"warden.options" => {:scope => "manager"}})
|
||||
end
|
||||
end
|
||||
@@ -12,8 +12,8 @@ end
|
||||
|
||||
class DeviseTest < ActiveSupport::TestCase
|
||||
test 'model options can be configured through Devise' do
|
||||
swap Devise, :confirm_within => 113, :pepper => "foo" do
|
||||
assert_equal 113, Devise.confirm_within
|
||||
swap Devise, :allow_unconfirmed_access_for => 113, :pepper => "foo" do
|
||||
assert_equal 113, Devise.allow_unconfirmed_access_for
|
||||
assert_equal "foo", Devise.pepper
|
||||
end
|
||||
end
|
||||
|
||||
@@ -98,7 +98,7 @@ class ConfirmationTest < ActionController::IntegrationTest
|
||||
end
|
||||
|
||||
test 'not confirmed user with setup to block without confirmation should not be able to sign in' do
|
||||
swap Devise, :confirm_within => 0.days do
|
||||
swap Devise, :allow_unconfirmed_access_for => 0.days do
|
||||
sign_in_as_user(:confirm => false)
|
||||
|
||||
assert_contain 'You have to confirm your account before continuing'
|
||||
@@ -107,7 +107,7 @@ class ConfirmationTest < ActionController::IntegrationTest
|
||||
end
|
||||
|
||||
test 'not confirmed user should not see confirmation message if invalid credentials are given' do
|
||||
swap Devise, :confirm_within => 0.days do
|
||||
swap Devise, :allow_unconfirmed_access_for => 0.days do
|
||||
sign_in_as_user(:confirm => false) do
|
||||
fill_in 'password', :with => 'invalid'
|
||||
end
|
||||
@@ -118,7 +118,7 @@ class ConfirmationTest < ActionController::IntegrationTest
|
||||
end
|
||||
|
||||
test 'not confirmed user but configured with some days to confirm should be able to sign in' do
|
||||
swap Devise, :confirm_within => 1.day do
|
||||
swap Devise, :allow_unconfirmed_access_for => 1.day do
|
||||
sign_in_as_user(:confirm => false)
|
||||
|
||||
assert_response :success
|
||||
@@ -201,3 +201,55 @@ class ConfirmationTest < ActionController::IntegrationTest
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ConfirmationOnChangeTest < ActionController::IntegrationTest
|
||||
def create_second_admin(options={})
|
||||
@admin = nil
|
||||
create_admin(options)
|
||||
end
|
||||
|
||||
def visit_admin_confirmation_with_token(confirmation_token)
|
||||
visit admin_confirmation_path(:confirmation_token => confirmation_token)
|
||||
end
|
||||
|
||||
test 'admin should be able to request a new confirmation after email changed' do
|
||||
admin = create_admin
|
||||
admin.update_attributes(:email => 'new_test@example.com')
|
||||
|
||||
visit new_admin_session_path
|
||||
click_link "Didn't receive confirmation instructions?"
|
||||
|
||||
fill_in 'email', :with => admin.unconfirmed_email
|
||||
assert_difference "ActionMailer::Base.deliveries.size" do
|
||||
click_button 'Resend confirmation instructions'
|
||||
end
|
||||
|
||||
assert_current_url '/admin_area/sign_in'
|
||||
assert_contain 'You will receive an email with instructions about how to confirm your account in a few minutes'
|
||||
end
|
||||
|
||||
test 'admin with valid confirmation token should be able to confirm email after email changed' do
|
||||
admin = create_admin
|
||||
admin.update_attributes(:email => 'new_test@example.com')
|
||||
assert_equal 'new_test@example.com', admin.unconfirmed_email
|
||||
visit_admin_confirmation_with_token(admin.confirmation_token)
|
||||
|
||||
assert_contain 'Your account was successfully confirmed.'
|
||||
assert_current_url '/admin_area/home'
|
||||
assert admin.reload.confirmed?
|
||||
assert_not admin.reload.pending_reconfirmation?
|
||||
end
|
||||
|
||||
test 'admin email should be unique also within unconfirmed_email' do
|
||||
admin = create_admin
|
||||
admin.update_attributes(:email => 'new_admin_test@example.com')
|
||||
assert_equal 'new_admin_test@example.com', admin.unconfirmed_email
|
||||
|
||||
create_second_admin(:email => "new_admin_test@example.com")
|
||||
|
||||
visit_admin_confirmation_with_token(admin.confirmation_token)
|
||||
assert_have_selector '#error_explanation'
|
||||
assert_contain /Email.*already.*taken/
|
||||
assert admin.reload.pending_reconfirmation?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,9 +12,24 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
|
||||
|
||||
test 'sign in should authenticate with http' do
|
||||
sign_in_as_new_user_with_http
|
||||
assert_response :success
|
||||
assert_response 200
|
||||
assert_match '<email>user@test.com</email>', response.body
|
||||
assert warden.authenticated?(:user)
|
||||
|
||||
get users_path(:format => :xml)
|
||||
assert_response 200
|
||||
end
|
||||
|
||||
test 'sign in should authenticate with http but not emit a cookie if skipping session storage' do
|
||||
swap Devise, :skip_session_storage => [:http_auth] do
|
||||
sign_in_as_new_user_with_http
|
||||
assert_response 200
|
||||
assert_match '<email>user@test.com</email>', response.body
|
||||
assert warden.authenticated?(:user)
|
||||
|
||||
get users_path(:format => :xml)
|
||||
assert_response 401
|
||||
end
|
||||
end
|
||||
|
||||
test 'returns a custom response with www-authenticate header on failures' do
|
||||
|
||||
@@ -80,16 +80,16 @@ class LockTest < ActionController::IntegrationTest
|
||||
|
||||
visit_user_unlock_with_token(user.unlock_token)
|
||||
|
||||
assert_current_url '/'
|
||||
assert_current_url "/users/sign_in"
|
||||
assert_contain 'Your account was successfully unlocked.'
|
||||
|
||||
assert_not user.reload.access_locked?
|
||||
end
|
||||
|
||||
test "sign in user automatically after unlocking its account" do
|
||||
test "redirect user to sign in page after unlocking its account" do
|
||||
user = create_user(:locked => true)
|
||||
visit_user_unlock_with_token(user.unlock_token)
|
||||
assert warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test "user should not be able to sign in when locked" do
|
||||
|
||||
@@ -13,7 +13,7 @@ class RegistrationTest < ActionController::IntegrationTest
|
||||
fill_in 'password confirmation', :with => 'new_user123'
|
||||
click_button 'Sign up'
|
||||
|
||||
assert_contain 'Welcome! You have signed up successfully.'
|
||||
assert_contain 'You have signed up successfully'
|
||||
assert warden.authenticated?(:admin)
|
||||
assert_current_url "/admin_area/home"
|
||||
|
||||
@@ -291,3 +291,34 @@ class RegistrationTest < ActionController::IntegrationTest
|
||||
assert_equal User.count, 0
|
||||
end
|
||||
end
|
||||
|
||||
class ReconfirmableRegistrationTest < ActionController::IntegrationTest
|
||||
test 'a signed in admin should see a more appropriate flash message when editing his account if reconfirmable is enabled' do
|
||||
sign_in_as_admin
|
||||
get edit_admin_registration_path
|
||||
|
||||
fill_in 'email', :with => 'admin.new@example.com'
|
||||
fill_in 'current password', :with => '123456'
|
||||
click_button 'Update'
|
||||
|
||||
assert_current_url '/admin_area/home'
|
||||
assert_contain 'but we need to verify your new email address'
|
||||
|
||||
assert_equal "admin.new@example.com", Admin.first.unconfirmed_email
|
||||
end
|
||||
|
||||
test 'a signed in admin should not see a reconfirmation message if they did not change their password' do
|
||||
sign_in_as_admin
|
||||
get edit_admin_registration_path
|
||||
|
||||
fill_in 'password', :with => 'pas123'
|
||||
fill_in 'password confirmation', :with => 'pas123'
|
||||
fill_in 'current password', :with => '123456'
|
||||
click_button 'Update'
|
||||
|
||||
assert_current_url '/admin_area/home'
|
||||
assert_contain 'You updated your account successfully.'
|
||||
|
||||
assert Admin.first.valid_password?('pas123')
|
||||
end
|
||||
end
|
||||
@@ -9,14 +9,6 @@ class RememberMeTest < ActionController::IntegrationTest
|
||||
user
|
||||
end
|
||||
|
||||
def create_admin_and_remember
|
||||
admin = create_admin
|
||||
admin.remember_me!
|
||||
raw_cookie = Admin.serialize_into_cookie(admin)
|
||||
cookies['remember_admin_token'] = generate_signed_cookie(raw_cookie)
|
||||
admin
|
||||
end
|
||||
|
||||
def generate_signed_cookie(raw_cookie)
|
||||
request = ActionDispatch::TestRequest.new
|
||||
request.cookie_jar.signed['raw_cookie'] = raw_cookie
|
||||
@@ -117,34 +109,6 @@ class RememberMeTest < ActionController::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
test 'if both extend_remember_period and remember_across_browsers are true, sends the same token with a new expire date' do
|
||||
swap Devise, :remember_across_browsers => true, :extend_remember_period => true, :remember_for => 1.year do
|
||||
admin = create_admin_and_remember
|
||||
token = admin.remember_token
|
||||
|
||||
admin.remember_created_at = old = 10.minutes.ago
|
||||
admin.save!
|
||||
|
||||
get root_path
|
||||
assert (cookie_expires("remember_admin_token") - 1.year) > (old + 5.minutes)
|
||||
assert_equal token, signed_cookie("remember_admin_token").last
|
||||
end
|
||||
end
|
||||
|
||||
test 'if both extend_remember_period and remember_across_browsers are false, sends a new token with old expire date' do
|
||||
swap Devise, :remember_across_browsers => false, :extend_remember_period => false, :remember_for => 1.year do
|
||||
admin = create_admin_and_remember
|
||||
token = admin.remember_token
|
||||
|
||||
admin.remember_created_at = old = 10.minutes.ago
|
||||
admin.save!
|
||||
|
||||
get root_path
|
||||
assert (cookie_expires("remember_admin_token") - 1.year) < (old + 5.minutes)
|
||||
assert_not_equal token, signed_cookie("remember_admin_token").last
|
||||
end
|
||||
end
|
||||
|
||||
test 'do not remember other scopes' do
|
||||
user = create_user_and_remember
|
||||
get root_path
|
||||
@@ -182,20 +146,6 @@ class RememberMeTest < ActionController::IntegrationTest
|
||||
assert_not warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test 'do not remember the admin anymore after forget' do
|
||||
admin = create_admin_and_remember
|
||||
get root_path
|
||||
assert warden.authenticated?(:admin)
|
||||
|
||||
get destroy_admin_session_path
|
||||
assert_not warden.authenticated?(:admin)
|
||||
assert_nil admin.reload.remember_token
|
||||
assert_nil warden.cookies['remember_admin_token']
|
||||
|
||||
get root_path
|
||||
assert_not warden.authenticated?(:admin)
|
||||
end
|
||||
|
||||
test 'changing user password expires remember me token' do
|
||||
user = create_user_and_remember
|
||||
user.password = "another_password"
|
||||
|
||||
@@ -25,7 +25,7 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
|
||||
end
|
||||
|
||||
test 'authenticate with valid authentication token key but does not store if stateless' do
|
||||
swap Devise, :token_authentication_key => :secret_token, :stateless_token => true do
|
||||
swap Devise, :token_authentication_key => :secret_token, :skip_session_storage => [:token_auth] do
|
||||
sign_in_as_new_user_with_token
|
||||
assert warden.authenticated?(:user)
|
||||
|
||||
@@ -88,7 +88,7 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
|
||||
end
|
||||
|
||||
test 'authenticate with valid authentication token key and do not store if stateless and timeoutable are enabled' do
|
||||
swap Devise, :token_authentication_key => :secret_token, :stateless_token => true, :timeout_in => (0.1).second do
|
||||
swap Devise, :token_authentication_key => :secret_token, :skip_session_storage => [:token_auth], :timeout_in => (0.1).second do
|
||||
user = sign_in_as_new_user_with_token
|
||||
assert warden.authenticated?(:user)
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ class TrackableHooksTest < ActionController::IntegrationTest
|
||||
end
|
||||
|
||||
test "does not update anything if user has signed out along the way" do
|
||||
swap Devise, :confirm_within => 0 do
|
||||
swap Devise, :allow_unconfirmed_access_for => 0 do
|
||||
user = create_user(:confirm => false)
|
||||
sign_in_as_user
|
||||
|
||||
|
||||
@@ -51,12 +51,12 @@ class MappingTest < ActiveSupport::TestCase
|
||||
|
||||
test 'has strategies depending on the model declaration' do
|
||||
assert_equal [:rememberable, :token_authenticatable, :database_authenticatable], Devise.mappings[:user].strategies
|
||||
assert_equal [:rememberable, :database_authenticatable], Devise.mappings[:admin].strategies
|
||||
assert_equal [:database_authenticatable], Devise.mappings[:admin].strategies
|
||||
end
|
||||
|
||||
test 'has no input strategies depending on the model declaration' do
|
||||
assert_equal [:rememberable, :token_authenticatable], Devise.mappings[:user].no_input_strategies
|
||||
assert_equal [:rememberable], Devise.mappings[:admin].no_input_strategies
|
||||
assert_equal [], Devise.mappings[:admin].no_input_strategies
|
||||
end
|
||||
|
||||
test 'find scope for a given object' do
|
||||
@@ -108,7 +108,6 @@ class MappingTest < ActiveSupport::TestCase
|
||||
assert mapping.authenticatable?
|
||||
assert mapping.recoverable?
|
||||
assert mapping.lockable?
|
||||
assert_not mapping.confirmable?
|
||||
assert_not mapping.omniauthable?
|
||||
end
|
||||
|
||||
|
||||
@@ -80,8 +80,8 @@ class ConfirmableTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test 'should send confirmation instructions by email' do
|
||||
assert_email_sent do
|
||||
create_user
|
||||
assert_email_sent "mynewuser@example.com" do
|
||||
create_user :email => "mynewuser@example.com"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -123,7 +123,7 @@ class ConfirmableTest < ActiveSupport::TestCase
|
||||
|
||||
test 'should send email instructions for the user confirm its email' do
|
||||
user = create_user
|
||||
assert_email_sent do
|
||||
assert_email_sent user.email do
|
||||
User.send_confirmation_instructions(:email => user.email)
|
||||
end
|
||||
end
|
||||
@@ -164,19 +164,19 @@ class ConfirmableTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test 'confirm time should fallback to devise confirm in default configuration' do
|
||||
swap Devise, :confirm_within => 1.day do
|
||||
swap Devise, :allow_unconfirmed_access_for => 1.day do
|
||||
user = new_user
|
||||
user.confirmation_sent_at = 2.days.ago
|
||||
assert_not user.active_for_authentication?
|
||||
|
||||
Devise.confirm_within = 3.days
|
||||
Devise.allow_unconfirmed_access_for = 3.days
|
||||
assert user.active_for_authentication?
|
||||
end
|
||||
end
|
||||
|
||||
test 'should be active when confirmation sent at is not overpast' do
|
||||
swap Devise, :confirm_within => 5.days do
|
||||
Devise.confirm_within = 5.days
|
||||
swap Devise, :allow_unconfirmed_access_for => 5.days do
|
||||
Devise.allow_unconfirmed_access_for = 5.days
|
||||
user = create_user
|
||||
|
||||
user.confirmation_sent_at = 4.days.ago
|
||||
@@ -198,7 +198,7 @@ class ConfirmableTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test 'should not be active when confirm in is zero' do
|
||||
Devise.confirm_within = 0.days
|
||||
Devise.allow_unconfirmed_access_for = 0.days
|
||||
user = create_user
|
||||
user.confirmation_sent_at = Date.today
|
||||
assert_not user.active_for_authentication?
|
||||
@@ -236,3 +236,81 @@ class ConfirmableTest < ActiveSupport::TestCase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ReconfirmableTest < ActiveSupport::TestCase
|
||||
test 'should generate confirmation token after changing email' do
|
||||
admin = create_admin
|
||||
assert admin.confirm!
|
||||
assert_nil admin.confirmation_token
|
||||
assert admin.update_attributes(:email => 'new_test@example.com')
|
||||
assert_not_nil admin.confirmation_token
|
||||
end
|
||||
|
||||
test 'should send confirmation instructions by email after changing email' do
|
||||
admin = create_admin
|
||||
assert admin.confirm!
|
||||
assert_email_sent "new_test@example.com" do
|
||||
assert admin.update_attributes(:email => 'new_test@example.com')
|
||||
end
|
||||
end
|
||||
|
||||
test 'should not send confirmation by email after changing password' do
|
||||
admin = create_admin
|
||||
assert admin.confirm!
|
||||
assert_email_not_sent do
|
||||
assert admin.update_attributes(:password => 'newpass', :password_confirmation => 'newpass')
|
||||
end
|
||||
end
|
||||
|
||||
test 'should stay confirmed when email is changed' do
|
||||
admin = create_admin
|
||||
assert admin.confirm!
|
||||
assert admin.update_attributes(:email => 'new_test@example.com')
|
||||
assert admin.confirmed?
|
||||
end
|
||||
|
||||
test 'should update email only when it is confirmed' do
|
||||
admin = create_admin
|
||||
assert admin.confirm!
|
||||
assert admin.update_attributes(:email => 'new_test@example.com')
|
||||
assert_not_equal 'new_test@example.com', admin.email
|
||||
assert admin.confirm!
|
||||
assert_equal 'new_test@example.com', admin.email
|
||||
end
|
||||
|
||||
test 'should not allow admin to get past confirmation email by resubmitting their new address' do
|
||||
admin = create_admin
|
||||
assert admin.confirm!
|
||||
assert admin.update_attributes(:email => 'new_test@example.com')
|
||||
assert_not_equal 'new_test@example.com', admin.email
|
||||
assert admin.update_attributes(:email => 'new_test@example.com')
|
||||
assert_not_equal 'new_test@example.com', admin.email
|
||||
end
|
||||
|
||||
test 'should find a admin by send confirmation instructions with unconfirmed_email' do
|
||||
admin = create_admin
|
||||
assert admin.confirm!
|
||||
assert admin.update_attributes(:email => 'new_test@example.com')
|
||||
confirmation_admin = Admin.send_confirmation_instructions(:email => admin.unconfirmed_email)
|
||||
assert_equal confirmation_admin, admin
|
||||
end
|
||||
|
||||
test 'should return a new admin if no email or unconfirmed_email was found' do
|
||||
confirmation_admin = Admin.send_confirmation_instructions(:email => "invalid@email.com")
|
||||
assert_not confirmation_admin.persisted?
|
||||
end
|
||||
|
||||
test 'should add error to new admin email if no email or unconfirmed_email was found' do
|
||||
confirmation_admin = Admin.send_confirmation_instructions(:email => "invalid@email.com")
|
||||
assert confirmation_admin.errors[:email]
|
||||
assert_equal "not found", confirmation_admin.errors[:email].join
|
||||
end
|
||||
|
||||
test 'should find admin with email in unconfirmed_emails' do
|
||||
admin = create_admin
|
||||
admin.unconfirmed_email = "new_test@email.com"
|
||||
assert admin.save
|
||||
admin = Admin.find_by_unconfirmed_email_with_errors(:email => "new_test@email.com")
|
||||
assert admin.persisted?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,7 +31,7 @@ class EncryptableTest < ActiveSupport::TestCase
|
||||
|
||||
test 'should generate a base64 hash using SecureRandom for password salt' do
|
||||
swap_with_encryptor Admin, :sha1 do
|
||||
SecureRandom.expects(:base64).with(15).returns('01lI')
|
||||
SecureRandom.expects(:base64).with(15).returns('01lI').twice
|
||||
salt = create_admin.password_salt
|
||||
assert_not_equal '01lI', salt
|
||||
assert_equal 4, salt.size
|
||||
|
||||
@@ -195,31 +195,4 @@ class RecoverableTest < ActiveSupport::TestCase
|
||||
assert_equal "has expired, please request a new one", reset_password_user.errors[:reset_password_token].join
|
||||
end
|
||||
end
|
||||
|
||||
test 'should save the model when the reset_password_sent_at doesnt exist' do
|
||||
user = create_user
|
||||
def user.respond_to?(meth, *)
|
||||
if meth == :reset_password_sent_at=
|
||||
false
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
user.send_reset_password_instructions
|
||||
user.reload
|
||||
assert_not_nil user.reset_password_token
|
||||
end
|
||||
|
||||
test 'should have valid period if does not respond to reset_password_sent_at' do
|
||||
user = create_user
|
||||
def user.respond_to?(meth, *)
|
||||
if meth == :reset_password_sent_at
|
||||
false
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
assert user.reset_password_period_valid?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,7 +1,46 @@
|
||||
require 'test_helper'
|
||||
|
||||
module SharedRememberableTest
|
||||
extend ActiveSupport::Testing::Declarative
|
||||
class RememberableTest < ActiveSupport::TestCase
|
||||
def resource_class
|
||||
User
|
||||
end
|
||||
|
||||
def create_resource
|
||||
create_user
|
||||
end
|
||||
|
||||
test 'remember_me should not generate a new token if using salt' do
|
||||
user = create_user
|
||||
user.expects(:valid?).never
|
||||
user.remember_me!
|
||||
end
|
||||
|
||||
test 'forget_me should not clear remember token if using salt' do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
user.expects(:valid?).never
|
||||
user.forget_me!
|
||||
end
|
||||
|
||||
test 'serialize into cookie' do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
assert_equal [user.to_key, user.authenticatable_salt], User.serialize_into_cookie(user)
|
||||
end
|
||||
|
||||
test 'serialize from cookie' do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
assert_equal user, User.serialize_from_cookie(user.to_key, user.authenticatable_salt)
|
||||
end
|
||||
|
||||
test 'raises a RuntimeError if authenticatable_salt is nil' do
|
||||
user = User.new
|
||||
user.encrypted_password = nil
|
||||
assert_raise RuntimeError do
|
||||
user.rememberable_value
|
||||
end
|
||||
end
|
||||
|
||||
test 'should respond to remember_me attribute' do
|
||||
assert resource_class.new.respond_to?(:remember_me)
|
||||
@@ -127,161 +166,3 @@ module SharedRememberableTest
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class RememberableTest < ActiveSupport::TestCase
|
||||
include SharedRememberableTest
|
||||
|
||||
def resource_class
|
||||
Admin
|
||||
end
|
||||
|
||||
def create_resource
|
||||
create_admin
|
||||
end
|
||||
|
||||
test 'remember_me should generate a new token and save the record without validating' do
|
||||
admin = create_admin
|
||||
admin.expects(:valid?).never
|
||||
token = admin.remember_token
|
||||
admin.remember_me!
|
||||
assert_not_equal token, admin.remember_token
|
||||
assert_not admin.changed?
|
||||
end
|
||||
|
||||
test 'forget_me should clear remember token and save the record without validating' do
|
||||
admin = create_admin
|
||||
admin.remember_me!
|
||||
assert_not admin.remember_token.nil?
|
||||
admin.expects(:valid?).never
|
||||
admin.forget_me!
|
||||
assert admin.remember_token.nil?
|
||||
assert_not admin.changed?
|
||||
end
|
||||
|
||||
test 'serialize into cookie' do
|
||||
admin = create_admin
|
||||
admin.remember_me!
|
||||
assert_equal [admin.to_key, admin.remember_token], Admin.serialize_into_cookie(admin)
|
||||
end
|
||||
|
||||
test 'serialize from cookie' do
|
||||
admin = create_admin
|
||||
admin.remember_me!
|
||||
assert_equal admin, Admin.serialize_from_cookie(admin.to_key, admin.remember_token)
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is true, remember_me! should create a new token if no token exists' do
|
||||
swap Devise, :remember_across_browsers => true, :remember_for => 1.year do
|
||||
admin = create_admin
|
||||
assert_equal nil, admin.remember_token
|
||||
admin.remember_me!
|
||||
assert_not_equal nil, admin.remember_token
|
||||
end
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is true, remember_me! should create a new token if a token exists but has expired' do
|
||||
swap Devise, :remember_across_browsers => true, :remember_for => 1.day do
|
||||
admin = create_admin
|
||||
admin.remember_me!
|
||||
admin.remember_created_at = 2.days.ago
|
||||
admin.save
|
||||
token = admin.remember_token
|
||||
admin.remember_me!
|
||||
assert_not_equal token, admin.remember_token
|
||||
end
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is true, remember_me! should not create a new token if a token exists and has not expired' do
|
||||
swap Devise, :remember_across_browsers => true, :remember_for => 2.days do
|
||||
admin = create_admin
|
||||
admin.remember_me!
|
||||
admin.remember_created_at = 1.day.ago
|
||||
admin.save
|
||||
token = admin.remember_token
|
||||
admin.remember_me!
|
||||
assert_equal token, admin.remember_token
|
||||
end
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is false, remember_me! should create a new token if no token exists' do
|
||||
swap Devise, :remember_across_browsers => false do
|
||||
admin = create_admin
|
||||
assert_equal nil, admin.remember_token
|
||||
admin.remember_me!
|
||||
assert_not_equal nil, admin.remember_token
|
||||
end
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is false, remember_me! should create a new token if a token exists but has expired' do
|
||||
swap Devise, :remember_across_browsers => false, :remember_for => 1.day do
|
||||
admin = create_admin
|
||||
admin.remember_me!
|
||||
admin.remember_created_at = 2.days.ago
|
||||
admin.save
|
||||
token = admin.remember_token
|
||||
admin.remember_me!
|
||||
assert_not_equal token, admin.remember_token
|
||||
end
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is false, remember_me! should create a new token if a token exists and has not expired' do
|
||||
swap Devise, :remember_across_browsers => false, :remember_for => 2.days do
|
||||
admin = create_admin
|
||||
admin.remember_me!
|
||||
admin.remember_created_at = 1.day.ago
|
||||
admin.save
|
||||
token = admin.remember_token
|
||||
admin.remember_me!
|
||||
assert_not_equal token, admin.remember_token
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class WithSaltRememberableTest < ActiveSupport::TestCase
|
||||
include SharedRememberableTest
|
||||
|
||||
setup do
|
||||
assert_not User.new.respond_to?(:remember_token)
|
||||
end
|
||||
|
||||
def resource_class
|
||||
User
|
||||
end
|
||||
|
||||
def create_resource
|
||||
create_user
|
||||
end
|
||||
|
||||
test 'remember_me should not generate a new token if using salt' do
|
||||
user = create_user
|
||||
user.expects(:valid?).never
|
||||
user.remember_me!
|
||||
end
|
||||
|
||||
test 'forget_me should not clear remember token if using salt' do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
user.expects(:valid?).never
|
||||
user.forget_me!
|
||||
end
|
||||
|
||||
test 'serialize into cookie' do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
assert_equal [user.to_key, user.authenticatable_salt], User.serialize_into_cookie(user)
|
||||
end
|
||||
|
||||
test 'serialize from cookie' do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
assert_equal user, User.serialize_from_cookie(user.to_key, user.authenticatable_salt)
|
||||
end
|
||||
|
||||
test 'raises a RuntimeError if authenticatable_salt is nil' do
|
||||
user = User.new
|
||||
user.encrypted_password = nil
|
||||
assert_raise RuntimeError do
|
||||
user.rememberable_value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,7 +16,7 @@ class SerializableTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test 'should include unsafe keys on XML if a force_except is provided' do
|
||||
assert_no_match /email/, @user.to_xml(:force_except => :email)
|
||||
assert_no_match /<email/, @user.to_xml(:force_except => :email)
|
||||
assert_match /confirmation-token/, @user.to_xml(:force_except => :email)
|
||||
end
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ require 'test_helper'
|
||||
|
||||
class Configurable < User
|
||||
devise :database_authenticatable, :encryptable, :confirmable, :rememberable, :timeoutable, :lockable,
|
||||
:stretches => 15, :pepper => 'abcdef', :confirm_within => 5.days,
|
||||
:stretches => 15, :pepper => 'abcdef', :allow_unconfirmed_access_for => 5.days,
|
||||
:remember_for => 7.days, :timeout_in => 15.minutes, :unlock_in => 10.days
|
||||
end
|
||||
|
||||
@@ -39,7 +39,7 @@ class ActiveRecordTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test 'can cherry pick modules' do
|
||||
assert_include_modules Admin, :database_authenticatable, :registerable, :timeoutable, :recoverable, :lockable, :rememberable, :encryptable
|
||||
assert_include_modules Admin, :database_authenticatable, :registerable, :timeoutable, :recoverable, :lockable, :encryptable, :confirmable
|
||||
end
|
||||
|
||||
test 'validations options are not applied too late' do
|
||||
@@ -55,12 +55,12 @@ class ActiveRecordTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test 'chosen modules are inheritable' do
|
||||
assert_include_modules Inheritable, :database_authenticatable, :registerable, :timeoutable, :recoverable, :lockable, :rememberable, :encryptable
|
||||
assert_include_modules Inheritable, :database_authenticatable, :registerable, :timeoutable, :recoverable, :lockable, :encryptable, :confirmable
|
||||
end
|
||||
|
||||
test 'order of module inclusion' do
|
||||
correct_module_order = [:database_authenticatable, :rememberable, :encryptable, :recoverable, :registerable, :lockable, :timeoutable]
|
||||
incorrect_module_order = [:database_authenticatable, :timeoutable, :registerable, :recoverable, :lockable, :encryptable, :rememberable]
|
||||
correct_module_order = [:database_authenticatable, :encryptable, :recoverable, :registerable, :confirmable, :lockable, :timeoutable]
|
||||
incorrect_module_order = [:database_authenticatable, :timeoutable, :registerable, :recoverable, :lockable, :encryptable, :confirmable]
|
||||
|
||||
assert_include_modules Admin, *incorrect_module_order
|
||||
|
||||
@@ -87,8 +87,8 @@ class ActiveRecordTest < ActiveSupport::TestCase
|
||||
assert_equal 'abcdef', Configurable.pepper
|
||||
end
|
||||
|
||||
test 'set a default value for confirm_within' do
|
||||
assert_equal 5.days, Configurable.confirm_within
|
||||
test 'set a default value for allow_unconfirmed_access_for' do
|
||||
assert_equal 5.days, Configurable.allow_unconfirmed_access_for
|
||||
end
|
||||
|
||||
test 'set a default value for remember_for' do
|
||||
|
||||
21
test/path_checker_test.rb
Normal file
21
test/path_checker_test.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
require 'test_helper'
|
||||
|
||||
class PathCheckerTest < ActiveSupport::TestCase
|
||||
test 'check if sign out path matches' do
|
||||
path_checker = Devise::PathChecker.new({"PATH_INFO" => "/users/sign_out"}, :user)
|
||||
assert path_checker.signing_out?
|
||||
|
||||
path_checker = Devise::PathChecker.new({"PATH_INFO" => "/users/sign_in"}, :user)
|
||||
assert_not path_checker.signing_out?
|
||||
end
|
||||
|
||||
test 'considers script name' do
|
||||
path_checker = Devise::PathChecker.new({"SCRIPT_NAME" => "/users", "PATH_INFO" => "/sign_out"}, :user)
|
||||
assert path_checker.signing_out?
|
||||
end
|
||||
|
||||
test 'ignores invalid routes' do
|
||||
path_checker = Devise::PathChecker.new({"PATH_INFO" => "/users/sign_in"}, :omg)
|
||||
assert_not path_checker.signing_out?
|
||||
end
|
||||
end
|
||||
@@ -5,5 +5,26 @@ class Admin
|
||||
include Shim
|
||||
include SharedAdmin
|
||||
|
||||
field :remember_token, :type => String
|
||||
## Database authenticatable
|
||||
field :email, :type => String, :null => true
|
||||
field :encrypted_password, :type => String, :null => true
|
||||
|
||||
## Recoverable
|
||||
field :reset_password_token, :type => String
|
||||
field :reset_password_sent_at, :type => Time
|
||||
|
||||
## Rememberable
|
||||
field :remember_created_at, :type => Time
|
||||
|
||||
## Confirmable
|
||||
field :confirmation_token, :type => String
|
||||
field :confirmed_at, :type => Time
|
||||
field :confirmation_sent_at, :type => Time
|
||||
field :unconfirmed_email, :type => String # Only if using reconfirmable
|
||||
|
||||
## Encryptable
|
||||
field :password_salt, :type => String
|
||||
|
||||
## Lockable
|
||||
field :locked_at, :type => Time
|
||||
end
|
||||
|
||||
@@ -7,4 +7,39 @@ class User
|
||||
|
||||
field :username, :type => String
|
||||
field :facebook_token, :type => String
|
||||
|
||||
## Database authenticatable
|
||||
field :email, :type => String, :null => false, :default => ""
|
||||
field :encrypted_password, :type => String, :null => false, :default => ""
|
||||
|
||||
## Recoverable
|
||||
field :reset_password_token, :type => String
|
||||
field :reset_password_sent_at, :type => Time
|
||||
|
||||
## Rememberable
|
||||
field :remember_created_at, :type => Time
|
||||
|
||||
## Trackable
|
||||
field :sign_in_count, :type => Integer, :default => 0
|
||||
field :current_sign_in_at, :type => Time
|
||||
field :last_sign_in_at, :type => Time
|
||||
field :current_sign_in_ip, :type => String
|
||||
field :last_sign_in_ip, :type => String
|
||||
|
||||
## Encryptable
|
||||
# field :password_salt, :type => String
|
||||
|
||||
## Confirmable
|
||||
field :confirmation_token, :type => String
|
||||
field :confirmed_at, :type => Time
|
||||
field :confirmation_sent_at, :type => Time
|
||||
# field :unconfirmed_email, :type => String # Only if using reconfirmable
|
||||
|
||||
## Lockable
|
||||
field :failed_attempts, :type => Integer, :default => 0 # Only if lock strategy is :failed_attempts
|
||||
field :unlock_token, :type => String # Only if unlock strategy is :email or :both
|
||||
field :locked_at, :type => Time
|
||||
|
||||
# Token authenticatable
|
||||
field :authentication_token, :type => String
|
||||
end
|
||||
|
||||
@@ -12,6 +12,9 @@ Devise.setup do |config|
|
||||
# Configure the class responsible to send e-mails.
|
||||
# config.mailer = "Devise::Mailer"
|
||||
|
||||
# Disable apply schema
|
||||
config.apply_schema = false
|
||||
|
||||
# ==> ORM configuration
|
||||
# Load and configure the ORM. Supports :active_record (default) and
|
||||
# :mongoid (bson_ext recommended) by default. Other ORMs may be
|
||||
@@ -60,16 +63,16 @@ Devise.setup do |config|
|
||||
# ==> Configuration for :database_authenticatable
|
||||
# For bcrypt, this is the cost for hashing the password and defaults to 10. If
|
||||
# using other encryptors, it sets how many times you want the password re-encrypted.
|
||||
config.stretches = 10
|
||||
config.stretches = Rails.env.test? ? 1 : 10
|
||||
|
||||
# ==> Configuration for :confirmable
|
||||
# The time you want to give your user to confirm his account. During this time
|
||||
# he will be able to access your application without confirming. Default is nil.
|
||||
# When confirm_within is zero, the user won't be able to sign in without confirming.
|
||||
# When allow_unconfirmed_access_for is zero, the user won't be able to sign in without confirming.
|
||||
# You can use this to let your user access some features of your application
|
||||
# without confirming the account, but blocking it after a certain period
|
||||
# (ie 2 days).
|
||||
# config.confirm_within = 2.days
|
||||
# config.allow_unconfirmed_access_for = 2.days
|
||||
|
||||
# Defines which key will be used when confirming an account
|
||||
# config.confirmation_keys = [ :email ]
|
||||
@@ -148,10 +151,6 @@ Devise.setup do |config|
|
||||
# Defines name of the authentication token params key
|
||||
# config.token_authentication_key = :auth_token
|
||||
|
||||
# If true, authentication through token does not store user in session and needs
|
||||
# to be supplied on each request. Useful if you are using the token as API token.
|
||||
# config.stateless_token = false
|
||||
|
||||
# ==> Scopes configuration
|
||||
# Turn scoped views on. Before rendering "sessions/new", it will first check for
|
||||
# "users/sessions/new". It's turned off by default because it's slower if you
|
||||
|
||||
@@ -4,22 +4,68 @@ class CreateTables < ActiveRecord::Migration
|
||||
t.string :username
|
||||
t.string :facebook_token
|
||||
|
||||
t.database_authenticatable :null => false
|
||||
t.confirmable
|
||||
t.recoverable
|
||||
t.rememberable
|
||||
t.trackable
|
||||
t.lockable
|
||||
t.token_authenticatable
|
||||
## Database authenticatable
|
||||
t.string :email, :null => false, :default => ""
|
||||
t.string :encrypted_password, :null => false, :default => ""
|
||||
|
||||
## Recoverable
|
||||
t.string :reset_password_token
|
||||
t.datetime :reset_password_sent_at
|
||||
|
||||
## Rememberable
|
||||
t.datetime :remember_created_at
|
||||
|
||||
## Trackable
|
||||
t.integer :sign_in_count, :default => 0
|
||||
t.datetime :current_sign_in_at
|
||||
t.datetime :last_sign_in_at
|
||||
t.string :current_sign_in_ip
|
||||
t.string :last_sign_in_ip
|
||||
|
||||
## Encryptable
|
||||
# t.string :password_salt
|
||||
|
||||
## Confirmable
|
||||
t.string :confirmation_token
|
||||
t.datetime :confirmed_at
|
||||
t.datetime :confirmation_sent_at
|
||||
# t.string :unconfirmed_email # Only if using reconfirmable
|
||||
|
||||
## Lockable
|
||||
t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
|
||||
t.string :unlock_token # Only if unlock strategy is :email or :both
|
||||
t.datetime :locked_at
|
||||
|
||||
# Token authenticatable
|
||||
t.string :authentication_token
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
create_table :admins do |t|
|
||||
t.database_authenticatable :null => true
|
||||
t.encryptable
|
||||
t.rememberable :use_salt => false
|
||||
t.recoverable
|
||||
t.lockable
|
||||
## Database authenticatable
|
||||
t.string :email, :null => true
|
||||
t.string :encrypted_password, :null => true
|
||||
|
||||
## Recoverable
|
||||
t.string :reset_password_token
|
||||
t.datetime :reset_password_sent_at
|
||||
|
||||
## Rememberable
|
||||
t.datetime :remember_created_at
|
||||
|
||||
## Confirmable
|
||||
t.string :confirmation_token
|
||||
t.datetime :confirmed_at
|
||||
t.datetime :confirmation_sent_at
|
||||
t.string :unconfirmed_email # Only if using reconfirmable
|
||||
|
||||
## Encryptable
|
||||
t.string :password_salt
|
||||
|
||||
## Lockable
|
||||
t.datetime :locked_at
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,8 +3,11 @@ module SharedAdmin
|
||||
|
||||
included do
|
||||
devise :database_authenticatable, :encryptable, :registerable,
|
||||
:timeoutable, :recoverable, :rememberable, :lockable,
|
||||
:unlock_strategy => :time
|
||||
:timeoutable, :recoverable, :lockable, :confirmable,
|
||||
:unlock_strategy => :time, :lock_strategy => :none,
|
||||
:allow_unconfirmed_access_for => 2.weeks, :reconfirmable => true
|
||||
|
||||
validates_uniqueness_of :email, :allow_blank => true, :if => :email_changed?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -225,6 +225,10 @@ class CustomizedRoutingTest < ActionController::TestCase
|
||||
assert_recognizes({:controller => 'devise/unlocks', :action => 'show'}, {:path => '/htmlonly_users/unlock.xml', :method => :get})
|
||||
end
|
||||
end
|
||||
|
||||
test 'map with format false is not permanent' do
|
||||
assert_equal "/set.xml", @routes.url_helpers.set_path(:xml)
|
||||
end
|
||||
end
|
||||
|
||||
class ScopedRoutingTest < ActionController::TestCase
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
if DEVISE_ORM == :mongoid
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class User2
|
||||
include Mongoid::Document
|
||||
devise :database_authenticatable
|
||||
end
|
||||
|
||||
class User3
|
||||
include Mongoid::Document
|
||||
devise :database_authenticatable, :authentication_keys => [:username, :email]
|
||||
end
|
||||
|
||||
class User4
|
||||
include Mongoid::Document
|
||||
devise :database_authenticatable, :authentication_keys => [:username]
|
||||
end
|
||||
|
||||
class SchemaTest < ActiveSupport::TestCase
|
||||
test 'should create an email field if there are no custom authentication keys' do
|
||||
assert_not_equal User2.fields['email'], nil
|
||||
end
|
||||
|
||||
test 'should create an email field if there are custom authentication keys and they include email' do
|
||||
assert_not_equal User3.fields['email'], nil
|
||||
end
|
||||
|
||||
test 'should not create an email field if there are custom authentication keys they don\'t include email' do
|
||||
assert_equal User4.fields['email'], nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -14,8 +14,11 @@ class ActiveSupport::TestCase
|
||||
end
|
||||
alias :assert_present :assert_not_blank
|
||||
|
||||
def assert_email_sent(&block)
|
||||
def assert_email_sent(address = nil, &block)
|
||||
assert_difference('ActionMailer::Base.deliveries.size') { yield }
|
||||
if address.present?
|
||||
assert_equal address, ActionMailer::Base.deliveries.last['to'].to_s
|
||||
end
|
||||
end
|
||||
|
||||
def assert_email_not_sent(&block)
|
||||
|
||||
@@ -23,8 +23,10 @@ class ActionDispatch::IntegrationTest
|
||||
def create_admin(options={})
|
||||
@admin ||= begin
|
||||
admin = Admin.create!(
|
||||
:email => 'admin@test.com', :password => '123456', :password_confirmation => '123456'
|
||||
:email => options[:email] || 'admin@test.com',
|
||||
:password => '123456', :password_confirmation => '123456'
|
||||
)
|
||||
admin.confirm! unless options[:confirm] == false
|
||||
admin
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,7 +17,7 @@ class TestHelpersTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
test "redirects if attempting to access a page with an unconfirmed account" do
|
||||
swap Devise, :confirm_within => 0 do
|
||||
swap Devise, :allow_unconfirmed_access_for => 0 do
|
||||
user = create_user
|
||||
assert !user.active_for_authentication?
|
||||
|
||||
@@ -28,7 +28,7 @@ class TestHelpersTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
test "returns nil if accessing current_user with an unconfirmed account" do
|
||||
swap Devise, :confirm_within => 0 do
|
||||
swap Devise, :allow_unconfirmed_access_for => 0 do
|
||||
user = create_user
|
||||
assert !user.active_for_authentication?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user