lib/oauth/controllers/application_controller_methods.rb in oauth-plugin-0.3.14 vs lib/oauth/controllers/application_controller_methods.rb in oauth-plugin-0.4.0.pre1

- old
+ new

@@ -1,109 +1,212 @@ require 'oauth/signature' module OAuth module Controllers module ApplicationControllerMethods + + def self.included(controller) + controller.class_eval do + extend ClassMethods + end + end + + module ClassMethods + def oauthenticate(options={}) + filter_options = {} + filter_options[:only] = options.delete(:only) if options[:only] + filter_options[:except] = options.delete(:except) if options[:except] + before_filter Filter.new(options), filter_options + end + end + + class Filter + def initialize(options={}) + @options={ + :interactive=>true, + :strategies => [:token,:two_legged] + }.merge(options) + @strategies = Array(@options[:strategies]) + @strategies << :interactive if @options[:interactive] + end + + def filter(controller) + Authenticator.new(controller,@strategies).allow? + end + end + + class Authenticator + attr_accessor :controller, :strategies, :strategy + def initialize(controller,strategies) + @controller = controller + @strategies = strategies + end + + def params + controller.send :params + end + def request + controller.send :request + end + + def allow? + if @strategies.any? do |strategy| + @strategy = strategy.to_sym + send @strategy + end + true + else + if @strategies.include?(:interactive) + controller.send :access_denied + else + controller.send :invalid_oauth_response + end + end + end + + def oauth20_token + return false unless defined?(Oauth2Token) + token, options = token_and_options + token ||= params[:oauth_token] || params[:access_token] + if !token.blank? + @oauth2_token = Oauth2Token.find_by_token(token) + if @oauth2_token && @oauth2_token.authorized? + controller.send :current_token=, @oauth2_token + end + end + @oauth2_token!=nil + end + + def oauth10_token + begin + if ClientApplication.verify_request(request) do |request_proxy| + @oauth_token = ClientApplication.find_token(request_proxy.token) + if @oauth_token.respond_to?(:provided_oauth_verifier=) + @oauth_token.provided_oauth_verifier=request_proxy.oauth_verifier + end + # return the token secret and the consumer secret + [(@oauth_token.nil? ? nil : @oauth_token.secret), (@oauth_token.client_application.nil? ? nil : @oauth_token.client_application.secret)] + end + controller.send :current_token=, @oauth_token + true + else + false + end + rescue + false + end + end + + def oauth10_request_token + oauth10_token && @oauth_token.is_a?(::RequestToken) + end + + def oauth10_access_token + oauth10_token && @oauth_token.is_a?(::AccessToken) + end + + def token + oauth20_token || oauth10_access_token + end + + def two_legged + begin + if ClientApplication.verify_request(request) do |request_proxy| + @client_application = ClientApplication.find_by_key(request_proxy.consumer_key) + + # 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 + + # return the token secret and the consumer secret + [nil, @client_application.secret] + end + controller.send :current_client_application=, @client_application + true + else + false + end + rescue + false + end + end + + def interactive + @controller.send :logged_in? + end + + # Blatantly stolen from http://github.com/technoweenie/http_token_authentication + # Parses the token and options out of the OAuth authorization header. If + # the header looks like this: + # Authorization: OAuth abc + # Then the returned token is "abc", and the options is {:nonce => "def"} + # + # request - ActionController::Request instance with the current headers. + # + # Returns an Array of [String, Hash] if a token is present. + # Returns nil if no token is found. + def token_and_options + if header = (request.respond_to?(:authorization) ? request.authorization : ActionController::HttpAuthentication::Basic.authorization(request)).to_s[/^OAuth (.*)/] + [$1.strip, {}] + end + end + + end + protected def current_token @current_token end def current_client_application @current_client_application end - def oauthenticate - verified=verify_oauth_signature - return verified && current_token.is_a?(::AccessToken) - end - def oauth? current_token!=nil end - # use in a before_filter + # use in a before_filter. Note this is for compatibility purposes. Better to use oauthenticate now def oauth_required - if oauthenticate - if authorized? - return true - else - invalid_oauth_response - end - else - invalid_oauth_response - end + Authenticator.new(self,[:oauth10_access_token]).allow? end - # This requies that you have an acts_as_authenticated compatible authentication plugin installed + # use in before_filter. Note this is for compatibility purposes. Better to use oauthenticate now def login_or_oauth_required - if oauthenticate - if authorized? - return true - else - invalid_oauth_response - end - else - login_required - end + Authenticator.new(self,[:oauth10_access_token,:interactive]).allow? end - - # verifies a request token request - def verify_oauth_consumer_signature - begin - valid = ClientApplication.verify_request(request) do |request_proxy| - @current_client_application = ClientApplication.find_by_key(request_proxy.consumer_key) - - # Store this temporarily in client_application object for use in request token generation - @current_client_application.token_callback_url=request_proxy.oauth_callback if request_proxy.oauth_callback - - # return the token secret and the consumer secret - [nil, @current_client_application.secret] - end - rescue - valid=false - end - - invalid_oauth_response unless valid - end - - def verify_oauth_request_token - verify_oauth_signature && current_token.is_a?(::RequestToken) - end - def invalid_oauth_response(code=401,message="Invalid OAuth Request") render :text => message, :status => code + false end + + # override this in your controller + def access_denied + head 401 + end private def current_token=(token) @current_token=token if @current_token @current_user=@current_token.user - @current_client_application=@current_token.client_application + @current_client_application=@current_token.client_application + else + @current_user = nil + @current_client_application = nil end @current_token end - # Implement this for your own application using app-specific models - def verify_oauth_signature - begin - valid = ClientApplication.verify_request(request) do |request_proxy| - self.current_token = ClientApplication.find_token(request_proxy.token) - if self.current_token.respond_to?(:provided_oauth_verifier=) - self.current_token.provided_oauth_verifier=request_proxy.oauth_verifier - end - # return the token secret and the consumer secret - [(current_token.nil? ? nil : current_token.secret), (current_client_application.nil? ? nil : current_client_application.secret)] - end - # reset @current_user to clear state for restful_...._authentication - @current_user = nil if (!valid) - valid - rescue - false + def current_client_application=(app) + if app + @current_client_application = app + @current_user = app.user + else + @current_client_application = nil + @current_user = nil end end end end end \ No newline at end of file