1
0
Fork 0
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:
José Valim 2010-10-14 23:46:10 +02:00
parent 5d4e4fbb88
commit 2f360bf201
26 changed files with 91 additions and 528 deletions

View file

@ -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'

View file

@ -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)

View file

@ -1,4 +0,0 @@
class Devise::OauthCallbacksController < ApplicationController
include Devise::Controllers::InternalHelpers
include Devise::Oauth::InternalHelpers
end

View file

@ -0,0 +1,6 @@
class Devise::OmniauthCallbacksController < ApplicationController
include Devise::Controllers::InternalHelpers
def failure
end
end

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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|

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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