Ensure fail! works inside strategies, create unauthenticated and invalid messages and do not redirect on invalid authentication.

This commit is contained in:
José Valim 2009-10-29 08:29:31 -02:00
parent 475da069ab
commit 5172d50b95
7 changed files with 35 additions and 25 deletions

View File

@ -1,3 +1,11 @@
* enhancements
* Ensure fail! works inside strategies
* Make unauthenticated message (when you haven't logged in) different from
invalid message (when your credentials are invalid)
* bug fix
* Do not redirect on invalid authenticate
== 0.2.2 == 0.2.2
* bug fix * bug fix

View File

@ -1,12 +1,19 @@
class SessionsController < ApplicationController class SessionsController < ApplicationController
include Devise::Controllers::Helpers include Devise::Controllers::Helpers
# Maps the messages types that comes from warden to a flash type.
WARDEN_MESSAGES = {
:unauthenticated => :success,
:unconfirmed => :failure
}
before_filter :require_no_authentication, :only => [ :new, :create ] before_filter :require_no_authentication, :only => [ :new, :create ]
# GET /resource/sign_in # GET /resource/sign_in
def new def new
unauthenticated! if params[:unauthenticated] WARDEN_MESSAGES.each do |message, type|
unconfirmed! if params[:unconfirmed] set_now_flash_message type, message if params.key?(message)
end
build_resource build_resource
end end
@ -16,7 +23,7 @@ class SessionsController < ApplicationController
set_flash_message :success, :signed_in set_flash_message :success, :signed_in
redirect_back_or_to home_or_root_path redirect_back_or_to home_or_root_path
else else
unauthenticated! set_now_flash_message :failure, :invalid
build_resource build_resource
render :new render :new
end end
@ -29,14 +36,4 @@ class SessionsController < ApplicationController
redirect_to root_path redirect_to root_path
end end
protected
def unauthenticated!
set_now_flash_message :failure, :unauthenticated
end
def unconfirmed!
set_now_flash_message :failure, :unconfirmed
end
end end

View File

@ -3,8 +3,9 @@ en:
sessions: sessions:
signed_in: 'Signed in successfully.' signed_in: 'Signed in successfully.'
signed_out: 'Signed out successfully.' signed_out: 'Signed out successfully.'
unauthenticated: 'Invalid email or password.' unauthenticated: 'You need to sign in or sign up before continuing.'
unconfirmed: 'Your account was not confirmed and your confirmation period has expired.' unconfirmed: 'Your account was not confirmed and your confirmation period has expired.'
invalid: 'Invalid email or password.'
passwords: passwords:
send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.' 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.' updated: 'Your password was changed successfully. You are now signed in.'

View File

@ -8,8 +8,12 @@ module Devise
# to the default_url. # to the default_url.
def self.call(env) def self.call(env)
options = env['warden.options'] options = env['warden.options']
params = options[:params] || {}
scope = options[:scope] scope = options[:scope]
params = if env['warden'].try(:message)
{ env['warden'].message => true }
else
options[:params]
end
redirect_path = if mapping = Devise.mappings[scope] redirect_path = if mapping = Devise.mappings[scope]
"/#{mapping.as}/#{mapping.path_names[:sign_in]}" "/#{mapping.as}/#{mapping.path_names[:sign_in]}"
@ -19,7 +23,7 @@ module Devise
headers = {} headers = {}
headers["Location"] = redirect_path headers["Location"] = redirect_path
headers["Location"] << "?" << Rack::Utils.build_query(params) unless params.empty? headers["Location"] << "?" << Rack::Utils.build_query(params) if params
headers["Content-Type"] = 'text/plain' headers["Content-Type"] = 'text/plain'
message = options[:message] || "You are being redirected to #{redirect_path}" message = options[:message] || "You are being redirected to #{redirect_path}"

View File

@ -7,12 +7,16 @@ module Devise
# Authenticate a user based on email and password params, returning to warden # Authenticate a user based on email and password params, returning to warden
# success and the authenticated user if everything is okay. Otherwise redirect # success and the authenticated user if everything is okay. Otherwise redirect
# to sign in page. # to sign in page.
#
# Please notice the semantic difference between calling fail! and throw :warden.
# The first does not perform any action when calling authenticate, just
# when authenticate! is invoked. The second always perform the action.
def authenticate! def authenticate!
if valid_attributes? && resource = mapping.to.authenticate(attributes) if valid_attributes? && resource = mapping.to.authenticate(attributes)
success!(resource) success!(resource)
else else
store_location store_location
throw :warden, :scope => scope, :params => { :unauthenticated => true } fail!(:unauthenticated)
end end
end end

View File

@ -81,8 +81,6 @@ class AuthenticationTest < ActionController::IntegrationTest
fill_in 'email', :with => 'wrongemail@test.com' fill_in 'email', :with => 'wrongemail@test.com'
end end
assert_redirected_to new_admin_session_path(:unauthenticated => true)
follow_redirect!
assert_contain 'Invalid email or password' assert_contain 'Invalid email or password'
assert_not warden.authenticated?(:admin) assert_not warden.authenticated?(:admin)
end end
@ -92,8 +90,6 @@ class AuthenticationTest < ActionController::IntegrationTest
fill_in 'password', :with => 'abcdef' fill_in 'password', :with => 'abcdef'
end end
assert_redirected_to new_admin_session_path(:unauthenticated => true)
follow_redirect!
assert_contain 'Invalid email or password' assert_contain 'Invalid email or password'
assert_not warden.authenticated?(:admin) assert_not warden.authenticated?(:admin)
end end
@ -101,13 +97,12 @@ class AuthenticationTest < ActionController::IntegrationTest
test 'error message is configurable by resource name' do test 'error message is configurable by resource name' do
begin begin
I18n.backend.store_translations(:en, :devise => { :sessions => I18n.backend.store_translations(:en, :devise => { :sessions =>
{ :admin => { :unauthenticated => "Invalid credentials" } } }) { :admin => { :invalid => "Invalid credentials" } } })
sign_in_as_admin do sign_in_as_admin do
fill_in 'password', :with => 'abcdef' fill_in 'password', :with => 'abcdef'
end end
follow_redirect!
assert_contain 'Invalid credentials' assert_contain 'Invalid credentials'
ensure ensure
I18n.reload! I18n.reload!
@ -145,14 +140,14 @@ class AuthenticationTest < ActionController::IntegrationTest
assert_not_contain 'Signed out successfully' assert_not_contain 'Signed out successfully'
end end
test 'redirect from warden shows error message' do test 'redirect from warden shows sign in or sign up message' do
get admins_path get admins_path
warden_path = new_admin_session_path(:unauthenticated => true) warden_path = new_admin_session_path(:unauthenticated => true)
assert_redirected_to warden_path assert_redirected_to warden_path
get warden_path get warden_path
assert_contain 'Invalid email or password.' assert_contain 'You need to sign in or sign up before continuing.'
end end
test 'render 404 on roles without permission' do test 'render 404 on roles without permission' do

View File

@ -13,6 +13,7 @@ ActionMailer::Base.default_url_options[:host] = 'test.com'
ActiveRecord::Migration.verbose = false ActiveRecord::Migration.verbose = false
ActiveRecord::Base.logger = Logger.new(nil) ActiveRecord::Base.logger = Logger.new(nil)
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
ActiveRecord::Schema.define(:version => 1) do ActiveRecord::Schema.define(:version => 1) do
[:users, :admins].each do |table| [:users, :admins].each do |table|
create_table table do |t| create_table table do |t|