Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save epoch/8257373 to your computer and use it in GitHub Desktop.
Save epoch/8257373 to your computer and use it in GitHub Desktop.
class ApplicationController < ActionController::Base
protect_from_forgery
protected
def current_user
@current_user ||= User.find_by_id(session[:user_id])
end
def signed_in?
!!current_user
end
helper_method :current_user, :signed_in?
def current_user=(user)
@current_user = user
session[:user_id] = user.nil? ? user : user.id
end
end
# == Schema Information
#
# Table name: authentications
#
# id :integer not null, primary key
# user_id :integer
# provider :string(255)
# uid :string(255)
# created_at :datetime not null
# updated_at :datetime not null
#
class Authentication < ActiveRecord::Base
attr_accessible :provider, :uid, :user_id
belongs_to :user
def self.find_with_omniauth(auth)
find_by_provider_and_uid(auth['provider'], auth['uid'])
end
def self.create_with_omniauth(auth)
create(uid: auth['uid'], provider: auth['provider']) # and other data you might want from the auth hash
end
end
<%= simple_form_for @user, :url => '/auth/identity/register' do |f| %>
<%= @user.inspect %>
<h1>Create an Account</h1>
<%# specify :input_html to avoid params nesting %>
<%= f.input :name, :input_html => {:name => 'name'} %>
<%= f.input :email, :input_html => {:name => 'email'} %>
<%= f.input :password, :as => 'password', :input_html => {:name => 'password'} %>
<%= f.input :password_confirmation, :label => "Confirm Password", :as => 'password', :input_html => {:name => 'password_confirmation'} %>
<button type='submit'>Sign Up</button>
<% end %>
Rails.application.config.middleware.use OmniAuth::Builder do
provider :identity, fields: [:email, :name], model: User, on_failed_registration: lambda { |env|
UsersController.action(:new).call(env)
}
provider :abc
provider :def
end
AppName::Application.routes.draw do
match '/auth/:provider/callback', to: 'sessions#create' #omniauth route
match '/signup', to: 'users#new'
match '/login', to: 'sessions#new'
match '/logout', to: 'sessions#destroy'
resources :users #needed by omniauth-identity
end
class SessionsController < ApplicationController
def new
# Stuff to display on the login-page.
end
def create
auth = request.env['omniauth.auth']
# Find an authentication or create an authentication
@authentication = Authentication.find_with_omniauth(auth)
if @authentication.nil?
# If no authentication was found, create a brand new one here
@authentication = Authentication.create_with_omniauth(auth)
end
if signed_in?
if @authentication.user == current_user
# User is signed in so they are trying to link an authentication with their
# account. But we found the authentication and the user associated with it
# is the current user. So the authentication is already associated with
# this user. So let's display an error message.
redirect_to root_path, notice: "You have already linked this account"
else
# The authentication is not associated with the current_user so lets
# associate the authentication
@authentication.user = current_user
@authentication.save
redirect_to root_path, notice: "Account successfully authenticated"
end
else # no user is signed_in
if @authentication.user.present?
# The authentication we found had a user associated with it so let's
# just log them in here
self.current_user = @authentication.user
redirect_to root_path, notice: "Signed in!"
else
# The authentication has no user assigned and there is no user signed in
# Our decision here is to create a new account for the user
# But your app may do something different (eg. ask the user
# if he already signed up with some other service)
if @authentication.provider == 'identity'
u = User.find(@authentication.uid)
# If the provider is identity, then it means we already created a user
# So we just load it up
else
# otherwise we have to create a user with the auth hash
u = User.create_with_omniauth(auth)
# NOTE: we will handle the different types of data we get back
# from providers at the model level in create_with_omniauth
end
# We can now link the authentication with the user and log him in
u.authentications << @authentication
self.current_user = u
redirect_to root_path, notice: "Welcome to The app!"
end
end
end
def destroy
self.current_user = nil
redirect_to root_path, notice: "Signed out!"
end
def failure
redirect_to root_path, alert: "Authentication failed, please try again."
end
end
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# name :string(255)
# email :string(255)
# created_at :datetime not null
# updated_at :datetime not null
# password_digest :string(255)
class User < OmniAuth::Identity::Models::ActiveRecord
attr_accessible :email, :name, :password, :password_confirmation
has_many :authentications
email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, :presence => true,
:format => { :with => email_regex },
:uniqueness => { :case_sensitive => false }
def self.create_with_omniauth(auth)
# you should handle here different providers data
# eg. case auth['provider'] ..
create(name: auth['info']['name'])
# IMPORTANT: when you're creating a user from a strategy that
# is not identity, you need to set a password, otherwise it will fail
# I use: user.password = rand(36**10).to_s(36)
end
end
class UsersController < ApplicationController
def new
@user = env['omniauth.identity'] ||= User.new
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment