Improves error handling behavior. Closes #578.

* OmniAuth::FailureEndpoint will raise any encountered
  errors out if RACK_ENV is development.
* It will redirect compatibly with current OmniAuth if
  not in development.
* Now uses Rack::Response to include a content length
  in the failure response.
This commit is contained in:
Michael Bleigh 2012-03-05 23:11:35 -05:00
parent 5fbc41943d
commit d02f9d58f7
7 changed files with 74 additions and 8 deletions

2
.rspec
View File

@ -1,2 +1,2 @@
--color
--order random
--order random

View File

@ -1,4 +1,13 @@
source 'https://rubygems.org'
gem 'rack', '~> 1.4'
gem 'growl'
gem 'guard'
gem 'guard-bundler'
gem 'guard-rspec'
gem 'pry'
gem 'pry-nav'
gem 'plymouth'
gem 'rb-fsevent'
gemspec

View File

@ -2,6 +2,8 @@ require 'rack'
require 'singleton'
module OmniAuth
class Error < StandardError; end
module Strategies
autoload :Developer, 'omniauth/strategies/developer'
end

View File

@ -1,4 +1,10 @@
module OmniAuth
# This simple Rack endpoint that serves as the default
# 'failure' mechanism for OmniAuth. If a strategy fails for
# any reason this endpoint will be invoked. The default behavior
# is to redirect to `/auth/failure` except in the case of
# a development `RACK_ENV`, in which case an exception will
# be raised.
class FailureEndpoint
attr_reader :env
@ -11,9 +17,18 @@ module OmniAuth
end
def call
raise_out! if ENV['RACK_ENV'].to_s == 'development'
redirect_to_failure
end
def raise_out!
raise env['omniauth.error'] || OmniAuth::Error.new(env['omniauth.error.type'])
end
def redirect_to_failure
message_key = env['omniauth.error.type']
new_path = "#{env['SCRIPT_NAME']}#{OmniAuth.config.path_prefix}/failure?message=#{message_key}"
[302, {'Location' => new_path, 'Content-Type'=> 'text/html'}, []]
Rack::Response.new(["302 Moved"], 302, 'Location' => new_path).finish
end
end
end

View File

@ -10,14 +10,9 @@ Gem::Specification.new do |gem|
gem.add_runtime_dependency 'rack'
gem.add_runtime_dependency 'hashie', '~> 1.2'
gem.add_development_dependency 'growl'
gem.add_development_dependency 'guard'
gem.add_development_dependency 'guard-bundler'
gem.add_development_dependency 'guard-rspec'
gem.add_development_dependency 'simplecov'
gem.add_development_dependency 'rack-test'
gem.add_development_dependency 'rake'
gem.add_development_dependency 'rb-fsevent'
gem.add_development_dependency 'rdiscount'
gem.add_development_dependency 'rspec', '~> 2.8'
gem.add_development_dependency 'yard'

View File

@ -0,0 +1,45 @@
require 'spec_helper'
describe OmniAuth::FailureEndpoint do
subject{ OmniAuth::FailureEndpoint }
context 'development' do
before do
@rack_env = ENV['RACK_ENV']
ENV['RACK_ENV'] = 'development'
end
it 'should raise out the error' do
err = StandardError.new("Blah")
expect{ subject.call('omniauth.error' => err) }.to raise_error(err)
end
it 'should raise out an OmniAuth::Error if no omniauth.error is set' do
expect{ subject.call('omniauth.error.type' => 'example') }.to raise_error(OmniAuth::Error, "example")
end
after do
ENV['RACK_ENV'] = @rack_env
end
end
context 'non-development' do
let(:env){ {'omniauth.error.type' => 'invalid_request'} }
it 'should be a redirect' do
status, head, body = *subject.call(env)
status.should == 302
end
it 'should include the SCRIPT_NAME' do
status, head, body = *subject.call(env.merge('SCRIPT_NAME' => '/random'))
head['Location'].should == '/random/auth/failure?message=invalid_request'
end
it 'should respect configured path prefix' do
OmniAuth.config.stub(:path_prefix => '/boo')
status, head, body = *subject.call(env)
head["Location"].should == '/boo/failure?message=invalid_request'
end
end
end

View File

@ -509,7 +509,7 @@ describe OmniAuth::Strategy do
end
it 'should be case insensitive on callback path' do
strategy.call(make_env('/AUTH/TeSt/CaLlBAck')).should == strategy.call(make_env('/auth/test/callback'))
strategy.call(make_env('/AUTH/TeSt/CaLlBAck')).first.should == strategy.call(make_env('/auth/test/callback')).first
end
it 'should maintain query string parameters' do