mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
Verify confirmation time frame to let the user sign in or block it if the user is not confirmed.
This commit is contained in:
parent
80f3f30704
commit
bbca9e830e
8 changed files with 69 additions and 6 deletions
|
@ -5,6 +5,7 @@ class SessionsController < ApplicationController
|
|||
# GET /resource/sign_in
|
||||
def new
|
||||
unauthenticated! if params[:unauthenticated]
|
||||
unconfirmed! if params[:unconfirmed]
|
||||
end
|
||||
|
||||
# POST /resource/sign_in
|
||||
|
@ -28,8 +29,11 @@ class SessionsController < ApplicationController
|
|||
protected
|
||||
|
||||
def unauthenticated!
|
||||
flash.now[:failure] = I18n.t(:"#{resource_name}.unauthenticated",
|
||||
:scope => [:devise, :sessions], :default => :unauthenticated)
|
||||
set_now_flash_message :failure, :unauthenticated
|
||||
end
|
||||
|
||||
def unconfirmed!
|
||||
set_now_flash_message :failure, :unconfirmed
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,6 +4,7 @@ en:
|
|||
signed_in: 'Signed in successfully.'
|
||||
signed_out: 'Signed out successfully.'
|
||||
unauthenticated: 'Invalid email or password.'
|
||||
unconfirmed: 'Your account was not confirmed and your confirmation period has expired.'
|
||||
passwords:
|
||||
send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.'
|
||||
updated: 'Your password was changed successfully. You are now signed in.'
|
||||
|
|
|
@ -58,6 +58,9 @@ module Devise
|
|||
include Devise::Models.const_get(m.to_s.classify)
|
||||
end
|
||||
|
||||
# Assert valid keys after including modules to ensure MODEL_CONFIG is fully loaded
|
||||
options.assert_valid_keys(:except, *Devise::MODEL_CONFIG)
|
||||
|
||||
# Convert new keys to methods which overwrites Devise defaults
|
||||
options.each { |key, value| send(:"#{key}=", value) }
|
||||
end
|
||||
|
|
|
@ -81,11 +81,17 @@ module Devise
|
|||
#
|
||||
# Please refer to README or en.yml locale file to check what messages are
|
||||
# available.
|
||||
def set_flash_message(key, kind)
|
||||
flash[key] = I18n.t(:"#{resource_name}.#{kind}",
|
||||
def set_flash_message(key, kind, now=false)
|
||||
flash_hash = now ? flash.now : flash
|
||||
flash_hash[key] = I18n.t(:"#{resource_name}.#{kind}",
|
||||
:scope => [:devise, controller_name.to_sym], :default => kind)
|
||||
end
|
||||
|
||||
# Shortcut to set flash.now message. Same rules applied from set_flash_message
|
||||
def set_now_flash_message(key, kind)
|
||||
set_flash_message(key, kind, true)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
20
lib/devise/hooks/confirmable.rb
Normal file
20
lib/devise/hooks/confirmable.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Each time the user is set we verify if it is still able to really sign in.
|
||||
# This is done by checking the time frame the user is able to sign in without
|
||||
# confirming it's account. If the user has not confirmed it's account during
|
||||
# this time frame, he/she will not able to sign in anymore.
|
||||
Warden::Manager.after_set_user do |record, auth, options|
|
||||
if record.present? && record.respond_to?(:active?) && !record.active?
|
||||
scope = options[:scope]
|
||||
mapping = Devise.mappings[scope]
|
||||
auth.logout(scope)
|
||||
# TODO: Change the way we handle redirect here after updating warden
|
||||
throw :warden, [
|
||||
302,
|
||||
{
|
||||
'Location' => "/#{mapping.as}/#{mapping.path_names[:sign_in]}?unconfirmed=true",
|
||||
'Content-Type' => 'text/plain'
|
||||
},
|
||||
['You are being redirected']
|
||||
]
|
||||
end
|
||||
end
|
|
@ -19,6 +19,6 @@ end
|
|||
Warden::Manager.before_logout do |record, auth, scope|
|
||||
if record.respond_to?(:forget_me!)
|
||||
record.forget_me!
|
||||
auth.cookies['remember_token'] = nil
|
||||
auth.cookies.delete('remember_token')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -82,7 +82,7 @@ module Devise
|
|||
# confirmation_period_valid? # will always return false
|
||||
def confirmation_period_valid?
|
||||
confirmation_sent_at? &&
|
||||
(Date.today - confirmation_sent_at.to_date).days.to_i < confirm_in
|
||||
(Date.today - confirmation_sent_at.to_date).days.to_i < confirm_in.to_i
|
||||
end
|
||||
|
||||
# Checks whether the record is confirmed or not, yielding to the block
|
||||
|
|
|
@ -57,4 +57,33 @@ class ConfirmationTest < ActionController::IntegrationTest
|
|||
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test 'not confirmed user and setup to block without confirmation should not be able to sign in' do
|
||||
Devise.confirm_in = 0
|
||||
user = sign_in_as_user(:confirm => false)
|
||||
|
||||
assert_redirected_to new_user_session_path(:unconfirmed => true)
|
||||
assert_not warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test 'not confirmed user but configured with some days to confirm should be able to sign in' do
|
||||
Devise.confirm_in = 1
|
||||
user = sign_in_as_user(:confirm => false)
|
||||
|
||||
assert_response :success
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test 'error message is configurable by resource name' do
|
||||
begin
|
||||
I18n.backend.store_translations(:en, :devise => { :sessions =>
|
||||
{ :admin => { :unconfirmed => "Not confirmed user" } } })
|
||||
|
||||
get new_admin_session_path(:unconfirmed => true)
|
||||
|
||||
assert_contain 'Not confirmed user'
|
||||
ensure
|
||||
I18n.reload!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue