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

Properly handle failure.

This commit is contained in:
José Valim 2010-10-15 01:15:17 +02:00
parent 611261c64e
commit 3e38043085
4 changed files with 57 additions and 53 deletions

View file

@ -2,5 +2,25 @@ class Devise::OmniauthCallbacksController < ApplicationController
include Devise::Controllers::InternalHelpers
def failure
set_flash_message :alert, :failure, :kind => failed_strategy.name.to_s.humanize, :reason => failure_message
redirect_to after_omniauth_failure_path_for(resource_name)
end
protected
def failed_strategy
env["omniauth.failed_strategy"]
end
def failure_message
exception = env["omniauth.error"]
error = exception.error_reason if exception.respond_to?(:error_reason)
error ||= exception.error if exception.respond_to?(:error)
error ||= env["omniauth.failure_key"]
error.to_s.humanize if error
end
def after_omniauth_failure_path_for(scope)
new_session_path(scope)
end
end

View file

@ -40,6 +40,11 @@ module Devise
raise "Could not find a valid mapping for #{duck}"
end
def self.find_by_path!(path)
Devise.mappings.each_value { |m| return m if path.include?(m.fullpath) }
raise "Could not find a valid mapping for path #{path}"
end
def initialize(name, options) #:nodoc:
@plural = (options[:as] ? "#{options[:as]}_#{name}" : name).to_sym
@singular = (options[:singular] || @plural.to_s.singularize).to_sym

View file

@ -6,19 +6,32 @@ rescue LoadError => e
end
module OmniAuth
module Strategy
# TODO HAX Backport to OmniAuth
# TODO HAXES Backport to OmniAuth
module Strategy #:nodoc:
def initialize(app, name, *args)
@app = app
@name = name.to_sym
yield self if block_given?
end
def fail!(message_key, exception = nil)
self.env['omniauth.error'] = exception
self.env['omniauth.failure_key'] = message_key
self.env['omniauth.failed_strategy'] = self
OmniAuth.config.on_failure.call(self.env, message_key.to_sym)
end
end
end
# Clean up the default path_prefix. It will be automatically set by Devise.
OmniAuth.config.path_prefix = nil
OmniAuth.config.on_failure = Proc.new do |env, key|
env['devise.mapping'] = Devise::Mapping.find_by_path!(env['PATH_INFO'])
controller_klass = "#{env['devise.mapping'].controllers[:omniauth_callbacks].camelize}Controller"
controller_klass.constantize.action(:failure).call(env)
end
module Devise
module OmniAuth
autoload :Config, "devise/omniauth/config"

View file

@ -87,55 +87,21 @@ class OmniauthableIntegrationTest < ActionController::IntegrationTest
assert !session["devise.facebook_data"]
end
# test "[FAILURE] shows 404 if no code or error are given as params" do
# assert_raise AbstractController::ActionNotFound do
# visit "/users/oauth/facebook/callback"
# end
# end
#
# test "[FAILURE] raises an error if model does not implement a hook" do
# begin
# visit "/users/oauth/github/callback?code=123456"
# raise "Expected visit to raise an error"
# rescue Exception => e
# assert_match "User does not respond to find_for_github_oauth", e.message
# end
# end
#
# test "[FAILURE] handles callback error parameter according to the specification" do
# visit "/users/oauth/facebook/callback?error=access_denied"
# assert_current_url "/users/sign_in"
# assert_contain 'Could not authorize you from Facebook because "Access denied".'
# end
#
# test "[FAILURE] handles callback error_reason just for Facebook compatibility" do
# visit "/users/oauth/facebook/callback?error_reason=access_denied"
# assert_current_url "/users/sign_in"
# assert_contain 'Could not authorize you from Facebook because "Access denied".'
# end
#
# test "[FAILURE][I18N] uses I18n for custom messages" do
# visit "/users/oauth/facebook/callback?error=access_denied"
# assert_current_url "/users/sign_in"
# assert_contain 'Could not authorize you from Facebook because "Access denied"'
# end
#
# test "[FAILURE][I18N] uses I18n with oauth callback scope for custom messages" do
# store_translations :en, :devise => { :oauth_callbacks => {
# :facebook => { :failure => "Access denied bro" } } } do
# visit "/users/oauth/facebook/callback?error=access_denied"
# assert_current_url "/users/sign_in"
# assert_contain "Access denied bro"
# end
# end
#
# test "[FAILURE][I18N] uses I18n with oauth callback scope and resource name for custom messages" do
# store_translations :en, :devise => { :oauth_callbacks => {
# :user => { :facebook => { :failure => "Access denied user" } },
# :facebook => { :failure => "Access denied bro" } } } do
# visit "/users/oauth/facebook/callback?error=access_denied"
# assert_current_url "/users/sign_in"
# assert_contain "Access denied user"
# end
# end
test "handles callback error parameter according to the specification" do
visit "/users/auth/facebook/callback?error=access_denied"
assert_current_url "/users/sign_in"
assert_contain 'Could not authorize you from Facebook because "Access denied".'
end
test "handles other exceptions from omniauth" do
Devise::OmniAuth.stub!(:facebook) do |b|
b.post('/oauth/access_token') { [401, {}, {}.to_json] }
end
visit "/users/sign_in"
click_link "Sign in with facebook"
assert_current_url "/users/sign_in"
assert_contain 'Could not authorize you from Facebook because "Invalid credentials".'
end
end