#645 Enable account creation or authorisation from a facebook signin (and should work for others with minimal extra work)

This commit is contained in:
Daniel O'Connor
2015-08-21 13:22:49 +09:30
parent 89b6c47bfb
commit 34b4d30014
3 changed files with 92 additions and 2 deletions

View File

@@ -0,0 +1,90 @@
#
# Handle signup or signin
# from various oauth providers
#
# Heavily overlaps with Authentications controller
#
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
create
end
def failure
redirect_to request.env['omniauth.origin'] || "/", :flash => {:error => ":("}
end
private
#
# Inspects the omniauth information
# and determines if we have an existing member
# (to add authentication to)
# or if this is a new signup
#
# As a side affect, this method sets the @member_created
# variable
#
def member
@member_created = false
auth = request.env['omniauth.auth']
authentication = Authentication.where(provider: auth.provider, uid: auth.uid).first
if authentication && authentication.member.id.present?
member = authentication.member
end
Member.where(email: auth.info.email).first_or_create do |m|
m.email = auth.info.email
m.password = Devise.friendly_token[0,20]
m.tos_agreement = true
m.login_name = Devise.friendly_token[0,20] # TODO: A better login name to generate
# m.name = auth.info.name # assuming the user model has a name
# m.image = auth.info.image # assuming the user model has an image
@member_created = true
end
member
end
def create
auth = request.env['omniauth.auth']
@authentication = nil
if auth
name = ''
case auth['provider']
when 'twitter'
name = auth['info']['nickname']
when 'flickr', 'facebook'
name = auth['info']['name']
else
name = auth['info']['name']
end
@authentication = member.authentications
.create_with(
:name => name,
:token => auth['credentials']['token'],
:secret => auth['credentials']['secret'],
)
.find_or_create_by(
:provider => auth['provider'],
:uid => auth['uid'],
:name => name,
:member_id => member.id
)
unless @member_created
sign_in_and_redirect member, :event => :authentication #this will throw if @user is not activated
set_flash_message(:notice, :success, :kind => auth['provider']) if is_navigational_format?
else
session["devise.#{auth['provider']}_data"] = request.env["omniauth.auth"]
redirect_to new_member_registration_url
end
else
flash[:notice] = "Authentication failed."
redirect_to request.env['omniauth.origin'] || edit_member_registration_path
end
end
end

View File

@@ -231,5 +231,5 @@ Devise.setup do |config|
# When using omniauth, Devise cannot automatically set Omniauth path,
# so you need to do it manually. For the users scope, it would be:
# config.omniauth_path_prefix = "/my_engine/users/auth"
config.omniauth :facebook, ENV['GROWSTUFF_FACEBOOK_KEY'], ENV['GROWSTUFF_FACEBOOK_SECRET'], :scope => 'email', :display => 'popup'
config.omniauth :facebook, ENV['GROWSTUFF_FACEBOOK_KEY'], ENV['GROWSTUFF_FACEBOOK_SECRET'], :scope => 'email,read_stream', :display => 'page', :info_fields => 'nickname,email,name'
end

View File

@@ -4,7 +4,7 @@ Growstuff::Application.routes.draw do
resources :plant_parts
devise_for :members, :controllers => { :registrations => "registrations", :passwords => "passwords" }
devise_for :members, :controllers => { :registrations => "registrations", :passwords => "passwords", :omniauth_callbacks => "omniauth_callbacks" }
devise_scope :member do
get '/members/unsubscribe/:message' => 'members#unsubscribe', :as => 'unsubscribe_member'
end