1
0
Fork 0
mirror of https://github.com/heartcombo/devise.git synced 2022-11-09 12:18:31 -05:00

No need to append ?unauthenticated=true in URLs anymore since Flash was moved to a middleware in Rails 3.

This commit is contained in:
José Valim 2010-04-03 11:43:31 +02:00
parent 0f7b311171
commit 23e608e27b
17 changed files with 112 additions and 115 deletions

View file

@ -15,9 +15,8 @@
* Compatibility with Datamapper and Mongoid.
* Make config.devise available on config/application.rb.
* TokenAuthenticatable now works with HTTP Basic Auth.
* Allow :unlock_strategy to be :none and add :lock_strategy which can be :failed_attempts or
none. Setting those values to :none means that you want to handle lock and unlocking by
yourself.
* Allow :unlock_strategy to be :none and add :lock_strategy which can be :failed_attempts or none. Setting those values to :none means that you want to handle lock and unlocking by yourself.
* No need to append ?unauthenticated=true in URLs anymore since Flash was moved to a middleware in Rails 3.
* bug fix
* Do not allow unlockable strategies based on time to access a controller.

View file

@ -4,9 +4,6 @@ class Devise::SessionsController < ApplicationController
# GET /resource/sign_in
def new
Devise::FLASH_MESSAGES.each do |message|
set_now_flash_message :alert, message if params[message] == "true"
end unless flash[:notice]
clean_up_passwords(build_resource)
render_with_scope :new
end

View file

