Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save richardpeng/765257b0ce581d163012 to your computer and use it in GitHub Desktop.
Save richardpeng/765257b0ce581d163012 to your computer and use it in GitHub Desktop.
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
protected
def current_user
@current_user ||= session[:user_id] and User.find(session[:user_id]['$oid'])
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
class Authentication
include Mongoid::Document
include Mongoid::Timestamps
field :user_id, type: String
field :provider, type: String
field :uid, type: String
belongs_to :user
def self.find_with_omniauth(auth)
find_by(provider: auth['provider'], uid: 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
class Identity
include Mongoid::Document
include OmniAuth::Identity::Models::Mongoid
field :email, type: String
field :name, type: String
field :password_digest, type: String
belongs_to :user
end
Rails.application.config.middleware.use OmniAuth::Builder do
provider :identity, fields: [:email, :name], 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)
# 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
# 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
= form_tag '/auth/identity/callback' do |f|
h1 Create an Account
= text_field_tag :auth_key
= password_field_tag :password
= submit_tag
class User
include Mongoid::Document
include Mongoid::Timestamps
has_many :kytes
field :name, type: String
field :email, type: String
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'], email: auth['info']['email'])
# 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
= form_tag '/auth/identity/register' do |f|
h1 Create an Account
= text_field_tag :name
= text_field_tag :email
= password_field_tag :password
= password_field_tag :password_confirmation
= submit_tag
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment