Skip to content

Commit

Permalink
switch to OmniAuth
Browse files Browse the repository at this point in the history
The Rack endpoint-model of facebook-login and twitter-login libraries
had its flaws; namely heavy reliance on payloads persisted in session.

This refactoring also improves the general flow of authentication,
connecting accounts, updating social connections etc.
  • Loading branch information
mislav committed Feb 3, 2012
1 parent 93c9acb commit 1c76bad
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 176 deletions.
5 changes: 3 additions & 2 deletions Gemfile
Expand Up @@ -19,15 +19,16 @@ gem 'mingo', '>= 0.3.0' #, :path => '/Users/mislav/Projects/mingo'
gem 'mongo_ext', '>= 0.19.3', :require => nil gem 'mongo_ext', '>= 0.19.3', :require => nil
gem 'mongo-rails-instrumentation' gem 'mongo-rails-instrumentation'
gem 'bson_ext', '>= 1.1.1', :require => nil gem 'bson_ext', '>= 1.1.1', :require => nil
gem 'twitter-login', '~> 0.4.0', :require => 'twitter/login' #, :path => '/Users/mislav/Projects/twitter-login'
gem 'will_paginate', '~> 3.0' #, :path => '/Users/mislav/.coral/will_paginate-mislav' gem 'will_paginate', '~> 3.0' #, :path => '/Users/mislav/.coral/will_paginate-mislav'
gem 'facebook-login', '~> 0.3.0', :require => 'facebook/login' #, :path => '/Users/mislav/Projects/facebook-login'
gem 'escape_utils' gem 'escape_utils'
gem 'choices' #, :path => '/Users/mislav/Projects/choices' gem 'choices' #, :path => '/Users/mislav/Projects/choices'
gem 'never-forget' #, :path => '/Users/mislav/Projects/never-forget' gem 'never-forget' #, :path => '/Users/mislav/Projects/never-forget'
gem 'twin' #, :path => '/Users/mislav/Projects/twin' gem 'twin' #, :path => '/Users/mislav/Projects/twin'
gem 'rails-behaviors' gem 'rails-behaviors'


gem 'omniauth-twitter'
gem 'omniauth-facebook'

group :extras do group :extras do
gem 'nokogiri', '~> 1.4.1' gem 'nokogiri', '~> 1.4.1'
gem 'nibbler', '~> 1.3' #, :path => '/Users/mislav/Projects/nibbler' gem 'nibbler', '~> 1.3' #, :path => '/Users/mislav/Projects/nibbler'
Expand Down
35 changes: 19 additions & 16 deletions Gemfile.lock
Expand Up @@ -67,11 +67,6 @@ GEM
eventmachine (0.12.10) eventmachine (0.12.10)
execjs (1.3.0) execjs (1.3.0)
multi_json (~> 1.0) multi_json (~> 1.0)
facebook-login (0.3.0)
addressable (~> 2.1)
hashie (>= 0.2.0)
oauth2 (>= 0.0.6)
rack (~> 1.2)
faraday (0.8.0.rc2) faraday (0.8.0.rc2)
multipart-post (~> 1.1) multipart-post (~> 1.1)
faraday_middleware (0.8.4) faraday_middleware (0.8.4)
Expand All @@ -82,7 +77,7 @@ GEM
gem_plugin (0.2.3) gem_plugin (0.2.3)
gherkin (2.4.21) gherkin (2.4.21)
json (>= 1.4.6) json (>= 1.4.6)
hashie (1.1.0) hashie (1.2.0)
hike (1.2.1) hike (1.2.1)
i18n (0.6.0) i18n (0.6.0)
journey (1.0.1) journey (1.0.1)
Expand Down Expand Up @@ -116,9 +111,22 @@ GEM
nibbler (1.3.0) nibbler (1.3.0)
nokogiri (1.4.7) nokogiri (1.4.7)
oauth (0.4.5) oauth (0.4.5)
oauth2 (0.5.0) oauth2 (0.5.2)
faraday (>= 0.6.1, < 0.8) faraday (~> 0.7)
multi_json (~> 1.0.0) multi_json (~> 1.0)
omniauth (1.0.2)
hashie (~> 1.2)
rack
omniauth-facebook (1.2.0)
omniauth-oauth2 (~> 1.0.0)
omniauth-oauth (1.0.0)
oauth
omniauth (~> 1.0)
omniauth-oauth2 (1.0.0)
oauth2 (~> 0.5.0)
omniauth (~> 1.0)
omniauth-twitter (0.0.7)
omniauth-oauth (~> 1.0)
rack (1.4.1) rack (1.4.1)
rack-cache (1.1) rack-cache (1.1)
rack (>= 0.4) rack (>= 0.4)
Expand Down Expand Up @@ -193,10 +201,6 @@ GEM
tilt (1.3.3) tilt (1.3.3)
twin (0.1.3) twin (0.1.3)
activesupport (>= 2.3) activesupport (>= 2.3)
twitter-login (0.4.3)
hashie (>= 0.2.2)
oauth (~> 0.4.2)
yajl-ruby (>= 0.7.7)
tzinfo (0.3.29) tzinfo (0.3.29)
uglifier (1.2.2) uglifier (1.2.2)
execjs (>= 0.3.0) execjs (>= 0.3.0)
Expand All @@ -207,7 +211,6 @@ GEM
will_paginate (3.0.1) will_paginate (3.0.1)
xpath (0.1.4) xpath (0.1.4)
nokogiri (~> 1.3) nokogiri (~> 1.3)
yajl-ruby (0.8.3)


