Skip to content

Instantly share code, notes, and snippets.

@travisp
Created March 9, 2012 15:56
Show Gist options
  • Save travisp/2007222 to your computer and use it in GitHub Desktop.
Save travisp/2007222 to your computer and use it in GitHub Desktop.
devise_invitable with omniauthable
class InvitationsController < Devise::InvitationsController
# GET /resource/invitation/accept?invitation_token=abcdef
def edit
if params[:invitation_token] && self.resource = resource_class.to_adapter.find_first( :invitation_token => params[:invitation_token] )
session[:invitation_token] = params[:invitation_token]
render :edit
else
set_flash_message(:alert, :invitation_token_invalid)
redirect_to after_sign_out_path_for(resource_name)
end
end
# PUT /resource/invitation
def update
self.resource = resource_class.accept_invitation!(params[resource_name])
if resource.errors.empty?
session[:invitation_token] = nil
set_flash_message :notice, :updated
sign_in(resource_name, resource)
respond_with resource, :location => after_accept_path_for(resource)
else
respond_with_navigational(resource){ render :edit }
end
end
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook/twitter/whatever
auth = request.env["omniauth.auth"]
identity = #find user by omniauth provider and uid
if identity
#do all regular sign in stuff here
else
#no identity found
token = session[:invitation_token]
if token && user = User.where(:invitation_token => token).first
#some app specific code
else
user = User.new
end
user.apply_omniauth(auth)
if user.valid?
if user.invited?
user.accept_invitation!
else
user.save
end
sign_in(:user, user)
redirect_to user_url(user)
else
#app specific code
end
end
session[:invitation_token] = nil
end
devise_for :users,
:controllers => {
:invitations => 'invitations',
:omniauth_callbacks => 'users/omniauth_callbacks'
}
@a5sk4s
Copy link

a5sk4s commented Feb 7, 2014

Needed to use User.find_by_invitation_token(invitation_token, true) instead of User.where(:invitation_token => token).first, probably due to security issues around tokens that were fixed in newer versions of devise - worked great otherwise as a guidance. Thanks.

@nunosilva800
Copy link

find_by_invitation_token is an method from devise invitable, that takes in the raw_invitation_token and calculates the real one (stored on the DB). It's not a rails find_by_* method... just a sad coincidence in naming.

@DavidLangva
Copy link

I had to change user.invited? to user.valid_invitation? since .invited? method doesn't appear to be included any more. (could also use invited_to_sign_up?, but figured I might as well check for valid invite at same time.

Had to follow what @a5sk4s said in the invitations_controller and the omniauth_callbacks_controller for exactly the reason @Onumis mentioned.

@FrankHald
Copy link

Since the only new objective in the update function in invitations_controller.rb is to remove the session invitation token, aren't we just able to define the function like this:

def update
    super
    session[:invitation_token] = nil if resource.errors.empty?
end

Or am I missing something?

@phacks
Copy link

phacks commented May 13, 2020

For recent (>= 2.0) versions of devise_invitable, here’s what’s worked for me:

def edit
      if params[:invitation_token] &&
           User.find_by_invitation_token(params[:invitation_token], true)
        session[:invitation_token] = params[:invitation_token]
        super
      else
        set_flash_message(:alert, :invitation_token_invalid)
        redirect_to after_sign_out_path_for(resource_name)
      end
    end

    def update
      super
      session[:invitation_token] = nil if resource.errors.empty?
    end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment