mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
Basic omniauth support.
This commit is contained in:
parent
bca72ddf59
commit
21d5e50054
11 changed files with 215 additions and 18 deletions
|
@ -6,6 +6,7 @@ require 'set'
|
|||
module Devise
|
||||
autoload :FailureApp, 'devise/failure_app'
|
||||
autoload :Oauth, 'devise/oauth'
|
||||
autoload :OmniAuth, 'devise/omniauth'
|
||||
autoload :PathChecker, 'devise/path_checker'
|
||||
autoload :Schema, 'devise/schema'
|
||||
autoload :TestHelpers, 'devise/test_helpers'
|
||||
|
@ -180,10 +181,6 @@ module Devise
|
|||
mattr_accessor :sign_out_via
|
||||
@@sign_out_via = :get
|
||||
|
||||
# Oauth providers
|
||||
mattr_accessor :oauth_providers
|
||||
@@oauth_providers = []
|
||||
|
||||
# PRIVATE CONFIGURATION
|
||||
|
||||
# Store scopes mappings.
|
||||
|
@ -194,15 +191,15 @@ module Devise
|
|||
mattr_reader :oauth_configs
|
||||
@@oauth_configs = ActiveSupport::OrderedHash.new
|
||||
|
||||
# Omniauth configurations.
|
||||
mattr_reader :omniauth_configs
|
||||
@@omniauth_configs = ActiveSupport::OrderedHash.new
|
||||
|
||||
# Define a set of modules that are called when a mapping is added.
|
||||
mattr_reader :helpers
|
||||
@@helpers = Set.new
|
||||
@@helpers << Devise::Controllers::Helpers
|
||||
|
||||
# Define a set of modules that are called when a provider is added.
|
||||
mattr_reader :oauth_helpers
|
||||
@@oauth_helpers = Set.new
|
||||
|
||||
# Private methods to interface with Warden.
|
||||
mattr_accessor :warden_config
|
||||
@@warden_config = nil
|
||||
|
@ -214,6 +211,14 @@ module Devise
|
|||
yield self
|
||||
end
|
||||
|
||||
def self.oauth_providers
|
||||
oauth_configs.keys
|
||||
end
|
||||
|
||||
def self.omniauth_providers
|
||||
omniauth_configs.keys
|
||||
end
|
||||
|
||||
def self.cookie_domain=(value)
|
||||
ActiveSupport::Deprecation.warn "Devise.cookie_domain=(value) is deprecated. "
|
||||
"Please use Devise.cookie_options = { :domain => value } instead."
|
||||
|
@ -322,19 +327,23 @@ module Devise
|
|||
#
|
||||
def self.oauth(provider, *args)
|
||||
@@helpers << Devise::Oauth::UrlHelpers
|
||||
@@oauth_helpers << Devise::Oauth::InternalHelpers
|
||||
|
||||
@@oauth_providers << provider
|
||||
@@oauth_providers.uniq!
|
||||
|
||||
@@oauth_helpers.each { |h| h.define_oauth_helpers(provider) }
|
||||
Devise::Oauth::InternalHelpers.define_oauth_helpers(provider)
|
||||
@@oauth_configs[provider] = Devise::Oauth::Config.new(*args)
|
||||
end
|
||||
|
||||
# Specify an omniauth provider.
|
||||
#
|
||||
# config.omniauth :github, APP_ID, APP_SECRET
|
||||
#
|
||||
def self.omniauth(provider, *args)
|
||||
@@helpers << Devise::OmniAuth::UrlHelpers
|
||||
@@omniauth_configs[provider] = Devise::OmniAuth::Config.new(provider, args)
|
||||
end
|
||||
|
||||
# Include helpers in the given scope to AC and AV.
|
||||
def self.include_helpers(scope)
|
||||
ActiveSupport.on_load(:action_controller) do
|
||||
include scope::Helpers
|
||||
include scope::Helpers if defined?(scope::Helpers)
|
||||
include scope::UrlHelpers
|
||||
end
|
||||
|
||||
|
|
|
@ -222,6 +222,7 @@ module Devise
|
|||
# A hook called to expire session data after sign up/in. This is used
|
||||
# by a few extensions, like oauth, to expire tokens stored in session.
|
||||
def expire_session_data_after_sign_in!
|
||||
session.keys.grep(/^devise\./).each { |k| session.delete(k) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -84,7 +84,7 @@ module Devise
|
|||
end
|
||||
|
||||
def fullpath
|
||||
"#{@path_prefix}/#{@path}".squeeze("/")
|
||||
"/#{@path_prefix}/#{@path}".squeeze("/")
|
||||
end
|
||||
|
||||
# Create magic predicates for verifying what module is activated by this map.
|
||||
|
|
26
lib/devise/models/omniauthable.rb
Normal file
26
lib/devise/models/omniauthable.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
require 'devise/omniauth'
|
||||
|
||||
module Devise
|
||||
module Models
|
||||
# Adds OAuth support to your model. The whole workflow is deeply discussed in the
|
||||
# README. This module adds just a class +oauth_access_token+ helper to your model
|
||||
# which assists you on creating an access token. All the other OAuth hooks in
|
||||
# Devise must be implemented by yourself in your application.
|
||||
#
|
||||
# == Options
|
||||
#
|
||||
# Oauthable adds the following options to devise_for:
|
||||
#
|
||||
# * +oauth_providers+: Which providers are avaialble to this model. It expects an array:
|
||||
#
|
||||
# devise_for :database_authenticatable, :oauthable, :oauth_providers => [:twitter]
|
||||
#
|
||||
module Omniauthable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
module ClassMethods
|
||||
Devise::Models.config(self, :omniauth_providers)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -11,7 +11,8 @@ Devise.with_options :model => true do |d|
|
|||
|
||||
# Other authentications
|
||||
d.add_module :encryptable
|
||||
d.add_module :oauthable, :controller => :oauth_callbacks, :route => :oauth_callback
|
||||
d.add_module :oauthable, :controller => :oauth_callbacks, :route => :oauth_callback
|
||||
d.add_module :omniauthable, :controller => :omniauth_callbacks, :route => :omniauth_callback
|
||||
|
||||
# Misc after
|
||||
routes = [nil, :new, :edit]
|
||||
|
|
55
lib/devise/omniauth.rb
Normal file
55
lib/devise/omniauth.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
begin
|
||||
require "omniauth/core"
|
||||
rescue LoadError => e
|
||||
warn "Could not load 'omniauth/core'. Please ensure you have the oa-core gem installed and listed in your Gemfile."
|
||||
raise
|
||||
end
|
||||
|
||||
module OmniAuth
|
||||
module Strategy
|
||||
# TODO HAX Backport to OmniAuth
|
||||
def initialize(app, name, *args)
|
||||
@app = app
|
||||
@name = name.to_sym
|
||||
yield self if block_given?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module Devise
|
||||
module OmniAuth
|
||||
autoload :Config, "devise/omniauth/config"
|
||||
autoload :UrlHelpers, "devise/omniauth/url_helpers"
|
||||
autoload :TestHelpers, "devise/omniauth/test_helpers"
|
||||
|
||||
class << self
|
||||
delegate :short_circuit_authorizers!, :unshort_circuit_authorizers!, :to => "Devise::OmniAuth::TestHelpers"
|
||||
|
||||
def test_mode!
|
||||
Faraday.default_adapter = :test if defined?(Faraday)
|
||||
ActiveSupport.on_load(:action_controller) { include Devise::OmniAuth::TestHelpers }
|
||||
ActiveSupport.on_load(:action_view) { include Devise::OmniAuth::TestHelpers }
|
||||
end
|
||||
|
||||
def stub!(provider, stubs=nil, &block)
|
||||
raise "You either need to pass stubs as a block or as a parameter" unless block_given? || stubs
|
||||
|
||||
config = Devise.omniauth_configs[provider]
|
||||
config.check_if_allow_stubs!
|
||||
|
||||
stubs ||= Faraday::Adapter::Test::Stubs.new(&block)
|
||||
config.build_connection do |b|
|
||||
b.adapter :test, stubs
|
||||
end
|
||||
end
|
||||
|
||||
def reset_stubs!(*providers)
|
||||
target = providers.any? ? Devise.omniauth_configs.slice(*providers) : Devise.omniauth_configs
|
||||
target.each_value do |config|
|
||||
next unless config.allow_stubs?
|
||||
config.build_connection { |b| b.adapter Faraday.default_adapter }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
30
lib/devise/omniauth/config.rb
Normal file
30
lib/devise/omniauth/config.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
module Devise
|
||||
module OmniAuth
|
||||
class Config
|
||||
attr_accessor :strategy
|
||||
attr_reader :args
|
||||
|
||||
def initialize(provider, args)
|
||||
@provider = provider
|
||||
@args = args
|
||||
@strategy = nil
|
||||
end
|
||||
|
||||
def strategy_class
|
||||
::OmniAuth::Strategies.const_get("#{::OmniAuth::Utils.camelize(@provider.to_s)}")
|
||||
end
|
||||
|
||||
def check_if_allow_stubs!
|
||||
raise "#{@provider} OmniAuth strategy does not allow stubs, only OAuth2 ones." unless allow_stubs?
|
||||
end
|
||||
|
||||
def allow_stubs?
|
||||
!(defined?(OmniAuth::Strategies::OAuth2) && strategy.is_a?(OmniAuth::Strategies::OAuth2))
|
||||
end
|
||||
|
||||
def build_connection(&block)
|
||||
strategy.client.connection.build(&block)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
29
lib/devise/omniauth/test_helpers.rb
Normal file
29
lib/devise/omniauth/test_helpers.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
module Devise
|
||||
module OmniAuth
|
||||
module TestHelpers #:nodoc:
|
||||
def self.short_circuit_authorizers!
|
||||
module_eval <<-ALIASES, __FILE__, __LINE__ + 1
|
||||
def omniauth_authorize_path(*args)
|
||||
omniauth_callback_path(*args)
|
||||
end
|
||||
ALIASES
|
||||
|
||||
Devise.mappings.each_value do |m|
|
||||
next unless m.omniauthable?
|
||||
|
||||
module_eval <<-ALIASES, __FILE__, __LINE__ + 1
|
||||
def #{m.name}_omniauth_authorize_path(provider)
|
||||
#{m.name}_omniauth_callback_path(provider)
|
||||
end
|
||||
ALIASES
|
||||
end
|
||||
end
|
||||
|
||||
def self.unshort_circuit_authorizers!
|
||||
module_eval do
|
||||
instance_methods.each { |m| remove_method(m) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
29
lib/devise/omniauth/url_helpers.rb
Normal file
29
lib/devise/omniauth/url_helpers.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
module Devise
|
||||
module OmniAuth
|
||||
module UrlHelpers
|
||||
def self.define_helpers(mapping)
|
||||
return unless mapping.omniauthable?
|
||||
|
||||
class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
|
||||
def #{mapping.name}_omniauth_authorize_path(provider)
|
||||
if Devise.omniauth_configs[provider.to_sym]
|
||||
"#{mapping.fullpath}/auth/\#{provider}"
|
||||
else
|
||||
raise ArgumentError, "Could not find omniauth provider \#{provider.inspect}"
|
||||
end
|
||||
end
|
||||
URL_HELPERS
|
||||
end
|
||||
|
||||
def omniauth_authorize_path(resource_or_scope, *args)
|
||||
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
||||
send("#{scope}_omniauth_authorize_path", *args)
|
||||
end
|
||||
|
||||
def omniauth_callback_url(resource_or_scope, *args)
|
||||
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
||||
send("#{scope}_omniauth_callback_path", *args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -29,11 +29,23 @@ module Devise
|
|||
end
|
||||
|
||||
initializer "devise.oauth_url_helpers" do
|
||||
if Devise.oauth_providers.any?
|
||||
if Devise.oauth_configs.any?
|
||||
Devise.include_helpers(Devise::Oauth)
|
||||
end
|
||||
end
|
||||
|
||||
initializer "devise.omniauth" do |app|
|
||||
Devise.omniauth_configs.each do |provider, config|
|
||||
app.middleware.use config.strategy_class, *config.args do |strategy|
|
||||
config.strategy = strategy
|
||||
end
|
||||
end
|
||||
|
||||
if Devise.omniauth_configs.any?
|
||||
Devise.include_helpers(Devise::OmniAuth)
|
||||
end
|
||||
end
|
||||
|
||||
initializer "devise.encryptor_check" do
|
||||
case Devise.encryptor
|
||||
when :bcrypt
|
||||
|
|
|
@ -243,6 +243,11 @@ module ActionDispatch::Routing
|
|||
:to => controllers[:oauth_callbacks], :as => :oauth_callback
|
||||
end
|
||||
|
||||
def devise_omniauth_callback(mapping, controllers) #:nodoc:
|
||||
get "/auth/:action/callback", :action => Regexp.union(mapping.to.omniauth_providers.map(&:to_s)),
|
||||
:to => controllers[:omniauth_callbacks], :as => :omniauth_callback
|
||||
end
|
||||
|
||||
def with_devise_exclusive_scope(new_path, new_as) #:nodoc:
|
||||
old_as, old_path, old_module = @scope[:as], @scope[:path], @scope[:module]
|
||||
@scope[:as], @scope[:path], @scope[:module] = new_as, new_path, nil
|
||||
|
|
Loading…
Reference in a new issue