PLATFORMS PLATFORMS
ruby ruby
Expand All @@ -222,7 +225,6 @@ DEPENDENCIES
cucumber-rails cucumber-rails
dalli dalli
escape_utils escape_utils
facebook-login (~> 0.3.0)
faraday (~> 0.8.0.rc) faraday (~> 0.8.0.rc)
faraday_middleware faraday_middleware
launchy launchy
Expand All @@ -233,6 +235,8 @@ DEPENDENCIES
never-forget never-forget
nibbler (~> 1.3) nibbler (~> 1.3)
nokogiri (~> 1.4.1) nokogiri (~> 1.4.1)
omniauth-facebook
omniauth-twitter
rails-behaviors rails-behaviors
railties (~> 3.2) railties (~> 3.2)
rspec-rails (~> 2.8.0) rspec-rails (~> 2.8.0)
Expand All @@ -243,7 +247,6 @@ DEPENDENCIES
therubyracer-heroku (~> 0.8.1.pre3) therubyracer-heroku (~> 0.8.1.pre3)
thin thin
twin twin
twitter-login (~> 0.4.0)
tzinfo tzinfo
uglifier uglifier
webmock webmock
Expand Down
18 changes: 7 additions & 11 deletions app/controllers/application_controller.rb
@@ -1,7 +1,7 @@
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
protect_from_forgery protect_from_forgery


before_filter :login_from_token, :authentication_denied_notice before_filter :login_from_token


def self.admin_actions(options) def self.admin_actions(options)
before_filter :check_admin, options before_filter :check_admin, options
Expand All @@ -28,7 +28,12 @@ def current_user=(user)
nil nil
end end
end end


def login_path(provider)
"/auth/#{provider}"
end
helper_method :login_path

protected protected


def login_from_token def login_from_token
Expand All @@ -39,15 +44,6 @@ def login_from_token
end end
end end


def authentication_denied_notice
%w[twitter facebook].detect do |service|
if session[:"#{service}_error"] == 'user_denied'
session.delete(:"#{service}_error")
flash.now[:warning] = "You have refused to connect with #{service.titleize}"
end
end
end

