Skip to content

Commit

Permalink
Closes #153 - Can restrict request methods to the request path (if yo…
Browse files Browse the repository at this point in the history
…u wish).
  • Loading branch information
Michael Bleigh committed Feb 4, 2011
1 parent 3a2dea5 commit 1343dd7
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 23 deletions.
3 changes: 2 additions & 1 deletion oa-core/lib/omniauth/core.rb
Expand Up @@ -26,6 +26,7 @@ class Configuration
end,
:form_css => Form::DEFAULT_CSS,
:test_mode => false,
:allowed_request_methods => [:get, :post],
:mock_auth => {
:default => {
'uid' => '1234',
Expand Down Expand Up @@ -55,7 +56,7 @@ def on_failure(&block)
end

attr_writer :on_failure
attr_accessor :path_prefix, :form_css, :test_mode, :mock_auth, :full_host
attr_accessor :path_prefix, :allowed_request_methods, :form_css, :test_mode, :mock_auth, :full_host
end

def self.config
Expand Down
4 changes: 2 additions & 2 deletions oa-core/lib/omniauth/strategy.rb
Expand Up @@ -26,8 +26,8 @@ def call(env)
def call!(env)
@env = env
return mock_call!(env) if OmniAuth.config.test_mode

if current_path == request_path
if current_path == request_path && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym)
status, headers, body = *call_app!
@response = Rack::Response.new(body, status, headers)
request_phase
Expand Down
58 changes: 38 additions & 20 deletions oa-core/spec/omniauth/strategy_spec.rb
Expand Up @@ -32,34 +32,34 @@ def callback_phase

context 'default paths' do
it 'should use the default request path' do
lambda{ strategy.call({'PATH_INFO' => '/auth/test'}) }.should raise_error("Request Phase")
lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test'}) }.should raise_error("Request Phase")
end

it 'should use the default callback path' do
lambda{ strategy.call({'PATH_INFO' => '/auth/test/callback'}) }.should raise_error("Callback Phase")
lambda{ strategy.call({'REQUEST_METHOD' => 'GET','PATH_INFO' => '/auth/test/callback'}) }.should raise_error("Callback Phase")
end

it 'should strip trailing spaces on request' do
lambda{ strategy.call({'PATH_INFO' => '/auth/test/'}) }.should raise_error("Request Phase")
lambda{ strategy.call({'REQUEST_METHOD' => 'GET','PATH_INFO' => '/auth/test/'}) }.should raise_error("Request Phase")
end

it 'should strip trailing spaces on callback' do
lambda{ strategy.call({'PATH_INFO' => '/auth/test/callback/'}) }.should raise_error("Callback Phase")
lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/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({'PATH_INFO' => '/auth/test'}) }.should raise_error("Request Phase")
lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test'}) }.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({'PATH_INFO' => '/auth/test', 'QUERY_STRING' => 'id=5'})
strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test', 'QUERY_STRING' => 'id=5'})
rescue RuntimeError; end
strategy.callback_url.should == 'http://example.com/auth/test/callback?id=5'
end
Expand All @@ -70,28 +70,28 @@ def callback_phase
app = lambda{|env| env['omniauth.boom'] = true; [404, {}, ['Whatev']] }

s = ExampleStrategy.new(app, 'test')
lambda{ s.call({'PATH_INFO' => '/auth/test'}) }.should raise_error("Request Phase")
lambda{ s.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test'}) }.should raise_error("Request Phase")
s.response.status.should == 404
s.last_env.should be_key('omniauth.boom')
end

context 'custom paths' do
it 'should use a custom request_path if one is provided' do
@options = {:request_path => '/awesome'}
lambda{ strategy.call({'PATH_INFO' => '/awesome'}) }.should raise_error("Request Phase")
lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/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({'PATH_INFO' => '/radical'}) }.should raise_error("Callback Phase")
lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/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({'PATH_INFO' => '/radical'}) }.should raise_error("Callback Phase")
lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/radical'}) }.should raise_error("Callback Phase")

strategy.callback_url.should == 'http://example.com/radical'
end
Expand All @@ -100,7 +100,7 @@ def callback_phase
@options = {:callback_path => '/radical'}
strategy.stub(:full_host).and_return('http://example.com')
begin
strategy.call({'QUERY_STRING' => 'id=5'})
strategy.call({'REQUEST_METHOD' => 'GET', 'QUERY_STRING' => 'id=5'})
rescue RuntimeError; end
strategy.callback_url.should == 'http://example.com/radical?id=5'
end
Expand All @@ -113,50 +113,68 @@ def callback_phase
end

it 'should use a custom prefix for request' do
lambda{ strategy.call({'PATH_INFO' => '/wowzers/test'}) }.should raise_error("Request Phase")
lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/wowzers/test'}) }.should raise_error("Request Phase")
end

it 'should use a custom prefix for callback' do
lambda{ strategy.call({'PATH_INFO' => '/wowzers/test/callback'}) }.should raise_error("Callback Phase")
lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/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({'PATH_INFO' => '/wowzers/test'}) }.should raise_error("Request Phase")
lambda{ strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/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({'PATH_INFO' => '/wowzers/test', 'QUERY_STRING' => 'id=5'})
strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/wowzers/test', 'QUERY_STRING' => 'id=5'})
rescue RuntimeError; end
strategy.callback_url.should == 'http://example.com/wowzers/test/callback?id=5'
end
end
end

context 'request method restriction' do
before do
OmniAuth.config.allowed_request_methods = [:post]
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
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")
end

after do
OmniAuth.config.allowed_request_methods = [:get, :post]
end
end

context 'test mode' do
before do
OmniAuth.config.test_mode = true
end

it 'should short circuit the request phase entirely' do
response = strategy.call({'PATH_INFO' => '/auth/test'})
response = strategy.call({'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test'})
response[0].should == 302
response[1]['Location'].should == '/auth/test/callback'
end

it 'should not short circuit requests outside of authentication' do
env = {'PATH_INFO' => '/'}
env = {'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/'}
strategy.call(env).should == app.call(env)
end

it 'should respond with the default hash if none is set' do
strategy.call 'PATH_INFO' => '/auth/test/callback'
strategy.call 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test/callback'
strategy.env['omniauth.auth']['uid'].should == '1234'
end

Expand All @@ -165,7 +183,7 @@ def callback_phase
'uid' => 'abc'
}

strategy.call 'PATH_INFO' => '/auth/test/callback'
strategy.call 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/auth/test/callback'
strategy.env['omniauth.auth']['uid'].should == 'abc'
end
end
Expand All @@ -178,7 +196,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('HOST' => 'my.host.net')
strategy.call('REQUEST_METHOD' => 'GET', 'HOST' => 'my.host.net')
strategy.full_host.should == 'my.host.net'
end
end
Expand Down

0 comments on commit 1343dd7

Please sign in to comment.