1
0
Fork 0
mirror of https://github.com/heartcombo/devise.git synced 2022-11-09 12:18:31 -05:00

Add OAuth url helpers.

This commit is contained in:
José Valim 2010-07-13 12:17:25 +02:00
parent bd8294aecf
commit faf771c798
7 changed files with 95 additions and 24 deletions

View file

@ -31,7 +31,7 @@ module Devise
end
# Constants which holds devise configuration for extensions. Those should
# not be modified by the "end user".
# not be modified by the "end user" (this is why they are constants).
ALL = []
CONTROLLERS = ActiveSupport::OrderedHash.new
ROUTES = ActiveSupport::OrderedHash.new
@ -115,10 +115,6 @@ module Devise
mattr_accessor :encryptor
@@encryptor = nil
# Store scopes mappings.
mattr_accessor :mappings
@@mappings = ActiveSupport::OrderedHash.new
# Tells if devise should apply the schema in ORMs where devise declaration
# and schema belongs to the same class (as Datamapper and Mongoid).
mattr_accessor :apply_schema
@ -173,9 +169,13 @@ module Devise
# PRIVATE CONFIGURATION
# Store scopes mappings.
mattr_reader :mappings
@@mappings = ActiveSupport::OrderedHash.new
# Oauth configurations.
mattr_reader :oauth_configs
@@oauth_configs = {}
@@oauth_configs = ActiveSupport::OrderedHash.new
# Private methods to interface with Warden.
mattr_accessor :warden_config
@ -195,7 +195,7 @@ module Devise
@@oauth_providers.uniq!
Devise::Oauth::Helpers.create_action(provider)
@@oauth_configs[provider] = Devise::Oauth::Config.new(*args)
@@oauth_configs[provider] = Devise::Oauth::Config.new(provider, *args)
end
def self.use_default_scope=(*)

View file

@ -54,7 +54,12 @@ module Devise
# Checks whether it's a devise mapped resource or not.
def is_devise_resource? #:nodoc:
raise ActionController::UnknownAction unless devise_mapping
unknown_action!("Could not find devise mapping for #{request.fullpath}.") unless devise_mapping
end
def unknown_action!(msg)
logger.debug msg
raise ActionController::UnknownAction, msg
end
# Sets the resource creating an instance variable
@ -90,12 +95,12 @@ module Devise
#
# Please refer to README or en.yml locale file to check what messages are
# available.
def set_flash_message(key, kind)
def set_flash_message(key, kind) #:nodoc:
flash[key] = I18n.t(:"#{resource_name}.#{kind}", :resource_name => resource_name,
:scope => [:devise, controller_name.to_sym], :default => kind)
end
def clean_up_passwords(object)
def clean_up_passwords(object) #:nodoc:
object.clean_up_passwords if object.respond_to?(:clean_up_passwords)
end
end

View file

@ -4,10 +4,26 @@ module Devise
extend ActiveSupport::Concern
module ClassMethods
def oauth_configs
def oauth_configs #:nodoc:
Devise.oauth_configs.slice(*oauth_providers)
end
# Pass a token stored in the database to this object to get an OAuth2::AccessToken
# object back, as the one received in your model hook.
#
# For each provider you add, you may want to add a hook to retrieve the token based
# on the column you stored the token in the database. For example, you may want to
# the following for twitter:
#
# def oauth_twitter_token
# @oauth_twitter_token ||= self.class.oauth_access_token(:twitter, twitter_token)
# end
#
# You can call get, post, put and delete in this object to access Twitter's API.
def oauth_access_token(provider, token)
oauth_configs[provider].access_token(token)
end
Devise::Models.config(self, :oauth_providers)
end
end

View file

@ -1,12 +1,28 @@
require 'active_support/core_ext/array/wrap'
module Devise
module Oauth
class Config
attr_reader :scope, :client
attr_reader :name, :scope, :client
def initialize(app_id, app_secret, options)
@scope = Array.wrap(options.delete(:scope)).join(",")
def initialize(name, app_id, app_secret, options)
@name = name
@scope = Array.wrap(options.delete(:scope))
@client = OAuth2::Client.new(app_id, app_secret, options)
end
def authorize_url(options)
options[:scope] ||= @scope.join(',')
client.web_server.authorize_url(options)
end
def access_token_by_code(code)
client.web_server.get_access_token(code)
end
def access_token_by_token(token)
OAuth2::AccessToken.new(client, token)
end
end
end
end

View file

@ -9,7 +9,7 @@ module Devise
end
included do
helpers = %w(oauth_callback oauth_config oauth_client)
helpers = %w(oauth_callback oauth_config)
hide_action *helpers
helper_method *helpers
before_filter :is_oauth_callback?
@ -23,15 +23,22 @@ module Devise
@oauth_client ||= resource_class.oauth_configs[oauth_callback]
end
def oauth_client
@oauth_client ||= oauth_config.client
end
protected
def is_oauth_callback?
raise ActionController::UnknownAction unless oauth_config
raise ActionController::UnknownAction unless params[:code]
unless params[:code]
unknown_action! "Skipping OAuth #{outh_callback.inspect} callback because code was not sent."
end
unless oauth_config
unknown_action! "Skipping OAuth #{outh_callback.inspect} callback because provider " <<
"could not be found in model #{resource_name.inspect}."
end
unless resource_class.respond_to?(oauth_model_callback)
raise "#{resource_class.name} does not respond to to OAuth callback #{oauth_model_callback.inspect}. " <<
"Check the OAuth section in the README for more information."
end
end
def oauth_model_callback
@ -39,12 +46,14 @@ module Devise
end
def callback_action
access_token = oauth_client.web_server.get_access_token(params[:code])
self.resource = User.send(oauth_model_callback, access_token, signed_in_resource)
access_token = oauth_config.access_token_by_code(params[:code])
self.resource = resource_class.send(oauth_model_callback, access_token, signed_in_resource)
if resource.persisted?
# ADD FLASH MESSAGE
sign_in_and_redirect resource_name, resource, :event => :authentication
else
# STORE STUFF IN SESSION
render_for_oauth
end
end

View file

@ -1,7 +1,32 @@
module Devise
module Oauth
module UrlHelpers
[:path, :url].each do |path_or_url|
class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
def oauth_callback_#{path_or_url}(resource_or_scope, *args)
scope = Devise::Mapping.find_scope!(resource_or_scope)
send("\#{scope}_oauth_callback_#{path_or_url}", *args)
end
URL_HELPERS
end
def oauth_authorize_url(resource_or_scope, *args)
scope = Devise::Mapping.find_scope!(resource_or_scope)
send("#{scope}_oauth_authorize_url}", *args)
end
Devise.mappings.each_key do |scope|
class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
def #{scope}_oauth_authorize_url(provider, options={})
if config = Devise.oauth_configs[provider.to_sym]
options[:redirect_uri] ||= #{scope}_oauth_callback_url
config.authorize_url(options)
else
raise ArgumentError, "Could not find oauth provider #{provider.inspect}"
end
end
URL_HELPERS
end
end
end
end