def check_admin def check_admin
unless logged_in? and current_user.admin? unless logged_in? and current_user.admin?
head :forbidden head :forbidden
Expand Down
51 changes: 29 additions & 22 deletions app/controllers/sessions_controller.rb
@@ -1,51 +1,55 @@
class SessionsController < ApplicationController require 'omniauth/auth_hash'
require 'ostruct'


include Twitter::Login::Helpers class SessionsController < ApplicationController
include Facebook::Login::Helpers


skip_before_filter :login_from_token skip_before_filter :login_from_token


# for offline testing purposes only # for offline testing purposes only
def instant_login def instant_login
user = Rails.configuration.twitter.test_user user = Rails.configuration.twitter.test_user
session[:twitter_user] = user signup_user OmniAuth::AuthHash.new(provider: 'twitter',
signup_user uid: user.id,
redirect_to watched_path(current_user) info: { name: user.name, nickname: user.screen_name },
extra: { raw_info: user })

redirect_to watched_url(current_user)
end end


def connect def connect
session[:connecting_with] = params[:network] # facebook or twitter session[:connecting_with] = params[:network] # facebook or twitter
session[:following_count] = current_user.friends.count session[:following_count] = current_user.friends.count


redirect_to polymorphic_path([params[:network], 'login']) redirect_to login_path(params[:network])
end end


def finalize def finalize
signup_user signup_user request.env['omniauth.auth']


unless Movies.offline?
current_user.fetch_twitter_info(twitter_client) if twitter_user
current_user.fetch_facebook_info(facebook_client) if facebook_user
end

if network = session[:connecting_with] if network = session[:connecting_with]
new_friends = current_user.friends.count - session[:following_count] new_friends = current_user.friends.count - session[:following_count]
if new_friends.zero? if new_friends.zero?
message = "Successfully connected #{network.capitalize}" message = "Successfully connected #{network.capitalize}"
else else
message = "Successfully connected with #{new_friends} people from #{network.capitalize}" message = "Successfully connected with #{new_friends} people from #{network.capitalize}"
end end


session.delete(:connecting_with)
session.delete(:following_count)

redirect_to following_url, notice: message redirect_to following_url, notice: message
else else
redirect_to watched_url(current_user) redirect_to watched_url(current_user)
end end
end end


def logout def auth_failure
twitter_logout render 'shared/error', status: 500, locals: {
facebook_logout error: OpenStruct.new(message: params[:message])
}
end


def logout
if logged_in? and cookies[:login_token].present? if logged_in? and cookies[:login_token].present?
current_user.delete_login_token cookies[:login_token] current_user.delete_login_token cookies[:login_token]
cookies.delete :login_token cookies.delete :login_token
Expand All @@ -56,11 +60,14 @@ def logout
end end


private private

def signup_user def signup_user(auth)
if self.current_user = User.login_from_twitter_or_facebook(twitter_user, facebook_user) if self.current_user = User.login_from_provider(auth, current_user)
if cookies[:login_token].blank? or !current_user.has_login_token?(cookies[:login_token]) if cookies[:login_token].blank? or !current_user.has_login_token?(cookies[:login_token])
cookies.permanent[:login_token] = current_user.generate_login_token cookies.signed.permanent[:login_token] = {
value: current_user.generate_login_token,
httponly: true
}
end end
end end
end end
Expand Down
2 changes: 2 additions & 0 deletions app/models/user/friends.rb
Expand Up @@ -15,11 +15,13 @@ module User::Friends
# cast twitter ids to integers # cast twitter ids to integers
def twitter_friends=(ids) def twitter_friends=(ids)
super ids.map { |id| id.to_i } super ids.map { |id| id.to_i }
self['twitter_friends_updated_at'] = Time.now
end end


# cast facebook ids to strings # cast facebook ids to strings
def facebook_friends=(ids) def facebook_friends=(ids)
super ids.map { |id| id.to_s } super ids.map { |id| id.to_s }
self['facebook_friends_updated_at'] = Time.now
end end
end end


Expand Down

0 comments on commit 1c76bad

Please sign in to comment.