Skip to content
Browse files

OAuth2 support in Rack Filter. First step to refactoring to rack. Specs.

  • Loading branch information...
1 parent f805e8c commit 62eaa5c61dd1d8bc602705902547af9e10e32c14 @pelle committed Jan 14, 2011
View
2 .gitignore
@@ -6,3 +6,5 @@ pkg
*.gem
.bundle
.swp
+.idea
+.rvmrc
View
85 Gemfile.lock
@@ -0,0 +1,85 @@
+PATH
+ remote: .
+ specs:
+ oauth-plugin (0.4.0.pre4)
+ multi_json
+ oauth (~> 0.4.4)
+ rack
+
+GEM
+ remote: http://rubygems.org/
+ specs:
+ addressable (2.2.2)
+ configuration (1.2.0)
+ diff-lcs (1.1.2)
+ fakeweb (1.3.0)
+ faraday (0.5.4)
+ addressable (~> 2.2.2)
+ multipart-post (~> 1.1.0)
+ rack (>= 1.1.0, < 2)
+ faraday_middleware (0.3.1)
+ faraday (~> 0.5.3)
+ fuubar (0.0.3)
+ rspec (~> 2.0)
+ rspec-instafail (~> 0.1.4)
+ ruby-progressbar (~> 0.0.9)
+ growl (1.0.3)
+ guard (0.2.2)
+ open_gem (~> 1.4.2)
+ thor (~> 0.14.3)
+ guard-rspec (0.1.9)
+ guard (>= 0.2.2)
+ hashie (0.4.0)
+ launchy (0.3.7)
+ configuration (>= 0.0.5)
+ rake (>= 0.8.1)
+ multi_json (0.0.5)
+ multi_xml (0.2.0)
+ multipart-post (1.1.0)
+ oauth (0.4.4)
+ open_gem (1.4.2)
+ launchy (~> 0.3.5)
+ opentransact (0.1.0)
+ multi_json
+ multi_xml
+ oauth (~> 0.4.4)
+ rack (1.2.1)
+ rack-test (0.5.6)
+ rack (>= 1.0)
+ rake (0.8.7)
+ rspec (2.4.0)
+ rspec-core (~> 2.4.0)
+ rspec-expectations (~> 2.4.0)
+ rspec-mocks (~> 2.4.0)
+ rspec-core (2.4.0)
+ rspec-expectations (2.4.0)
+ diff-lcs (~> 1.1.2)
+ rspec-instafail (0.1.5)
+ rspec-mocks (2.4.0)
+ ruby-progressbar (0.0.9)
+ simple_oauth (0.1.3)
+ thor (0.14.6)
+ twitter (1.1.0)
+ faraday (~> 0.5.3)
+ faraday_middleware (~> 0.3.1)
+ hashie (~> 0.4.0)
+ multi_json (~> 0.0.5)
+ multi_xml (~> 0.2.0)
+ simple_oauth (~> 0.1.3)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ fakeweb
+ fuubar
+ growl
+ guard-rspec
+ multi_json
+ oauth (~> 0.4.4)
+ oauth-plugin!
+ opentransact
+ rack
+ rack-test
+ rspec (~> 2.4.0)
+ twitter
View
8 Guardfile
@@ -0,0 +1,8 @@
+# A sample Guardfile
+# More info at http://github.com/guard/guard#readme
+
+guard 'rspec', :version => 2 do
+ watch('^spec/(.*)_spec.rb')
+ watch('^lib/oauth/(.*)\.rb') { |m| "spec/#{m[1]}_spec.rb" }
+ watch('^spec/spec_helper.rb') { "spec" }
+end
View
27 lib/oauth/controllers/application_controller_methods.rb
@@ -39,6 +39,7 @@ class Authenticator
def initialize(controller,strategies)
@controller = controller
@strategies = strategies
+ controller.send :oauth_authenticator=, self
end
def params
@@ -180,11 +181,11 @@ def token_and_options
protected
def current_token
- @current_token
+ @oauth_authenticator.try(:token)
end
def current_client_application
- @current_client_application
+ @oauth_authenticator.try(:client_application)
end
def oauth?
@@ -213,26 +214,8 @@ def access_denied
private
- def current_token=(token)
- @current_token=token
- if @current_token
- @current_user=@current_token.user
- @current_client_application=@current_token.client_application
- else
- @current_user = nil
- @current_client_application = nil
- end
- @current_token
- end
-
- def current_client_application=(app)
- if app
- @current_client_application = app
- @current_user = app.user
- else
- @current_client_application = nil
- @current_user = nil
- end
+ def oauth_authenticator=(auth)
+ @oauth_authenticator = auth
end
end
end
View
51 lib/oauth/rack/oauth_filter.rb
@@ -1,6 +1,8 @@
require "rack"
require "rack/request"
-require "oauth/signature"
+require "oauth"
+require "oauth/request_proxy/rack_request"
+
module OAuth
module Rack
@@ -22,29 +24,56 @@ def initialize(app)
def call(env)
request = ::Rack::Request.new(env)
env["oauth_plugin"]=true
- if ClientApplication.verify_request(request) do |request_proxy|
+ if token_string = oauth2_token(request)
+ token = Oauth2Token.find_by_token(token_string) if token_string
+ if token
+ env["oauth.token"] = token
+ env["oauth.version"] = 2
+ 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
+ env["oauth.client_application_candidate"] = 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
- oauth_token = client_application.tokens.first(:conditions=>{:token => request_proxy.token})
- if oauth_token.respond_to?(:provided_oauth_verifier=)
- oauth_token.provided_oauth_verifier=request_proxy.oauth_verifier
+ oauth_token = nil
+
+ if request_proxy.token
+ oauth_token = client_application.tokens.first(:conditions=>{:token => request_proxy.token})
+ 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
# 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.token"] = env["oauth.token_candidate"]
env["oauth.client_application"] = env["oauth.client_application_candidate"]
-# Rails.logger.info "oauth.token = #{env["oauth.token"].inspect}"
+ env["oauth.version"] = 1
end
env["oauth.client_application_candidate"] = nil
env["oauth.token_candidate"] = nil
- response = @app.call(env)
+ @app.call(env)
end
- end
-
+
+ def oauth1_verify(request, options = {}, &block)
+ begin
+ signature = OAuth::Signature.build(request, options, &block)
+ return false unless OauthNonce.remember(signature.request.nonce, signature.request.timestamp)
+ value = signature.verify
+ value
+ rescue OAuth::Signature::UnknownSignatureMethod => e
+ false
+ end
+ end
+
+ def oauth2_token(request)
+ request.params["oauth_token"] ||
+ request.env["HTTP_AUTHORIZATION"] &&
+ request.env["HTTP_AUTHORIZATION"][/^(OAuth|Token) ([^\s]*)$/] && $2
+ end
+ end
end
end
View
11 oauth-plugin.gemspec
@@ -25,7 +25,14 @@ Gem::Specification.new do |s|
s.summary = %q{Ruby on Rails Plugin for OAuth Provider and Consumer}
s.add_development_dependency "twitter"
s.add_development_dependency "opentransact"
-
- s.add_dependency(%q<oauth>, [">= 0.4.4"])
+ s.add_development_dependency "rspec", "~> 2.4.0"
+ s.add_development_dependency "fakeweb"
+ s.add_development_dependency "fuubar"
+ s.add_development_dependency "guard-rspec"
+ s.add_development_dependency "growl"
+ s.add_development_dependency "rack-test"
+ s.add_dependency "multi_json"
+ s.add_dependency("oauth", ["~> 0.4.4"])
+ s.add_dependency("rack")
end
View
109 spec/rack/oauth_filter_spec.rb
@@ -0,0 +1,109 @@
+require 'spec_helper'
+require 'rack/test'
+require 'oauth/rack/oauth_filter'
+require 'multi_json'
+require 'forwardable'
+class OAuthEcho
+ def call(env)
+ response = {}
+ response[:oauth_token] = env["oauth.token"].token if env["oauth.token"]
+ response[:client_application] = env["oauth.client_application"].key if env["oauth.client_application"]
+ response[:oauth_version] = env["oauth.version"] if env["oauth.version"]
+ [200 ,{"Accept"=>"application/json"}, [MultiJson.encode(response)] ]
+ end
+end
+
+# Dummy implementation
+class ClientApplication
+ attr_accessor :key
+
+ def self.find_by_key(key)
+ ClientApplication.new(key)
+ end
+
+ def initialize(key)
+ @key = key
+ end
+
+ def secret
+ "secret"
+ end
+end
+
+class OauthToken
+ attr_accessor :token
+
+ def self.find_by_token(token)
+ OauthToken.new(token)
+ end
+
+ def initialize(token)
+ @token = token
+ end
+
+ def secret
+ "secret"
+ end
+end
+
+class Oauth2Token < OauthToken ; end
+
+class OauthNonce
+ # Always remember
+ def self.remember(nonce,timestamp)
+ true
+ end
+end
+
+describe OAuth::Rack::OAuthFilter do
+ include Rack::Test::Methods
+
+ def app
+ @app ||= OAuth::Rack::OAuthFilter.new(OAuthEcho.new)
+ end
+
+ it "should pass through without oauth" do
+ get '/'
+ last_response.should be_ok
+ response = MultiJson.decode(last_response.body)
+ response.should == {}
+ end
+
+# it "should sign with consumer" do
+# consumer = "consumer"
+# get '/'
+# last_response.should be_ok
+# response = MultiJson.decode(last_response.body)
+# response.should == {"client_application" => consumer}
+# end
+
+ it "should authenticate with oauth2 auth header" do
+ get '/',{},{"HTTP_AUTHORIZATION"=>"OAuth my_token"}
+ last_response.should be_ok
+ response = MultiJson.decode(last_response.body)
+ response.should == {"oauth_token" => "my_token", "oauth_version"=>2}
+ end
+
+ it "should authenticate with pre draft 10 oauth2 auth header" do
+ get '/',{},{"HTTP_AUTHORIZATION"=>"Token my_token"}
+ last_response.should be_ok
+ response = MultiJson.decode(last_response.body)
+ response.should == {"oauth_token" => "my_token", "oauth_version"=>2}
+ end
+
+ it "should authenticate with oauth2 query parameter" do
+ get '/?oauth_token=my_token'
+ last_response.should be_ok
+ response = MultiJson.decode(last_response.body)
+ response.should == {"oauth_token" => "my_token", "oauth_version"=>2}
+ end
+
+ it "should authenticate with oauth2 post parameter" do
+ post '/', :oauth_token=>'my_token'
+ last_response.should be_ok
+ response = MultiJson.decode(last_response.body)
+ response.should == {"oauth_token" => "my_token", "oauth_version"=>2}
+ end
+
+
+end
View
3 spec/spec_helper.rb
@@ -0,0 +1,3 @@
+$LOAD_PATH.unshift(File.dirname(__FILE__))
+$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
+require 'rspec'

0 comments on commit 62eaa5c

Please sign in to comment.
Something went wrong with that request. Please try again.