@ -67,7 +67,7 @@ module Devise
#
def stored_location_for(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
session.delete(:"#{scope}.return_to")
session.delete(:"#{scope}_return_to")
end
# The default url to be used after signing in. This is used by all Devise

View file

@ -90,15 +90,9 @@ module Devise
#
# Please refer to README or en.yml locale file to check what messages are
# available.
def set_flash_message(key, kind, now=false)
flash_hash = now ? flash.now : flash
flash_hash[key] = I18n.t(:"#{resource_name}.#{kind}", :resource_name => resource_name,
: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)
def set_flash_message(key, kind)
flash[key] = I18n.t(:"#{resource_name}.#{kind}", :resource_name => resource_name,
:scope => [:devise, controller_name.to_sym], :default => kind)
end
def clean_up_passwords(object)

View file

@ -10,6 +10,8 @@ module Devise
include ActionController::UrlFor
include ActionController::Redirecting
delegate :flash, :to => :request
def self.call(env)
action(:respond).call(env)
end
@ -20,31 +22,44 @@ module Devise
def respond
if http_auth?
self.status = 401
self.headers["WWW-Authenticate"] = %(Basic realm=#{Devise.http_authentication_realm.inspect})
self.content_type = request.format.to_s
self.response_body = http_auth_body
elsif action = warden_options[:recall]
default_message :invalid
env["PATH_INFO"] = attempted_path
params.merge!(query_string_params)
self.response = recall_controller.action(action).call(env)
http_auth
elsif warden_options[:recall]
recall
else
scope = warden_options[:scope]
store_location!(scope)
redirect_to send(:"new_#{scope}_session_path", query_string_params)
redirect
end
end
def http_auth
self.status = 401
self.headers["WWW-Authenticate"] = %(Basic realm=#{Devise.http_authentication_realm.inspect})
self.content_type = request.format.to_s
self.response_body = http_auth_body
end
def recall
env["PATH_INFO"] = attempted_path
flash.now[:alert] = i18n_message(:invalid)
self.response = recall_controller.action(warden_options[:recall]).call(env)
end
def redirect
store_location!
flash[:alert] = i18n_message unless flash[:notice]
redirect_to send(:"new_#{scope}_session_path")
end
protected
def message
@message ||= warden.message || warden_options[:message] || default_message
end
def i18n_message(default = nil)
message = warden.message || warden_options[:message] || default || :unauthenticated
def default_message(message=nil)
@default_message = message if message
@default_message ||= :unauthenticated
if message.is_a?(Symbol)
I18n.t(:"#{scope}.#{message}", :resource_name => scope,
:scope => [:devise, :sessions], :default => [message, message.to_s])
else
message.to_s
end
end
def http_auth?
@ -52,26 +67,8 @@ module Devise
end
def http_auth_body
body = if message.is_a?(Symbol)
I18n.t "devise.sessions.#{message}", :default => message.to_s
else
message.to_s
end
method = :"to_#{request.format.to_sym}"
{}.respond_to?(method) ? { :error => body }.send(method) : body
end
# Build the proper query string based on the given message.
def query_string_params
case message
when Symbol
{ message => "true" }
when String
{ :message => message }
else
{}
end
{}.respond_to?(method) ? { :error => i18n_message }.send(method) : i18n_message
end
def recall_controller
@ -86,6 +83,10 @@ module Devise
env['warden.options']
end
def scope
@scope ||= warden_options[:scope]
end
def attempted_path
warden_options[:attempted_path]
end
@ -94,8 +95,8 @@ module Devise
# scoped session provided by warden here, since the user is not authenticated
# yet, but we still need to store the uri based on scope, so different scopes
# would never use the same uri to redirect.
def store_location!(scope)
session[:"#{scope}.return_to"] = attempted_path if request && request.get?
def store_location!
session[:"#{scope}_return_to"] = attempted_path if request && request.get?
end
end
end

View file

@ -121,20 +121,20 @@ class ControllerAuthenticableTest < ActionController::TestCase
test 'stored location for returns the location for a given scope' do
assert_nil @controller.stored_location_for(:user)
@controller.session[:"user.return_to"] = "/foo.bar"
@controller.session[:"user_return_to"] = "/foo.bar"
assert_equal "/foo.bar", @controller.stored_location_for(:user)
end
test 'stored location for accepts a resource as argument' do
assert_nil @controller.stored_location_for(:user)
@controller.session[:"user.return_to"] = "/foo.bar"
@controller.session[:"user_return_to"] = "/foo.bar"
assert_equal "/foo.bar", @controller.stored_location_for(User.new)
end
test 'stored location cleans information after reading' do
@controller.session[:"user.return_to"] = "/foo.bar"
@controller.session[:"user_return_to"] = "/foo.bar"
assert_equal "/foo.bar", @controller.stored_location_for(:user)
assert_nil @controller.session[:"user.return_to"]
assert_nil @controller.session[:"user_return_to"]
end
test 'after sign in path defaults to root path if none by was specified for the given scope' do
@ -152,7 +152,7 @@ class ControllerAuthenticableTest < ActionController::TestCase
test 'sign in and redirect uses the stored location' do
user = User.new
@controller.session[:"user.return_to"] = "/foo.bar"
@controller.session[:"user_return_to"] = "/foo.bar"
@mock_warden.expects(:user).with(:user).returns(nil)
@mock_warden.expects(:set_user).with(user, :scope => :user).returns(true)
@controller.expects(:redirect_to).with("/foo.bar")

View file

@ -16,7 +16,9 @@ class FailureTest < ActiveSupport::TestCase
'rack.input' => "",
'warden' => OpenStruct.new(:message => nil)
}.merge!(env_params)
Devise::FailureApp.call(env).to_a
@response = Devise::FailureApp.call(env).to_a
@request = ActionDispatch::Request.new(env)
end
def call_failure_with_http(env_params={})
@ -26,49 +28,55 @@ class FailureTest < ActiveSupport::TestCase
context 'When redirecting' do
test 'return 302 status' do
assert_equal 302, call_failure.first
call_failure
assert_equal 302, @response.first
end
test 'return to the default redirect location' do
assert_equal 'http://test.host/users/sign_in?unauthenticated=true', call_failure.second['Location']
call_failure
assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
assert_equal 'http://test.host/users/sign_in', @response.second['Location']
end
test 'uses the proxy failure message as symbol' do
warden = OpenStruct.new(:message => :test)
location = call_failure('warden' => warden).second['Location']
assert_equal 'http://test.host/users/sign_in?test=true', location
call_failure('warden' => OpenStruct.new(:message => :test))
assert_equal 'test', @request.flash[:alert]
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
end
test 'uses the proxy failure message as string' do
warden = OpenStruct.new(:message => 'Hello world')
location = call_failure('warden' => warden).second['Location']
assert_equal 'http://test.host/users/sign_in?message=Hello+world', location
call_failure('warden' => OpenStruct.new(:message => 'Hello world'))
assert_equal 'Hello world', @request.flash[:alert]
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
end
test 'set content type to default text/html' do
assert_equal 'text/html; charset=utf-8', call_failure.second['Content-Type']
call_failure
assert_equal 'text/html; charset=utf-8', @response.second['Content-Type']
end
test 'setup a default message' do
assert_match /You are being/, call_failure.last.body
assert_match /redirected/, call_failure.last.body
assert_match /\?unauthenticated=true/, call_failure.last.body
call_failure
assert_match /You are being/, @response.last.body
assert_match /redirected/, @response.last.body
assert_match /users\/sign_in/, @response.last.body
end
end
context 'For HTTP request' do
test 'return 401 status' do
assert_equal 401, call_failure_with_http.first
call_failure_with_http
assert_equal 401, @response.first
end
test 'return WWW-authenticate headers' do
assert_equal 'Basic realm="Application"', call_failure_with_http.second["WWW-Authenticate"]
call_failure_with_http
assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
end
test 'uses the proxy failure message as response body' do
warden = OpenStruct.new(:message => :invalid)
response = call_failure_with_http('warden' => warden).third
assert_equal 'Invalid email or password.', response.body
call_failure_with_http('warden' => OpenStruct.new(:message => :invalid))
assert_equal 'Invalid email or password.', @response.third.body
end
end
@ -79,9 +87,9 @@ class FailureTest < ActiveSupport::TestCase
"warden.options" => { :recall => "new", :attempted_path => "/users/sign_in" },
"warden" => stub_everything
}
response = call_failure(env).third
assert response.body.include?('<h2>Sign in</h2>')
assert response.body.include?('Invalid email or password.')
call_failure(env)
assert @response.third.body.include?('<h2>Sign in</h2>')
assert @response.third.body.include?('Invalid email or password.')
end
end
end

View file

@ -88,9 +88,9 @@ class ConfirmationTest < ActionController::IntegrationTest
test 'error message is configurable by resource name' do
store_translations :en, :devise => {
:sessions => { :admin => { :unconfirmed => "Not confirmed user" } }
:sessions => { :user => { :unconfirmed => "Not confirmed user" } }
} do
get new_admin_session_path(:unconfirmed => true)
sign_in_as_user(:confirm => false)
assert_contain 'Not confirmed user'
end
end

View file

@ -50,7 +50,7 @@ class DatabaseAuthenticationSanityTest < ActionController::IntegrationTest
test 'not signed in as admin should not be able to access admins actions' do
get admins_path
assert_redirected_to new_admin_session_path(:unauthenticated => true)
assert_redirected_to new_admin_session_path
assert_not warden.authenticated?(:admin)
end
@ -60,7 +60,7 @@ class DatabaseAuthenticationSanityTest < ActionController::IntegrationTest
assert_not warden.authenticated?(:admin)
get admins_path
assert_redirected_to new_admin_session_path(:unauthenticated => true)
assert_redirected_to new_admin_session_path
end
test 'signed in as admin should be able to access admin actions' do
@ -146,7 +146,7 @@ class AuthenticationTest < ActionController::IntegrationTest
test 'redirect from warden shows sign in or sign up message' do
get admins_path
warden_path = new_admin_session_path(:unauthenticated => true)
warden_path = new_admin_session_path
assert_redirected_to warden_path
get warden_path
@ -157,35 +157,35 @@ class AuthenticationTest < ActionController::IntegrationTest
sign_in_as_user
assert_template 'home/index'
assert_nil session[:"user.return_to"]
assert_nil session[:"user_return_to"]
end
test 'redirect to requested url after sign in' do
get users_path
assert_redirected_to new_user_session_path(:unauthenticated => true)
assert_equal users_path, session[:"user.return_to"]
assert_redirected_to new_user_session_path
assert_equal users_path, session[:"user_return_to"]
follow_redirect!
sign_in_as_user :visit => false
assert_template 'users/index'
assert_nil session[:"user.return_to"]
assert_nil session[:"user_return_to"]
end
test 'redirect to last requested url overwriting the stored return_to option' do
get expire_user_path(create_user)
assert_redirected_to new_user_session_path(:unauthenticated => true)
assert_equal expire_user_path(create_user), session[:"user.return_to"]
assert_redirected_to new_user_session_path
assert_equal expire_user_path(create_user), session[:"user_return_to"]
get users_path
assert_redirected_to new_user_session_path(:unauthenticated => true)
assert_equal users_path, session[:"user.return_to"]
assert_redirected_to new_user_session_path
assert_equal users_path, session[:"user_return_to"]
follow_redirect!
sign_in_as_user :visit => false
assert_template 'users/index'
assert_nil session[:"user.return_to"]
assert_nil session[:"user_return_to"]
end
test 'redirect to configured home path for a given scope after sign in' do
@ -199,7 +199,7 @@ class AuthenticationTest < ActionController::IntegrationTest
User.destroy_all
get '/users'
assert_redirected_to '/users/sign_in?unauthenticated=true'
assert_redirected_to new_user_session_path
end
test 'allows session to be set by a given scope' do

View file

@ -93,9 +93,9 @@ class LockTest < ActionController::IntegrationTest
test 'error message is configurable by resource name' do
store_translations :en, :devise => {
:sessions => { :admin => { :locked => "You are locked!" } }
:sessions => { :user => { :locked => "You are locked!" } }
} do
get new_admin_session_path(:locked => true)
user = sign_in_as_user(:locked => true)
assert_contain 'You are locked!'
end
end

View file

@ -134,7 +134,7 @@ class PasswordTest < ActionController::IntegrationTest
request_forgot_password
reset_password :reset_password_token => user.reload.reset_password_token
assert_current_path new_user_session_path(:unconfirmed => true)
assert_equal new_user_session_path, @request.path
assert !warden.authenticated?(:user)
end

View file

@ -28,9 +28,9 @@ class RegistrationTest < ActionController::IntegrationTest
fill_in 'password confirmation', :with => 'new_user123'
click_button 'Sign up'
assert_contain 'You have signed up successfully.'
assert_contain 'You have signed up successfully'
assert_contain 'Sign in'
assert_not_contain 'Confirm your account'
assert_not_contain 'You have to confirm your account before continuing'
assert_not warden.authenticated?(:user)
@ -73,7 +73,9 @@ class RegistrationTest < ActionController::IntegrationTest
test 'a guest should not be able to change account' do
get edit_user_registration_path
assert_redirected_to new_user_session_path(:unauthenticated => true)
assert_redirected_to new_user_session_path
follow_redirect!
assert_contain 'You need to sign in or sign up before continuing.'
end
test 'a signed in user should not be able to access sign up' do

View file

@ -47,7 +47,7 @@ class RememberMeTest < ActionController::IntegrationTest
user = create_user_and_remember('add')
get users_path
assert_not warden.authenticated?(:user)
assert_redirected_to new_user_session_path(:unauthenticated => true)
assert_redirected_to new_user_session_path
end
test 'do not remember with token expired' do
@ -55,7 +55,7 @@ class RememberMeTest < ActionController::IntegrationTest
swap Devise, :remember_for => 0 do
get users_path
assert_not warden.authenticated?(:user)
assert_redirected_to new_user_session_path(:unauthenticated => true)
assert_redirected_to new_user_session_path
end
end

View file

@ -32,7 +32,7 @@ class SessionTimeoutTest < ActionController::IntegrationTest
assert_not_nil last_request_at
get users_path
assert_redirected_to new_user_session_path(:timeout => true)
assert_redirected_to new_user_session_path
assert_not warden.authenticated?(:user)
end
@ -47,7 +47,7 @@ class SessionTimeoutTest < ActionController::IntegrationTest
get expire_user_path(user)
get users_path
assert_redirected_to new_user_session_path(:timeout => true)
assert_redirected_to new_user_session_path
assert_not warden.authenticated?(:user)
end
end

View file

@ -47,7 +47,7 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
test 'does not authenticate with improper authentication token key' do
swap Devise, :token_authentication_key => :donald_duck_token do
sign_in_as_new_user_with_token(:auth_token_key => :secret_token)
assert_current_path new_user_session_path(:unauthenticated => true)
assert_equal new_user_session_path, @request.path
assert_contain 'You need to sign in or sign up before continuing'
assert_contain 'Sign in'
@ -58,7 +58,7 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
test 'does not authenticate with improper authentication token value' do
store_translations :en, :devise => {:sessions => {:invalid_token => 'LOL, that was not a single character correct.'}} do
sign_in_as_new_user_with_token(:auth_token => '*** INVALID TOKEN ***')
assert_current_path new_user_session_path(:invalid_token => true)
assert_equal new_user_session_path, @request.path
assert_contain 'LOL, that was not a single character correct.'
assert_contain 'Sign in'

View file

@ -50,10 +50,6 @@ class ActionDispatch::IntegrationTest
admin
end
def assert_current_path(path)
assert_equal(prepend_host(path), prepend_host(current_url))
end
# Fix assert_redirect_to in integration sessions because they don't take into
# account Middleware redirects.
#

View file

@ -6,14 +6,14 @@ class TestHelpersTest < ActionController::TestCase
test "redirects if attempting to access a page unauthenticated" do
get :index
assert_redirected_to "/users/sign_in?unauthenticated=true"
assert_redirected_to new_user_session_path
end
test "redirects if attempting to access a page with a unconfirmed account" do
swap Devise, :confirm_within => 0 do
sign_in create_user
get :index
assert_redirected_to "/users/sign_in?unconfirmed=true"
assert_redirected_to new_user_session_path
end
end
@ -35,7 +35,7 @@ class TestHelpersTest < ActionController::TestCase
sign_out user
get :index
assert_redirected_to "/users/sign_in?unauthenticated=true"
assert_redirected_to new_user_session_path
end
test "allows to sign in with different users" do