app/controllers/auth_controller.rb
# -*- encoding : utf-8 -*-
class AuthController < ApplicationController
skip_before_filter :login_required
def callback
provider = params[:provider]
begin
auth_hash = params[:auth] || symbolize_keys(request.env["omniauth.auth"])
AppLink.find_by_provider_and_app_user_id_and_user_id(provider, auth_hash[:uid], nil).try(:destroy)
load_profile(auth_hash, provider)
if logged_in?
if current_user.app_links.find_by_provider(provider)
flash[:notice] = t(:'oauth.already_linked_to_your_account')
elsif AppLink.find_by_provider_and_app_user_id(provider, auth_hash[:uid])
flash[:error] = t(:'oauth.already_taken_by_other_account')
else
current_user.link_to_app(provider, auth_hash[:uid], auth_hash[:credentials])
flash[:success] = t(:'oauth.account_linked')
end
return redirect_to(account_linked_accounts_path)
else
if oauth_login(provider, auth_hash[:uid])
flash[:success] = t(:'oauth.logged_in')
return redirect_to projects_path
else
if signups_enabled?
session[:profile] = @profile
app_link = AppLink.create!(:provider => provider,
:app_user_id => auth_hash[:uid],
:custom_attributes => auth_hash,
:access_token => auth_hash[:credentials] ? auth_hash[:credentials][:token] : nil,
:access_secret => auth_hash[:credentials] ? auth_hash[:credentials][:secret] : nil
)
session[:app_link] = app_link.id
if conflict?
return redirect_to login_path
else
return redirect_to signup_path
end
else
flash[:error] = t(:'users.new.no_public_signup')
return redirect_to login_path
end
end
end
rescue
render :text => %(<p>Authentification Error: #{params[:error]}:</p><p><a href="/auth/#{@provider}">Retry</a></p>)
end
end
def failure
flash[:error] = "Authentification Error: #{params[:message]}"
redirect_back_or_to login_path
end
private
# Authentificate with login
def oauth_login(provider, auth_hash_uid)
if app_link = AppLink.find(:first, :conditions => {:provider => provider, :app_user_id => auth_hash_uid})
!!self.current_user = app_link.user if app_link.user
end
end
# Loads user's OAuth profile in @profile
def load_profile(user, provider)
@profile = {}
@profile[:provider] = provider
@profile[:login] = user[:user_info][:nickname] if user[:user_info][:nickname]
@profile[:phone] = user[:user_info][:phone] if user[:user_info][:phone]
if user[:user_info][:first_name] and user[:user_info][:last_name]
@profile[:first_name] = user[:user_info][:first_name]
@profile[:last_name] = user[:user_info][:last_name]
else
@profile[:first_name] = user[:user_info][:name].try(:split).try(:first)
@profile[:last_name] = user[:user_info][:name].try(:split).try(:second)
end
# Extra
@profile[:email] = user[:extra][:user_hash][:email] if user[:extra][:user_hash][:email]
end
def conflict?
email = User.find_by_email(@profile[:email])
login = User.find_by_login(@profile[:login])
if email or login
session[:conflict] = {:email => (@profile[:email] if email), :login => (@profile[:login] if login)}
true
else
false
end
end
def symbolize_keys arg
case arg
when Array
arg.map { |elem| symbolize_keys elem }
when Hash
Hash[
arg.map { |key, value|
k = key.is_a?(String) ? key.to_sym : key
v = symbolize_keys value
[k,v]
}]
else
arg
end
end
end