Pastebin is 300% more awesome when you are logged in. Sign Up, it's FREE!
Guest

devise, omniauth-facebook and mongoid

By: joemanfoo on Oct 8th, 2012  |  syntax: Rails  |  size: 4.26 KB  |  hits: 182  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. users.rb
  2. devise :database_authenticatable, :registerable,
  3.          :recoverable, :rememberable, :trackable, :validatable, :omniauthable
  4.  
  5. #...field setups for devise...
  6.   #
  7.   ## Provide foundation to support multiple omniauth providers
  8.   #
  9.   embeds_many :authentications
  10.  
  11.  
  12.   field :name,            :type => String
  13.   field :provider,        :type => String  # TODO: This is a complete hack, better way?
  14.  
  15.   validates_uniqueness_of :email
  16.   attr_accessible :name, :email, :password, :password_confirmation, :remember_me
  17.  
  18.   index( { email: 1},                         { background: true, unique: true } )
  19.   index( { "authentications.provider" => 1 }, { background: true } )
  20.   index( { "authentications.uid"      => 1 }, { background: true } )
  21.  
  22.   def self.new_with_session(params, session)
  23.     #
  24.     ## When omniauth is generating the user data this method is requested
  25.     #
  26.     if session["devise.user_attributes"]
  27.       auth = session["devise.user_attributes"]
  28.       new do |user|
  29.         user.name    = auth['info']['name'] unless auth['info']['name'].blank?
  30.         user.name  ||= auth['info']['nickname'] unless auth['info']['nickname'].blank?
  31.         user.name  ||=auth['info']['first_name'] + ' ' + auth['info']['last_name'] unless auth['info']['first_name'].blank? || auth['info']['last_name'].blank?
  32.  
  33.         user.email   = auth['info']['email'] unless auth['info']['email'].blank?
  34.        
  35.         user.provider = auth['provider']
  36.        
  37.         #
  38.         ## This password stuff is a complete hack
  39.         #
  40.         user.password, user.password_confirmation = auth['credentials']['token']
  41.  
  42.         user.valid?
  43.       end
  44.     else
  45.       #
  46.       ## We don't have a omniauth hash, so default to normal devise registration
  47.       #
  48.       super
  49.     end
  50.   end
  51.  
  52.   def password_required?
  53.     super && provider.blank?
  54.   end
  55.  
  56.   def update_with_password(params, *options)
  57.     if encrypted_password.blank?
  58.       update_attributes(params, *options)
  59.     else
  60.       super
  61.     end
  62.   end
  63.  
  64. Authentication.rb
  65. class Authentication
  66.   include Mongoid::Document
  67.  
  68.   field :provider,    :type => String, :default => ''
  69.   field :uid,             :type => String, :default => ''
  70.  
  71.   embedded_in :user
  72.   #
  73.   ## TODO:  At the least, we'll want to add in data hooks for FB
  74.   ##       for posting to user's wall, events, etc.
  75.   #
  76. end  
  77.  
  78. authentication_controller.rb
  79. class AuthenticationController < Devise::OmniauthCallbacksController
  80.        
  81.   def all
  82.     auth = request.env['omniauth.auth']
  83.     authentication = User.first.authentications.where(:provider => auth['provider'], :uid => auth['uid']).first
  84.       if current_user
  85.         #
  86.         ## we've got a logged in user, lets see if they have already linked their account
  87.         #
  88.         if current_user.authentications.where(:provider => auth['provider'], :uid => auth['uid'])
  89.           flash.notice = "#{auth['provider']} is already linked to your account."
  90.           redirect_to '/'
  91.         else
  92.           current_user.authentications.create!(:provider => auth['provider'], :uid => auth['uid'])
  93.           flash.notice = "Sucessfully linked your #{auth['provider']} to your account!"
  94.           sign_in_and_redirect current_user #TODO: think about redirection
  95.         end
  96.  
  97.       elsif authentication
  98.         #
  99.         ## We don't have a currently logged in user but we do have this provider and uid
  100.         #
  101.         flash.notice = "Signed in via your #{auth['provider']} account!"
  102.         sign_in_and_redirect(:user, authentication.user)
  103.  
  104.       elsif user = create_new_omniauth_user(auth)
  105.         user.authentications.create!(:provider => auth['provider'], :uid => auth['uid'])
  106.         flash.notice = "Sucessfully created account!"
  107.         sign_in_and_redirect user #TODO: think about redirection
  108.  
  109.       else
  110.         session["devise.user_attributes"] = auth
  111.         redirect_to new_user_registration_url
  112.       end
  113.     end
  114.    
  115.     alias_method :facebook, :all
  116.  
  117.  
  118. #  def destroy
  119. #       @authentication = current_user.authentications.find(params[:id])
  120. #       @authentication.destroy
  121. #       flash.notice = "Successfully destroyed authenication!"
  122. #       redirect_to root
  123. #  end
  124.  
  125.   def create_new_omniauth_user(auth)
  126.     user = User.new_with_session(auth, session)
  127.     if user.save
  128.       user
  129.     else
  130.       nil
  131.     end
  132.   end
  133. end
  134.  
  135. In routes.rb I changed the controllers: {omniauth_callbacks: "omnitauth_callback"} to
  136. controllers: {omniauth_callbacks: "authentication"}