diff --git a/README.rdoc b/README.rdoc index e21b744a..0cc09174 100644 --- a/README.rdoc +++ b/README.rdoc @@ -138,6 +138,11 @@ A big change over previous versions is that we now use a rack filter. You have t require 'oauth/rack/oauth_filter' config.middleware.use OAuth::Rack::OAuthFilter +== Filter Options +If you only want the middleware to operate on certain paths, you can supply a regex expression to whitelist certain paths. + + require 'oauth/rack/oauth_filter' + config.middleware.use OAuth::Rack::OAuthFilter, '\/api\/*' === Generator Options diff --git a/lib/oauth/rack/oauth_filter.rb b/lib/oauth/rack/oauth_filter.rb index 98eaa750..bd82dc01 100644 --- a/lib/oauth/rack/oauth_filter.rb +++ b/lib/oauth/rack/oauth_filter.rb @@ -15,63 +15,66 @@ module Rack # config.middleware.use OAuth::Rack::OAuthFilter class OAuthFilter - def initialize(app) + def initialize(app, path = '\/') @app = app + @path = path end def call(env) - request = ::Rack::Request.new(env) - env["oauth_plugin"] = true - strategies = [] - if token_string = oauth2_token(request) - if token = Oauth2Token.where('invalidated_at IS NULL and authorized_at IS NOT NULL and token = ?', token_string).first - env["oauth.token"] = token - env["oauth.version"] = 2 - strategies << :oauth20_token - strategies << :token - end + if env['PATH_INFO'].match(Regexp.new(@path)) + request = ::Rack::Request.new(env) + env["oauth_plugin"] = true + strategies = [] + if token_string = oauth2_token(request) + if token = Oauth2Token.where('invalidated_at IS NULL and authorized_at IS NOT NULL and token = ?', token_string).first + env["oauth.token"] = token + env["oauth.version"] = 2 + strategies << :oauth20_token + strategies << :token + end - elsif oauth1_verify(request) do |request_proxy| - client_application = ClientApplication.find_by_key(request_proxy.consumer_key) - env["oauth.client_application_candidate"] = client_application + elsif oauth1_verify(request) do |request_proxy| + client_application = ClientApplication.find_by_key(request_proxy.consumer_key) + env["oauth.client_application_candidate"] = client_application - oauth_token = nil + oauth_token = nil - if client_application - # Store this temporarily in client_application object for use in request token generation - client_application.token_callback_url = request_proxy.oauth_callback if request_proxy.oauth_callback + if client_application + # Store this temporarily in client_application object for use in request token generation + client_application.token_callback_url = request_proxy.oauth_callback if request_proxy.oauth_callback - if request_proxy.token - oauth_token = client_application.tokens.where('invalidated_at IS NULL AND authorized_at IS NOT NULL and token = ?', request_proxy.token).first - if oauth_token.respond_to?(:provided_oauth_verifier=) - oauth_token.provided_oauth_verifier = request_proxy.oauth_verifier + if request_proxy.token + oauth_token = client_application.tokens.where('invalidated_at IS NULL AND authorized_at IS NOT NULL and token = ?', request_proxy.token).first + if oauth_token.respond_to?(:provided_oauth_verifier=) + oauth_token.provided_oauth_verifier = request_proxy.oauth_verifier + end + env["oauth.token_candidate"] = oauth_token end - env["oauth.token_candidate"] = oauth_token end - end - # return the token secret and the consumer secret - [(oauth_token.nil? ? nil : oauth_token.secret), (client_application.nil? ? nil : client_application.secret)] - end - if env["oauth.token_candidate"] - env["oauth.token"] = env["oauth.token_candidate"] - strategies << :oauth10_token - if env["oauth.token"].is_a?(::RequestToken) - strategies << :oauth10_request_token - elsif env["oauth.token"].is_a?(::AccessToken) - strategies << :token - strategies << :oauth10_access_token - end - else - strategies << :two_legged + # return the token secret and the consumer secret + [(oauth_token.nil? ? nil : oauth_token.secret), (client_application.nil? ? nil : client_application.secret)] end - env["oauth.client_application"] = env["oauth.client_application_candidate"] - env["oauth.version"] = 1 + if env["oauth.token_candidate"] + env["oauth.token"] = env["oauth.token_candidate"] + strategies << :oauth10_token + if env["oauth.token"].is_a?(::RequestToken) + strategies << :oauth10_request_token + elsif env["oauth.token"].is_a?(::AccessToken) + strategies << :token + strategies << :oauth10_access_token + end + else + strategies << :two_legged + end + env["oauth.client_application"] = env["oauth.client_application_candidate"] + env["oauth.version"] = 1 + end + env["oauth.strategies"] = strategies unless strategies.empty? + env["oauth.client_application_candidate"] = nil + env["oauth.token_candidate"] = nil end - env["oauth.strategies"] = strategies unless strategies.empty? - env["oauth.client_application_candidate"] = nil - env["oauth.token_candidate"] = nil @app.call(env) end diff --git a/oauth-plugin.gemspec b/oauth-plugin.gemspec index 17487e71..6815d4fa 100644 --- a/oauth-plugin.gemspec +++ b/oauth-plugin.gemspec @@ -33,7 +33,7 @@ Gem::Specification.new do |s| s.add_development_dependency "rack-test" s.add_dependency "multi_json" - s.add_dependency("oauth", ["~> 0.4.4"]) + s.add_dependency("oauth", ["~> 0.5.3"]) s.add_dependency("rack") s.add_dependency("oauth2", '>= 0.5.0') end diff --git a/spec/rack/oauth_filter_spec.rb b/spec/rack/oauth_filter_spec.rb index b4029716..51872d7b 100644 --- a/spec/rack/oauth_filter_spec.rb +++ b/spec/rack/oauth_filter_spec.rb @@ -30,6 +30,14 @@ def app response.should == {} end + it "should pass through when not on the whitelisted paths" do + @app ||= OAuth::Rack::OAuthFilter.new(OAuthEcho.new, '\/api/') + get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer", oauth_nonce="amrLDyFE2AMztx5fOYDD1OEqWps6Mc2mAR5qyO44Rj8", oauth_signature="KCSg0RUfVFUcyhrgJo580H8ey0c%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1295039581", oauth_version="1.0"'} + last_response.should be_ok + response = MultiJson.decode(last_response.body) + response.should == {} + end + describe 'OAuth1' do describe 'with optional white space' do it "should sign with consumer" do @@ -241,4 +249,4 @@ def app end end end -end \ No newline at end of file +end