Browse files

Adds omniauth.origin for easy redirect to the page before request phase.

  • Loading branch information...
1 parent 6fcce73 commit 7fd2a7869dd5c2aaea408a3b2e30fc6ed78db72e Michael Bleigh committed Feb 11, 2011
View
2 oa-core/lib/omniauth/core.rb
@@ -10,7 +10,7 @@ module OmniAuth
module Strategies
autoload :Password, 'omniauth/strategies/password'
end
-
+
def self.strategies
@@strategies ||= []
end
View
22 oa-core/lib/omniauth/strategy.rb
@@ -1,9 +1,8 @@
require 'omniauth/core'
module OmniAuth
-
- module Strategy
-
+ class NoSessionError < StandardError; end
+ module Strategy
def self.included(base)
OmniAuth.strategies << base
base.class_eval do
@@ -24,12 +23,20 @@ def call(env)
end
def call!(env)
+ raise OmniAuth::NoSessionError.new("You must provide a session to use OmniAuth.") unless env['rack.session']
+
@env = env
return mock_call!(env) if OmniAuth.config.test_mode
if current_path == request_path && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
- call_through_to_app || request_phase
+ if response = call_through_to_app
+ response
+ else
+ env['rack.session']['omniauth.origin'] = env['HTTP_REFERER']
+ request_phase
+ end
elsif current_path == callback_path
+ env['omniauth.origin'] = session.delete('omniauth.origin')
callback_phase
else
if respond_to?(:other_phase)
@@ -42,7 +49,12 @@ def call!(env)
def mock_call!(env)
if current_path == request_path
- call_through_to_app || redirect(callback_path)
+ if response = call_through_to_app
+ response
+ else
+ env['rack.session']['omniauth.origin'] = env['HTTP_REFERER']
+ redirect(callback_path)
+ end
elsif current_path == callback_path
@env['omniauth.auth'] = OmniAuth.mock_auth_for(name.to_sym)
call_app!
View
4 oa-core/lib/omniauth/test/strategy_test_case.rb
@@ -26,7 +26,7 @@ def app
Rack::Builder.new {
use OmniAuth::Test::PhonySession
use *strat
- run lambda { |env| [200, {'Content-Type' => 'text/plain'}, [resp || env.key?('omniauth.auth').to_s]] }
+ run lambda {|env| [404, {'Content-Type' => 'text/plain'}, [resp || env.key?('omniauth.auth').to_s]] }
}.to_app
end
@@ -46,4 +46,4 @@ def strategy
end
-end
+end
View
3 oa-core/spec/omniauth/strategies/password_spec.rb
@@ -22,9 +22,6 @@ def strategy
before do
get '/auth/password', { :identifier => 'jerome', :password => 'my password'}
end
- it 'should be OK' do
- last_response.should be_ok
- end
sets_an_auth_hash
sets_provider_to 'password'
sets_user_info_to "username" => "jerome"
View
68 oa-core/spec/omniauth/strategy_spec.rb
@@ -9,10 +9,19 @@ def request_phase
raise "Request Phase"
end
def callback_phase
+ @last_env = env
raise "Callback Phase"
end
end
+def make_env(path = '/auth/test', props = {})
+ {
+ 'REQUEST_METHOD' => 'GET',
+ 'PATH_INFO' => path,
+ 'rack.session' => {}
+ }.merge(props)
+end
+
describe OmniAuth::Strategy do
let(:app){ lambda{|env| [404, {}, ['Awesome']]}}
describe '#initialize' do
@@ -30,36 +39,48 @@ def callback_phase
describe '#call' do
let(:strategy){ ExampleStrategy.new(app, 'test', @options) }
+ context 'omniauth.origin' do
+ it 'should be set on the request phase' do
+ lambda{ strategy.call(make_env('/auth/test', 'HTTP_REFERER' => 'http://example.com/origin')) }.should raise_error("Request Phase")
+ strategy.last_env['rack.session']['omniauth.origin'].should == 'http://example.com/origin'
+ end
+
+ it 'should be turned into an env variable on the callback phase' do
+ lambda{ strategy.call(make_env('/auth/test/callback', 'rack.session' => {'omniauth.origin' => 'http://example.com/origin'})) }.should raise_error("Callback Phase")
+ strategy.last_env['omniauth.origin'].should == 'http://example.com/origin'
+ end
+ end
+
context 'default paths' do
it 'should use the default request path' do
- lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test'}) }.should raise_error("Request Phase")
+ lambda{ strategy.call(make_env) }.should raise_error("Request Phase")
end
it 'should use the default callback path' do
- lambda{ strategy.call({'REQUEST_METHOD' => 'GET','PATH_INFO' => '/auth/test/callback'}) }.should raise_error("Callback Phase")
+ lambda{ strategy.call(make_env('/auth/test/callback')) }.should raise_error("Callback Phase")
end
it 'should strip trailing spaces on request' do
- lambda{ strategy.call({'REQUEST_METHOD' => 'GET','PATH_INFO' => '/auth/test/'}) }.should raise_error("Request Phase")
+ lambda{ strategy.call(make_env('/auth/test/')) }.should raise_error("Request Phase")
end
it 'should strip trailing spaces on callback' do
- lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test/callback/'}) }.should raise_error("Callback Phase")
+ lambda{ strategy.call(make_env('/auth/test/callback/')) }.should raise_error("Callback Phase")
end
context 'callback_url' do
it 'uses the default callback_path' do
strategy.should_receive(:full_host).and_return('http://example.com')
- lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test'}) }.should raise_error("Request Phase")
+ lambda{ strategy.call(make_env) }.should raise_error("Request Phase")
strategy.callback_url.should == 'http://example.com/auth/test/callback'
end
it 'preserves the query parameters' do
strategy.stub(:full_host).and_return('http://example.com')
begin
- strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test', 'QUERY_STRING' => 'id=5'})
+ strategy.call(make_env('/auth/test', 'QUERY_STRING' => 'id=5'))
rescue RuntimeError; end
strategy.callback_url.should == 'http://example.com/auth/test/callback?id=5'
end
@@ -70,34 +91,34 @@ def callback_phase
subject { ExampleStrategy.new(app, 'test') }
let(:app){ lambda{|env| env['omniauth.boom'] = true; [env['test.status'] || 404, {}, ['Whatev']] } }
it 'should be able to modify the env on the fly before the request_phase' do
- lambda{ subject.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test'}) }.should raise_error("Request Phase")
+ lambda{ subject.call(make_env) }.should raise_error("Request Phase")
subject.response.status.should == 404
subject.last_env.should be_key('omniauth.boom')
end
it 'should call through to the app instead if a non-404 response is received' do
- lambda{ subject.call('REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test', 'test.status' => 200) }.should_not raise_error
+ lambda{ subject.call(make_env('/auth/test', 'test.status' => 200)) }.should_not raise_error
subject.response.body.should == ['Whatev']
end
end
context 'custom paths' do
it 'should use a custom request_path if one is provided' do
@options = {:request_path => '/awesome'}
- lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/awesome'}) }.should raise_error("Request Phase")
+ lambda{ strategy.call(make_env('/awesome')) }.should raise_error("Request Phase")
end
it 'should use a custom callback_path if one is provided' do
@options = {:callback_path => '/radical'}
- lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/radical'}) }.should raise_error("Callback Phase")
+ lambda{ strategy.call(make_env('/radical')) }.should raise_error("Callback Phase")
end
context 'callback_url' do
it 'uses a custom callback_path if one is provided' do
@options = {:callback_path => '/radical'}
strategy.should_receive(:full_host).and_return('http://example.com')
- lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/radical'}) }.should raise_error("Callback Phase")
+ lambda{ strategy.call(make_env('/radical')) }.should raise_error("Callback Phase")
strategy.callback_url.should == 'http://example.com/radical'
end
@@ -106,7 +127,7 @@ def callback_phase
@options = {:callback_path => '/radical'}
strategy.stub(:full_host).and_return('http://example.com')
begin
- strategy.call({'REQUEST_METHOD' => 'GET', 'QUERY_STRING' => 'id=5'})
+ strategy.call(make_env('/auth/test', 'QUERY_STRING' => 'id=5'))
rescue RuntimeError; end
strategy.callback_url.should == 'http://example.com/radical?id=5'
end
@@ -119,26 +140,26 @@ def callback_phase
end
it 'should use a custom prefix for request' do
- lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/wowzers/test'}) }.should raise_error("Request Phase")
+ lambda{ strategy.call(make_env('/wowzers/test')) }.should raise_error("Request Phase")
end
it 'should use a custom prefix for callback' do
- lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/wowzers/test/callback'}) }.should raise_error("Callback Phase")
+ lambda{ strategy.call(make_env('/wowzers/test/callback')) }.should raise_error("Callback Phase")
end
context 'callback_url' do
it 'uses a custom prefix' do
strategy.should_receive(:full_host).and_return('http://example.com')
- lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/wowzers/test'}) }.should raise_error("Request Phase")
+ lambda{ strategy.call(make_env('/wowzers/test')) }.should raise_error("Request Phase")
strategy.callback_url.should == 'http://example.com/wowzers/test/callback'
end
it 'preserves the query parameters' do
strategy.stub(:full_host).and_return('http://example.com')
begin
- strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/wowzers/test', 'QUERY_STRING' => 'id=5'})
+ strategy.call(make_env('/auth/test', 'QUERY_STRING' => 'id=5'))
rescue RuntimeError; end
strategy.callback_url.should == 'http://example.com/wowzers/test/callback?id=5'
end
@@ -151,11 +172,11 @@ def callback_phase
end
it 'should not allow a request method of the wrong type' do
- lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test'})}.should_not raise_error
+ lambda{ strategy.call(make_env)}.should_not raise_error
end
it 'should allow a request method of the correct type' do
- lambda{ strategy.call({'REQUEST_METHOD' => 'POST', 'PATH_INFO' => '/auth/test'})}.should raise_error("Request Phase")
+ lambda{ strategy.call(make_env('/auth/test', 'REQUEST_METHOD' => 'POST'))}.should raise_error("Request Phase")
end
after do
@@ -169,18 +190,17 @@ def callback_phase
end
it 'should short circuit the request phase entirely' do
- response = strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test'})
+ response = strategy.call(make_env)
response[0].should == 302
response[1]['Location'].should == '/auth/test/callback'
end
it 'should not short circuit requests outside of authentication' do
- env = {'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/'}
- strategy.call(env).should == app.call(env)
+ strategy.call(make_env('/')).should == app.call(make_env('/'))
end
it 'should respond with the default hash if none is set' do
- strategy.call 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test/callback'
+ strategy.call make_env('/auth/test/callback')
strategy.env['omniauth.auth']['uid'].should == '1234'
end
@@ -189,7 +209,7 @@ def callback_phase
'uid' => 'abc'
}
- strategy.call 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test/callback'
+ strategy.call make_env('/auth/test/callback')
strategy.env['omniauth.auth']['uid'].should == 'abc'
end
end
@@ -202,7 +222,7 @@ def callback_phase
it 'should run the proc with the env when it is a proc' do
OmniAuth.config.full_host = Proc.new{|env| env['HOST']}
- strategy.call('REQUEST_METHOD' => 'GET', 'HOST' => 'my.host.net')
+ strategy.call(make_env('/auth/test', 'HOST' => 'my.host.net'))
strategy.full_host.should == 'my.host.net'
end
end
View
2 oa-oauth/spec/omniauth/strategies/oauth_spec.rb
@@ -8,7 +8,7 @@ def app
use OmniAuth::Builder do
provider :oauth, 'example.org', 'abc', 'def', :site => 'https://api.example.org'
end
- run lambda { |env| [200, {'Content-Type' => 'text/plain'}, [env.key?('omniauth.auth').to_s]] }
+ run lambda { |env| [404, {'Content-Type' => 'text/plain'}, [env.key?('omniauth.auth').to_s]] }
}.to_app
end

0 comments on commit 7fd2a78

Please sign in to comment.