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:
parent
bd8294aecf
commit
faf771c798
7 changed files with 95 additions and 24 deletions
|
@ -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=(*)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in a new issue