mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
Remove OAuth2 in favor of OmniAuth.
This commit is contained in:
parent
5d4e4fbb88
commit
2f360bf201
26 changed files with 91 additions and 528 deletions
2
Gemfile
2
Gemfile
|
@ -5,7 +5,7 @@ gemspec
|
|||
gem "rails", "3.0.0"
|
||||
gem "webrat", "0.7.1"
|
||||
gem "mocha", :require => false
|
||||
gem "oauth2"
|
||||
gem "oa-oauth", :require => "omniauth/oauth"
|
||||
|
||||
platforms :jruby do
|
||||
gem 'activerecord-jdbcsqlite3-adapter'
|
||||
|
|
17
Gemfile.lock
17
Gemfile.lock
|
@ -77,9 +77,18 @@ GEM
|
|||
nokogiri (1.4.3.1)
|
||||
nokogiri (1.4.3.1-java)
|
||||
weakling (>= 0.0.3)
|
||||
oauth2 (0.1.0)
|
||||
faraday (~> 0.5.0)
|
||||
multi_json (~> 0.0.4)
|
||||
oa-core (0.1.4)
|
||||
rack (~> 1.1)
|
||||
oa-oauth (0.1.4)
|
||||
multi_json (~> 0.0.2)
|
||||
nokogiri (~> 1.4.2)
|
||||
oa-core (= 0.1.4)
|
||||
oauth (~> 0.4.0)
|
||||
oauth2 (~> 0.0.10)
|
||||
oauth (0.4.3)
|
||||
oauth2 (0.0.13)
|
||||
faraday (>= 0.4.1)
|
||||
multi_json (>= 0.0.4)
|
||||
orm_adapter (0.0.2)
|
||||
polyglot (0.3.1)
|
||||
rack (1.2.1)
|
||||
|
@ -132,7 +141,7 @@ DEPENDENCIES
|
|||
mocha
|
||||
mongo (= 1.0.7)
|
||||
mongoid (= 2.0.0.beta.18)
|
||||
oauth2
|
||||
oa-oauth
|
||||
orm_adapter (~> 0.0.2)
|
||||
rails (= 3.0.0)
|
||||
ruby-debug (>= 0.10.3)
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
class Devise::OauthCallbacksController < ApplicationController
|
||||
include Devise::Controllers::InternalHelpers
|
||||
include Devise::Oauth::InternalHelpers
|
||||
end
|
6
app/controllers/devise/omniauth_callbacks_controller.rb
Normal file
6
app/controllers/devise/omniauth_callbacks_controller.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
class Devise::OmniauthCallbacksController < ApplicationController
|
||||
include Devise::Controllers::InternalHelpers
|
||||
|
||||
def failure
|
||||
end
|
||||
end
|
|
@ -5,7 +5,6 @@ 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'
|
||||
|
@ -187,10 +186,6 @@ module Devise
|
|||
mattr_reader :mappings
|
||||
@@mappings = ActiveSupport::OrderedHash.new
|
||||
|
||||
# Oauth configurations.
|
||||
mattr_reader :oauth_configs
|
||||
@@oauth_configs = ActiveSupport::OrderedHash.new
|
||||
|
||||
# Omniauth configurations.
|
||||
mattr_reader :omniauth_configs
|
||||
@@omniauth_configs = ActiveSupport::OrderedHash.new
|
||||
|
@ -211,10 +206,6 @@ module Devise
|
|||
yield self
|
||||
end
|
||||
|
||||
def self.oauth_providers
|
||||
oauth_configs.keys
|
||||
end
|
||||
|
||||
def self.omniauth_providers
|
||||
omniauth_configs.keys
|
||||
end
|
||||
|
@ -317,20 +308,6 @@ module Devise
|
|||
@@warden_config_block = block
|
||||
end
|
||||
|
||||
# Specify an oauth provider.
|
||||
#
|
||||
# config.oauth :github, APP_ID, APP_SECRET,
|
||||
# :site => 'https://github.com/',
|
||||
# :authorize_path => '/login/oauth/authorize',
|
||||
# :access_token_path => '/login/oauth/access_token',
|
||||
# :scope => %w(user public_repo)
|
||||
#
|
||||
def self.oauth(provider, *args)
|
||||
@@helpers << Devise::Oauth::UrlHelpers
|
||||
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
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
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 Oauthable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
module ClassMethods
|
||||
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_by_token(token)
|
||||
end
|
||||
|
||||
# TODO Implement this method in the future.
|
||||
# def refresh_oauth_token(provider, refresh_token)
|
||||
# returns access_token
|
||||
# end
|
||||
|
||||
Devise::Models.config(self, :oauth_providers)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,18 +2,15 @@ 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.
|
||||
# Adds OmniAuth support to your model.
|
||||
#
|
||||
# == Options
|
||||
#
|
||||
# Oauthable adds the following options to devise_for:
|
||||
#
|
||||
# * +oauth_providers+: Which providers are avaialble to this model. It expects an array:
|
||||
# * +omniauth_providers+: Which providers are avaialble to this model. It expects an array:
|
||||
#
|
||||
# devise_for :database_authenticatable, :oauthable, :oauth_providers => [:twitter]
|
||||
# devise_for :database_authenticatable, :omniauthable, :omniauth_providers => [:twitter]
|
||||
#
|
||||
module Omniauthable
|
||||
extend ActiveSupport::Concern
|
||||
|
|
|
@ -11,7 +11,6 @@ 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 :omniauthable, :controller => :omniauth_callbacks, :route => :omniauth_callback
|
||||
|
||||
# Misc after
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
begin
|
||||
require "oauth2"
|
||||
rescue LoadError => e
|
||||
warn "Could not load 'oauth2'. Please ensure you have the gem installed and listed in your Gemfile."
|
||||
raise
|
||||
end
|
||||
|
||||
module Devise
|
||||
module Oauth
|
||||
autoload :Config, "devise/oauth/config"
|
||||
autoload :Helpers, "devise/oauth/helpers"
|
||||
autoload :InternalHelpers, "devise/oauth/internal_helpers"
|
||||
autoload :UrlHelpers, "devise/oauth/url_helpers"
|
||||
autoload :TestHelpers, "devise/oauth/test_helpers"
|
||||
|
||||
class << self
|
||||
delegate :short_circuit_authorizers!, :unshort_circuit_authorizers!, :to => "Devise::Oauth::TestHelpers"
|
||||
|
||||
def test_mode!
|
||||
Faraday.default_adapter = :test
|
||||
ActiveSupport.on_load(:action_controller) { include Devise::Oauth::TestHelpers }
|
||||
ActiveSupport.on_load(:action_view) { include Devise::Oauth::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
|
||||
stubs ||= Faraday::Adapter::Test::Stubs.new(&block)
|
||||
Devise.oauth_configs[provider].build_connection do |b|
|
||||
b.adapter :test, stubs
|
||||
end
|
||||
end
|
||||
|
||||
def reset_stubs!(*providers)
|
||||
target = providers.any? ? Devise.oauth_configs.slice(*providers) : Devise.oauth_configs
|
||||
target.each_value do |v|
|
||||
v.build_connection { |b| b.adapter Faraday.default_adapter }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,33 +0,0 @@
|
|||
require 'active_support/core_ext/array/wrap'
|
||||
|
||||
module Devise
|
||||
module Oauth
|
||||
# A configuration object that holds the OAuth2::Client object
|
||||
# and all configuration values given config.oauth.
|
||||
class Config
|
||||
attr_reader :scope, :client
|
||||
|
||||
def initialize(app_id, app_secret, options)
|
||||
@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, redirect_uri=nil)
|
||||
client.web_server.get_access_token(code, :redirect_uri => redirect_uri)
|
||||
end
|
||||
|
||||
def access_token_by_token(token)
|
||||
OAuth2::AccessToken.new(client, token)
|
||||
end
|
||||
|
||||
def build_connection(&block)
|
||||
client.connection.build(&block)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,18 +0,0 @@
|
|||
module Devise
|
||||
module Oauth
|
||||
# Provides a few helpers that are included in ActionController::Base
|
||||
# for convenience.
|
||||
module Helpers
|
||||
|
||||
protected
|
||||
|
||||
# Overwrite expire_session_data_after_sign_in! so it removes all
|
||||
# oauth tokens from session ensuring registrations done in a row
|
||||
# do not try to store the same token in the database.
|
||||
def expire_session_data_after_sign_in!
|
||||
super
|
||||
session.keys.grep(/_oauth_token$/).each { |k| session.delete(k) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,182 +0,0 @@
|
|||
module Devise
|
||||
module Oauth
|
||||
module InternalHelpers
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def self.define_oauth_helpers(name) #:nodoc:
|
||||
alias_method(name, :callback_action)
|
||||
public name
|
||||
end
|
||||
|
||||
included do
|
||||
helpers = %w(oauth_callback oauth_provider oauth_config)
|
||||
hide_action *helpers
|
||||
helper_method *helpers
|
||||
before_filter :valid_oauth_callback?, :oauth_error_happened?
|
||||
end
|
||||
|
||||
# Returns the oauth_callback (also aliased as oauth_provider) as a symbol.
|
||||
# For example: :github.
|
||||
def oauth_callback
|
||||
@oauth_callback ||= action_name.to_sym
|
||||
end
|
||||
alias :oauth_provider :oauth_callback
|
||||
|
||||
# Returns the configuration object for this oauth callback.
|
||||
def oauth_config
|
||||
@oauth_client ||= resource_class.oauth_configs[oauth_callback]
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# This method checks three things:
|
||||
#
|
||||
# * If the URL being accessed is a valid provider for the given scope;
|
||||
# * If code or error was streamed back from the server;
|
||||
# * If the resource class implements the required hook;
|
||||
#
|
||||
def valid_oauth_callback?
|
||||
unless oauth_config
|
||||
unknown_action! "Skipping #{oauth_callback} OAuth because configuration " <<
|
||||
"could not be found for model #{resource_name}."
|
||||
end
|
||||
|
||||
unless params[:code] || params[:error] || params[:error_reason]
|
||||
unknown_action! "Skipping #{oauth_callback} OAuth because code nor error were sent."
|
||||
end
|
||||
|
||||
unless resource_class.respond_to?(oauth_model_callback)
|
||||
raise "#{resource_class.name} does not respond to #{oauth_model_callback}. " <<
|
||||
"Check the OAuth section in the README for more information."
|
||||
end
|
||||
end
|
||||
|
||||
# Check if an error was sent by the authorizer. If it happened, we redirect
|
||||
# to url specified by after_oauth_failure_path_for, which defaults to new_session_path.
|
||||
#
|
||||
# By default, Devise shows a custom message from I18n saying the user could
|
||||
# not be authenticated and the reason:
|
||||
#
|
||||
# en:
|
||||
# devise:
|
||||
# oauth_callbacks:
|
||||
# failure: 'Could not authorize you from %{kind} because "%{reason}".'
|
||||
#
|
||||
# Let's suppose the reason returned by a Github was "access_denied". It will show:
|
||||
#
|
||||
# Could not authorize you from Github because "Access denied"
|
||||
#
|
||||
# And it will also be logged on console:
|
||||
#
|
||||
# github oauth failed: "access_denied".
|
||||
#
|
||||
# However, each specific error message can be customized using I18n:
|
||||
#
|
||||
# en:
|
||||
# devise:
|
||||
# oauth_callbacks:
|
||||
# access_denied: 'You did not give access to our application on %{kind}.'
|
||||
#
|
||||
# Note "access_denied" follows the same lookup rule described in set_oauth_flash_message
|
||||
# method. Besides, is important to remember most errors are specified by OAuth 2
|
||||
# specification. But a few providers do not use them yet.
|
||||
#
|
||||
# TODO: Currently, Facebook is returning error_reason=user_denied when
|
||||
# the user denies, but the specification defines error=access_denied instead.
|
||||
def oauth_error_happened?
|
||||
if error = params[:error] || params[:error_reason]
|
||||
# Some providers returns access-denied instead of access_denied.
|
||||
error = error.to_s.gsub("-", "_")
|
||||
logger.warn "[Devise] #{oauth_callback} oauth failed: #{error.inspect}."
|
||||
|
||||
set_oauth_flash_message :alert, :failure, :reason => error.humanize
|
||||
redirect_to after_oauth_failure_path_for(resource_name)
|
||||
end
|
||||
end
|
||||
|
||||
# The model method used as hook.
|
||||
def oauth_model_callback #:nodoc:
|
||||
"find_for_#{oauth_callback}_oauth"
|
||||
end
|
||||
|
||||
# The session key to store the token.
|
||||
def oauth_session_key #:nodoc:
|
||||
"#{resource_name}_#{oauth_callback}_oauth_token"
|
||||
end
|
||||
|
||||
# The callback redirect uri. Used to request the access token.
|
||||
def oauth_redirect_uri #:nodoc:
|
||||
oauth_callback_url(resource_name, oauth_callback)
|
||||
end
|
||||
|
||||
# This is the implementation for all OAuth actions.
|
||||
def callback_action
|
||||
access_token = oauth_config.access_token_by_code(params[:code], oauth_redirect_uri)
|
||||
self.resource = resource_class.send(oauth_model_callback, access_token, signed_in_resource)
|
||||
|
||||
if resource.persisted? && resource.errors.empty?
|
||||
set_oauth_flash_message :notice, :success
|
||||
sign_in_and_redirect resource_name, resource, :event => :authentication
|
||||
else
|
||||
session[oauth_session_key] = access_token.token
|
||||
clean_up_passwords(resource)
|
||||
render_for_oauth
|
||||
end
|
||||
end
|
||||
|
||||
# Handles oauth flash messages by adding a cascade. The default messages
|
||||
# are always in the controller namespace:
|
||||
#
|
||||
# en:
|
||||
# devise:
|
||||
# oauth_callbacks:
|
||||
# success: 'Successfully authorized from %{kind} account.'
|
||||
# failure: 'Could not authorize you from %{kind} because "%{reason}".'
|
||||
# skipped: 'Skipped Oauth authorization for %{kind}.'
|
||||
#
|
||||
# But they can also be nested according to the oauth provider:
|
||||
#
|
||||
# en:
|
||||
# devise:
|
||||
# oauth_callbacks:
|
||||
# github:
|
||||
# success: 'Hello coder! Welcome to our app!'
|
||||
#
|
||||
# And finally by Devise scope:
|
||||
#
|
||||
# en:
|
||||
# devise:
|
||||
# oauth_callbacks:
|
||||
# admin:
|
||||
# github:
|
||||
# success: 'Hello coder with high permissions! Can I get a raise?'
|
||||
#
|
||||
def set_oauth_flash_message(key, type, options={})
|
||||
options[:kind] = oauth_callback.to_s.titleize
|
||||
options[:default] = type.to_sym
|
||||
set_flash_message(key, "#{oauth_callback}.#{type}", options)
|
||||
end
|
||||
|
||||
# Choose which template to render when a not persisted resource is
|
||||
# returned in the find_for_x_oauth. By default, it renders registrations/new.
|
||||
def render_for_oauth
|
||||
render_with_scope :new, devise_mapping.controllers[:registrations]
|
||||
end
|
||||
|
||||
# The default hook used by oauth to specify the redirect url for success.
|
||||
def after_oauth_success_path_for(resource)
|
||||
after_sign_in_path_for(resource)
|
||||
end
|
||||
|
||||
# The default hook used by oauth to specify the redirect url for failure.
|
||||
def after_oauth_failure_path_for(scope)
|
||||
new_session_path(scope)
|
||||
end
|
||||
|
||||
# Overwrite redirect_for_sign_in so it takes uses after_oauth_success_path_for.
|
||||
def redirect_for_sign_in(scope, resource) #:nodoc:
|
||||
redirect_to stored_location_for(scope) || after_oauth_success_path_for(resource)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,29 +0,0 @@
|
|||
module Devise
|
||||
module Oauth
|
||||
module TestHelpers #:nodoc:
|
||||
def self.short_circuit_authorizers!
|
||||
module_eval <<-ALIASES, __FILE__, __LINE__ + 1
|
||||
def oauth_authorize_url(scope, provider)
|
||||
oauth_callback_path(scope, provider, :code => "12345")
|
||||
end
|
||||
ALIASES
|
||||
|
||||
Devise.mappings.each_value do |m|
|
||||
next unless m.oauthable?
|
||||
|
||||
module_eval <<-ALIASES, __FILE__, __LINE__ + 1
|
||||
def #{m.name}_oauth_authorize_url(provider)
|
||||
#{m.name}_oauth_callback_path(provider, :code => "12345")
|
||||
end
|
||||
ALIASES
|
||||
end
|
||||
end
|
||||
|
||||
def self.unshort_circuit_authorizers!
|
||||
module_eval do
|
||||
instance_methods.each { |m| remove_method(m) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
module Devise
|
||||
module Oauth
|
||||
module UrlHelpers
|
||||
def self.define_helpers(mapping)
|
||||
return unless mapping.oauthable?
|
||||
|
||||
class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
|
||||
def #{mapping.name}_oauth_authorize_url(provider, options={})
|
||||
if config = Devise.oauth_configs[provider.to_sym]
|
||||
options[:redirect_uri] ||= #{mapping.name}_oauth_callback_url(provider.to_s)
|
||||
config.authorize_url(options)
|
||||
else
|
||||
raise ArgumentError, "Could not find oauth provider \#{provider.inspect}"
|
||||
end
|
||||
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
|
||||
|
||||
def oauth_callback_url(resource_or_scope, *args)
|
||||
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
||||
send("#{scope}_oauth_callback_url", *args)
|
||||
end
|
||||
|
||||
def oauth_callback_path(resource_or_scope, *args)
|
||||
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
||||
send("#{scope}_oauth_callback_path", *args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -26,33 +26,8 @@ module Devise
|
|||
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
|
||||
delegate :short_circuit_authorizers!, :unshort_circuit_authorizers!,
|
||||
:test_mode!, :stub!, :reset_stubs!, :to => "Devise::OmniAuth::TestHelpers"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,6 +1,32 @@
|
|||
module Devise
|
||||
module OmniAuth
|
||||
module TestHelpers #:nodoc:
|
||||
module TestHelpers
|
||||
def self.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 self.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 self.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
|
||||
|
||||
def self.short_circuit_authorizers!
|
||||
module_eval <<-ALIASES, __FILE__, __LINE__ + 1
|
||||
def omniauth_authorize_path(*args)
|
||||
|
|
|
@ -28,12 +28,6 @@ module Devise
|
|||
Devise.include_helpers(Devise::Controllers)
|
||||
end
|
||||
|
||||
initializer "devise.oauth_url_helpers" do
|
||||
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|
|
||||
|
|
|
@ -238,11 +238,6 @@ module ActionDispatch::Routing
|
|||
end
|
||||
end
|
||||
|
||||
def devise_oauth_callback(mapping, controllers) #:nodoc:
|
||||
get "/oauth/:action/callback", :action => Regexp.union(mapping.to.oauth_providers.map(&:to_s)),
|
||||
:to => controllers[:oauth_callbacks], :as => :oauth_callback
|
||||
end
|
||||
|
||||
def devise_omniauth_callback(mapping, controllers) #:nodoc:
|
||||
path_prefix = "#{mapping.fullpath}/auth"
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ module Devise
|
|||
def model_contents
|
||||
<<-CONTENT
|
||||
# Include default devise modules. Others available are:
|
||||
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :oauthable
|
||||
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
|
||||
devise :database_authenticatable, :registerable,
|
||||
:recoverable, :rememberable, :trackable, :validatable
|
||||
|
||||
|
|
|
@ -148,14 +148,10 @@ Devise.setup do |config|
|
|||
# The default HTTP method used to sign out a resource. Default is :get.
|
||||
# config.sign_out_via = :get
|
||||
|
||||
# ==> OAuth2
|
||||
# Add a new OAuth2 provider. Check the README for more information on setting
|
||||
# up on your models and hooks. By default this is not set.
|
||||
# config.oauth :github, 'APP_ID', 'APP_SECRET',
|
||||
# :site => 'https://github.com/',
|
||||
# :authorize_path => '/login/oauth/authorize',
|
||||
# :access_token_path => '/login/oauth/access_token',
|
||||
# :scope => %w(user public_repo)
|
||||
# ==> OmniAuth
|
||||
# Add a new OmniAuth provider. Check the wiki for more information on setting
|
||||
# up on your models and hooks.
|
||||
# config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo'
|
||||
|
||||
# ==> Warden configuration
|
||||
# If you want to use other strategies, that are not supported by Devise, or
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
require 'test_helper'
|
||||
|
||||
class OauthConfigTest < ActiveSupport::TestCase
|
||||
class OmniAuthConfigTest < ActiveSupport::TestCase
|
||||
ACCESS_TOKEN = {
|
||||
:access_token => "plataformatec"
|
||||
}
|
||||
|
||||
setup { @config = Devise.oauth_configs[:facebook] }
|
||||
teardown { Devise::Oauth.reset_stubs! }
|
||||
setup { @config = Devise.omniauth_configs[:facebook] }
|
||||
teardown { Devise::Omniauth.reset_stubs! }
|
||||
|
||||
test "stored OAuth2::Client" do
|
||||
assert_kind_of OAuth2::Client, @config.client
|
|
@ -1,6 +1,6 @@
|
|||
require 'test_helper'
|
||||
|
||||
class OauthRoutesTest < ActionController::TestCase
|
||||
class OmniAuthRoutesTest < ActionController::TestCase
|
||||
tests ApplicationController
|
||||
|
||||
def assert_path_and_url(action, provider)
|
||||
|
@ -17,31 +17,31 @@ class OauthRoutesTest < ActionController::TestCase
|
|||
@controller.send("user_#{action}", provider, :param => 123)
|
||||
end
|
||||
|
||||
test 'should alias oauth_callback to mapped user auth_callback' do
|
||||
assert_path_and_url :oauth_callback_path, :github
|
||||
assert_path_and_url :oauth_callback_url, :github
|
||||
assert_path_and_url :oauth_callback_path, :facebook
|
||||
assert_path_and_url :oauth_callback_url, :facebook
|
||||
test 'should alias omniauth_callback to mapped user auth_callback' do
|
||||
assert_path_and_url :omniauth_callback_path, :github
|
||||
assert_path_and_url :omniauth_callback_url, :github
|
||||
assert_path_and_url :omniauth_callback_path, :facebook
|
||||
assert_path_and_url :omniauth_callback_url, :facebook
|
||||
end
|
||||
|
||||
test 'should alias oauth_authorize to mapped user auth_authorize' do
|
||||
assert_path_and_url :oauth_authorize_url, :github
|
||||
assert_path_and_url :oauth_authorize_url, :facebook
|
||||
test 'should alias omniauth_authorize to mapped user auth_authorize' do
|
||||
assert_path_and_url :omniauth_authorize_url, :github
|
||||
assert_path_and_url :omniauth_authorize_url, :facebook
|
||||
end
|
||||
|
||||
test 'should adds scope, provider and redirect_uri to authorize urls' do
|
||||
url = @controller.oauth_authorize_url(:user, :github)
|
||||
assert_match "https://github.com/login/oauth/authorize?", url
|
||||
url = @controller.omniauth_authorize_url(:user, :github)
|
||||
assert_match "https://github.com/login/omniauth/authorize?", url
|
||||
assert_match "scope=user%2Cpublic_repo", url
|
||||
assert_match "client_id=APP_ID", url
|
||||
assert_match "type=web_server", url
|
||||
assert_match "redirect_uri=http%3A%2F%2Ftest.host%2Fusers%2Foauth%2Fgithub%2Fcallback", url
|
||||
assert_match "redirect_uri=http%3A%2F%2Ftest.host%2Fusers%2Fomniauth%2Fgithub%2Fcallback", url
|
||||
|
||||
url = @controller.oauth_authorize_url(:user, :facebook)
|
||||
assert_match "https://graph.facebook.com/oauth/authorize?", url
|
||||
url = @controller.omniauth_authorize_url(:user, :facebook)
|
||||
assert_match "https://graph.facebook.com/omniauth/authorize?", url
|
||||
assert_match "scope=email%2Coffline_access", url
|
||||
assert_match "client_id=APP_ID", url
|
||||
assert_match "type=web_server", url
|
||||
assert_match "redirect_uri=http%3A%2F%2Ftest.host%2Fusers%2Foauth%2Ffacebook%2Fcallback", url
|
||||
assert_match "redirect_uri=http%3A%2F%2Ftest.host%2Fusers%2Fomniauth%2Ffacebook%2Fcallback", url
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
def facebook
|
||||
data = env["omniauth.auth"]
|
||||
session["devise.facebook_data"] = data
|
||||
render :json => data
|
||||
end
|
||||
end
|
|
@ -148,18 +148,16 @@ Devise.setup do |config|
|
|||
# The default HTTP method used to sign out a resource. Default is :get.
|
||||
# config.sign_out_via = :get
|
||||
|
||||
# ==> OAuth2
|
||||
# Add a new OAuth2 provider. Check the README for more information on setting
|
||||
# up on your models and hooks. By default this is not set.
|
||||
config.oauth :github, 'APP_ID', 'APP_SECRET',
|
||||
# ==> OmniAuth
|
||||
config.omniauth :github, 'APP_ID', 'APP_SECRET',
|
||||
:site => 'https://github.com/',
|
||||
:authorize_path => '/login/oauth/authorize',
|
||||
:access_token_path => '/login/oauth/access_token',
|
||||
:scope => 'user,public_repo'
|
||||
|
||||
config.oauth :facebook, 'APP_ID', 'APP_SECRET',
|
||||
config.omniauth :facebook, 'APP_ID', 'APP_SECRET',
|
||||
:site => 'https://graph.facebook.com/',
|
||||
:scope => %w(email offline_access)
|
||||
:scope => 'email,offline_access'
|
||||
|
||||
# ==> Warden configuration
|
||||
# If you want to use other strategies, that are not supported by Devise, or
|
||||
|
|
|
@ -8,7 +8,7 @@ Rails.application.routes.draw do
|
|||
resources :admins, :only => [:index]
|
||||
|
||||
# Users scope
|
||||
devise_for :users do
|
||||
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" } do
|
||||
match "/devise_for/sign_in", :to => "devise/sessions#new"
|
||||
end
|
||||
|
||||
|
|
|
@ -4,45 +4,20 @@ module SharedUser
|
|||
included do
|
||||
devise :database_authenticatable, :confirmable, :lockable, :recoverable,
|
||||
:registerable, :rememberable, :timeoutable, :token_authenticatable,
|
||||
:trackable, :validatable, :oauthable
|
||||
:trackable, :validatable, :omniauthable
|
||||
|
||||
# They need to be included after Devise is called.
|
||||
extend ExtendMethods
|
||||
end
|
||||
|
||||
module ExtendMethods
|
||||
def find_for_facebook_oauth(access_token, signed_in_resource=nil)
|
||||
data = ActiveSupport::JSON.decode(access_token.get('/me'))
|
||||
user = signed_in_resource || User.find_by_email(data["email"]) || User.new
|
||||
user.update_with_facebook_oauth(access_token, data)
|
||||
user.save
|
||||
user
|
||||
end
|
||||
|
||||
def new_with_session(params, session)
|
||||
super.tap do |user|
|
||||
if session[:user_facebook_oauth_token]
|
||||
access_token = oauth_access_token(:facebook, session[:user_facebook_oauth_token])
|
||||
user.update_with_facebook_oauth(access_token)
|
||||
if data = session["devise.facebook_data"]
|
||||
user.username = data["nickname"]
|
||||
user.email = data["email"]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_with_facebook_oauth(access_token, data=nil)
|
||||
data ||= ActiveSupport::JSON.decode(access_token.get('/me'))
|
||||
|
||||
self.username = data["username"] unless username.present?
|
||||
self.email = data["email"] unless email.present?
|
||||
|
||||
self.confirmed_at ||= Time.now
|
||||
self.facebook_token = access_token.token
|
||||
|
||||
unless encrypted_password.present?
|
||||
self.password = Devise.friendly_token[0, 10]
|
||||
self.password_confirmation = nil
|
||||
end
|
||||
|
||||
yield self if block_given?
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue