Created
November 15, 2010 13:43
-
-
Save cousine/700365 to your computer and use it in GitHub Desktop.
Sing Sign-in Solutions in Rails using Authentasaurus: The consumer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Authentasaurus configuration | |
development: &non_production_settings | |
:hashing: "SHA2" # MD5 - SHA1 - SHA2 | |
:mail: | |
:email: &development_email "[email protected]" | |
:host: "http://localhost:3001/" | |
:modules: | |
:remote: | |
:user: | |
:site: "http://localhost:3000/application_name" | |
:session_element: "remote_sessions" | |
:sync: true | |
:sync_to: "user" | |
:recoverable: | |
:token_expires_after: 10 # days | |
:send_email: true | |
:mail_subject: "Reset your password on your-domain.com" | |
:mail_from: *development_email | |
:invitable: | |
:send_email: true | |
:mail_subject: "You've been invited to your-domain.com" | |
:mail_from: *development_email | |
:validatable: | |
:send_email: true | |
:mail_subject: "Validate your account on your-domain.com" | |
:mail_from: *development_email |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#### Rails 3 | |
authentasaurus_routes :authorization, :validation # Add authentasaurus routes | |
# For redirecting the user back to your application after the token is authenticated | |
# Token was invalid | |
match "/sessions/signin" => "sessions#callback", :as => "sessions_callback" | |
# Token is authenticated successfully and the provider returned the username and token | |
match "/sessions/signin/:username/:token" => "sessions#callback" | |
#### Rails 2.3.* | |
map.authentasaurus_routes :authorizable, :validatable # Add authentasaurus routes | |
# For redirecting the user back to your application after the token is authenticated | |
# Token was invalid | |
map.sessions_callback "/sessions/signin", :controller => :sessions, :action => :callback | |
# Token is authenticated successfully and the provider returned the username and token | |
map.connect "/sessions/signin/:username/:token", :controller => :sessions, :action => :callback |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Session | |
include Authentasaurus::Models::Session # include the default functionalities from Authentasaurus | |
attr_accessor :token | |
# Creates a new session object using the token | |
def save_token(*session_types) | |
return false if self.username.nil? || self.token.nil? | |
session_types = session_types.flatten | |
if session_types.empty? | |
session_types = [:user_sync] | |
end | |
ret = true | |
session_types.each do |type| | |
# Authenticate token using the user_sync object | |
@user = type.to_s.camelize.constantize.authenticate_token(self.username, self.token) | |
if @user.nil? | |
ret &= false | |
else | |
ret = true | |
break | |
end | |
end | |
ret | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SessionsController < ApplicationController | |
include Authentasaurus::SessionsController | |
before_filter :check_is_logged_in, :only => [:callback] | |
before_filter :authenticate_token, :only => [:new] | |
layout "login" | |
# Called after the provider has authenticated the saved token | |
# The provider responds to this url with a username and the token if the token is found and correct | |
# A session object is created from the input data and the data is authenticated with Session#save_remote | |
def callback | |
begin | |
@session = Session.new :username => params[:username], :token => params[:token] | |
respond_to do |format| | |
if @session.save_token | |
session[:user_id] = User.find_by_username(@session.user.username).try(:id) | |
user = current_user # get local user for authorization | |
# authorize ... | |
session[:user_permissions] = {:read => user.permissions.collect{|per| per.area.name if per.read}, :write => user.permissions.collect{|per| per.area.name if per.write}} | |
session[:provider_token] = params[:token] | |
format.html { redirect_to session[:original_url] || root_url } | |
else | |
@session = Session.new | |
format.html { render :new } | |
end | |
end | |
rescue ActiveResource::ForbiddenAccess | |
respond_to do |format| | |
@session = Session.new | |
format.html { render :new } | |
end | |
rescue ActiveResource::UnauthorizedAccess | |
respond_to do |format| | |
@session = Session.new | |
format.html { render :new } | |
end | |
rescue ActiveResource::MethodNotAllowed | |
respond_to do |format| | |
@session = Session.new | |
format.html { render :new } | |
end | |
rescue | |
respond_to do |format| | |
@session = Session.new | |
format.html { render :new } | |
end | |
end | |
end | |
# Creates a new session object by authenticating with the provider | |
def create | |
begin | |
@session = Session.new params[:session] | |
respond_to do |format| | |
if @session.save(UserSync) | |
# setup cookie for other applications | |
if RAILS_ENV == "production" | |
cookie_options = { | |
:value => @session.user.token, | |
:domain => 'your-provider-domain.com', | |
:secure => true, | |
:httponly => true | |
} | |
else | |
cookie_options = { | |
:value => @session.user.token, | |
:httponly => true | |
} | |
end | |
# create cookie | |
if @session.remember == "1" | |
cookies.signed.permanent[:provider_token] = cookie_options | |
else | |
cookies.signed[:provider_token] = cookie_options | |
end | |
session[:user_id] = User.find_by_username(@session.user.username).try(:id) | |
user = current_user # get local user for authorization | |
session[:user_permissions] = {:read => user.permissions.collect{|per| per.area.name if per.read}, :write => user.permissions.collect{|per| per.area.name if per.write}} | |
session[:provider_token] = @session.user.token | |
format.html { redirect_to session[:original_url] || root_url } | |
else | |
format.html { render :action => :new } | |
end | |
end | |
rescue ActiveResource::ForbiddenAccess | |
@session.errors.add_to_base "Invalid API key" | |
respond_to do |format| | |
format.html { render :new } | |
end | |
rescue ActiveResource::UnauthorizedAccess | |
@session.errors.add_to_base I18n.t(:invalid_login, :scope => [:authentasaurus, :messages, :sessions]) | |
respond_to do |format| | |
format.html { render :new } | |
end | |
rescue ActiveResource::MethodNotAllowed | |
@session.errors.add_to_base "You are not subscribed in this application" | |
respond_to do |format| | |
format.html { render :new } | |
end | |
end | |
end | |
# Logout | |
def destroy | |
session[:user_id] = nil | |
session[:user_permissions] = nil | |
session[:provider_token] = nil | |
cookies.delete :remember_me_token | |
if RAILS_ENV == "production" | |
cookies.delete(:provider_token, :domain => 'your-provider-domain.com') | |
else | |
cookies.delete(:provider_token) | |
end | |
respond_to do |format| | |
format.html { redirect_to :action => :new } | |
end | |
end | |
private | |
# Redirect user to the provider to authenticate the saved token | |
def authenticate_token | |
unless is_logged_in? | |
redirect_to url_for("#{AUTHENTASAURUS[:modules][:remote][:user][:site]}/remote_sessions/authenticate_token") # In Rails 2.3.* | |
redirect_to url_for("#{Rails.application.config.authentasaurus[:modules][:remote][:user][:site]}/remote_sessions/authenticate_token") # In Rails 3 | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class User < ActiveRecord::Base | |
authenticatable :strong_password, :validatable # Include default functions from Authentasaurus | |
@default_data = { | |
# we set the default group_id here to bypass the data incoming from the provider | |
# or to set default data for attributes that are not on the provider | |
:group_id => 2 | |
} | |
# we dont need to save the token but we need to store it in the object | |
attr_accessor :provider_token | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class UserSync < ActiveResource::Base | |
authenticatable # include the original functionality from Authentasaurus | |
# Authenticates the username and token with the provider | |
def self.authenticate_token(username, token) | |
req_body=self.post(:signin_token,:username => username, :token => token).body | |
case(self.format) | |
when ActiveResource::Formats::XmlFormat | |
user = self.new Hash.from_xml(req_body).values.first | |
when ActiveResource::Formats::JsonFormat | |
user = self.new ActiveSupport::JSON.decode(req_body) | |
else | |
user = self.new Hash.from_xml(req_body).values.first | |
end | |
# Caching the user | |
unless user.nil? | |
if self.sync && !self.sync_to.nil? | |
last_update = user.attributes.delete "updated_at" | |
local_user = self.sync_to.find_or_initialize_by_username user.username, user.attributes | |
unless local_user.new_record? | |
last_update_datetime = (last_update.kind_of?(String)) ? (DateTime.parse(last_update)) : (last_update) | |
if local_user.updated_at < last_update_datetime | |
local_user.update_attributes user.attributes | |
end | |
else | |
local_user.save | |
end | |
end | |
end | |
return user | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment