Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow users to only apply the middleware to specific paths #151

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
89 changes: 46 additions & 43 deletions lib/oauth/rack/oauth_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion oauth-plugin.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion spec/rack/oauth_filter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -241,4 +249,4 @@ def app
end
end
end
end
end