Skip to content

Instantly share code, notes, and snippets.

@ctrochalakis
Created June 11, 2010 12:17
Show Gist options
  • Save ctrochalakis/434418 to your computer and use it in GitHub Desktop.
Save ctrochalakis/434418 to your computer and use it in GitHub Desktop.
facebook, google, twitter, yahoo warden strategies
require 'dalton/strategies/skroutz'
require 'dalton/strategies/facebook'
require 'dalton/strategies/openid' # yahoo, #google
require 'dalton/strategies/twitter'
# Setup OpenId file storage, don't change the storage engine!
require 'openid/store/filesystem'
Rails.configuration.middleware.use(Rack::OpenID,
OpenID::Store::Filesystem.new(Rails.root + 'tmp/openid'))
# Register Authntication middleware
Rails.configuration.middleware.use RailsWarden::Manager do |manager|
manager.default_strategies :skroutz, :facebook, :openid, :twitter
manager.failure_app = UsersController
end
Warden::Manager.serialize_into_session { |user| user.id }
Warden::Manager.serialize_from_session { |id| User.find_by_id(id) }
# Runs *every time* a user logins
#
#Warden::Manager.after_set_user do |user, auth, opts|
#end
# Runs every time a user authenticates, start of session
#
Warden::Manager.after_authentication do |user,auth,opts|
session, params, cookies = auth.session, auth.params, auth.cookies
roles = user.roles.collect{|c| c.code}
cookies[:login] = 'y'
# Check Permissions
if roles.include? "superban"
auth.logout
throw :warden, :message => "You are banned!", :scope => opts[:scope]
end
end
Warden::Manager.before_logout do |user,auth,opts|
auth.cookies.delete :login
end
require 'oauth2'
Warden::Strategies.add(:facebook) do
Key = 'my-key'
Secret = 'my-secret'
def valid?
params[:facebook] or params[:code] or params[:error_reason]
end
def client
OAuth2::Client.new(Key, Secret, :site => 'https://graph.facebook.com')
end
def redirect_to_facebook
redirect! client.web_server.authorize_url(:redirect_uri => redirect_uri,
:scope => 'email')
end
def authenticate!
# First Time
return redirect_to_facebook if params[:facebook]
# What a jackass
return fail!('You have not accepted to assign your acount with example.com') if params[:error_reason]
access_token = client.web_server.get_access_token(params[:code], :redirect_uri => redirect_uri)
fb_user = JSON.parse(access_token.get('/me', :fields =>'id,link,email,picture,gender'))
id = "fb:#{fb_user['id']}"
unless u = User.find_by_identity_url(id)
uname = fb_user['link'].split('/').last
uname = fb_user['email'].split('@').first if uname =~ /^profile/
# Create the user
User.create :username => uname
end
success! u
end
def redirect_uri
uri = URI.parse(request.url)
uri.path = '/users/facebook'
uri.query = nil
uri.to_s
end
end
Warden::Strategies.add(:openid) do
def valid?
params[:openid_identifier] or env[Rack::OpenID::RESPONSE]
end
def authenticate!
if response = env[Rack::OpenID::RESPONSE]
case response.status
when :success
if user = User.find_by_identity_url(response.identity_url)
success!(user)
else
# Create the user
create_user_from_response response
success!(u)
end
else
fail! "You couldn't be authenticated!"
end
elsif identifier = params['openid_identifier']
if identifier.empty?
fail!('OpenID identifier is required')
else
custom!([401, {'WWW-Authenticate' =>
Rack::OpenID.build_header(:identifier => identifier,
:return_to => callback_url,
:required => ["http://axschema.org/contact/email"])}, ''])
end
end
end
def callback_url
uri = URI.parse(request.url)
uri.path = '/users/openid'
uri.to_s
end
def create_user_from_response(response)
ax = OpenID::AX::FetchResponse.from_success_response(response)
email = ax ? ax["http://axschema.org/contact/email"].first : sreg['email']
username = email.split(/@/).flatten.first
User.create :username => :username, :email => email, :identity_url => response.identity_url
end
end
Warden::Strategies.add(:skroutz) do
def valid?
params[:password] or params[:username]
end
def authenticate!
u = User.authenticate(params[:username], params[:password])
u.nil? ? fail!("Wrong username or password") : success!(u)
end
end
Warden::Strategies.add(:twitter) do
def valid?
params[:twitter] or params[:oauth_token]
end
def authenticate!
key = 'my-key'
secret = 'my-secret'
consumer = OAuth::Consumer.new(key, secret, {:site=>"https://twitter.com"})
if params[:oauth_token].blank?
request_token = consumer.get_request_token :oauth_callback => callback_url
session[:twitter] = {:token => request_token.token, :secret => request_token.secret}
authenticate_url = request_token.authorize_url.gsub(/authorize/, 'authenticate')
redirect!(authenticate_url)
else
request_token = OAuth::RequestToken.new(consumer, session[:twitter][:token], session[:twitter][:secret])
#now we need to get an access token
access_token = request_token.get_access_token(:oauth_verifier => params[:oauth_verifier])
identifier = (access_token.params["oauth_token"] + access_token.params["oauth_token_secret"]).to_md5
if u = User.find_by_identity_url(identifier)
success!(u)
else
username = access_token.params["screen_name"]
# Create the user
User.create :username => username, :identity_url => identifier
success!(u)
end
end
end
def callback_url
uri = URI.parse(request.url)
uri.path = '/users/twitter'
uri.to_s
end
end
class UsersController < ApplicationController
# facebook callback
def facebook
warden.authenticate!(:facebook)
return login!
end
# Twitter callback
def twitter
warden.authenticate!(:twitter)
return login!
end
# openid callback (yahoo, google)
def openid
warden.authenticate!(:openid)
return login!
end
def login
case request.method
when :post
warden.authenticate!
redirect_to '/'
when :get
render(:action => "login")
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment