Created
January 5, 2009 15:34
-
-
Save oleganza/43438 to your computer and use it in GitHub Desktop.
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
# app/controllers/application/authentication.rb | |
class Application | |
module Authentication | |
module Accessors | |
# Returns true or false if the user is logged in. | |
# Preloads @current_person with the Person model if they're logged in. | |
def logged_in? | |
!!current_person | |
end | |
def authorized? | |
logged_in? | |
end | |
# Accesses the current user from the session. Set it to :false if login fails | |
# so that future calls do not hit the database. | |
def current_person | |
@current_person ||= (login_somehow || false) | |
end | |
# Store the given user in the session. | |
def current_person=(person) | |
session[:person] = (!person || !person.kind_of?(Person)) ? nil : person.id | |
@current_person = person | |
end | |
end # Accessors | |
module BeforeFilters | |
def authenticate | |
logged_in? || access_denied! | |
end | |
def authorize | |
authorized? || access_denied! | |
end | |
end # BeforeFilters | |
module AccessDenial | |
# This is called before throw :halt | |
def access_denied! | |
case content_type | |
when :xml | |
basic_authentication.request # this throws :halt, so we don't put it into #access_denied | |
else | |
throw(:halt, :access_denied) | |
end | |
end | |
# This is called after throw :halt | |
def access_denied(message = "Please sign in first") | |
case content_type | |
when :html | |
store_location | |
redirect url(:signin_or_signup), :message => {:error => message} | |
when :json | |
display({:error => message}) | |
end | |
end | |
end # AccessDenial | |
module LoginMethods | |
def login_somehow | |
login_from_session || login_from_cookie || login_from_basic_auth | |
end | |
# Called from #current_person. First attempt to login by the user id stored in the session. | |
def login_from_session | |
self.current_person = Person.get(session[:person]) if session[:person] | |
end | |
# Called from #current_person. Now, attempt to login by basic authentication information. | |
def login_from_basic_auth | |
basic_authentication.authenticate do |email, password| | |
self.current_person = Person.authenticate(email, password) | |
end | |
end | |
# Called from #current_person. Finaly, attempt to login by an expiring token in the cookie. | |
def login_from_cookie | |
person = cookies[:auth_token] && Person.first(:remember_token => cookies[:auth_token]) | |
if person && person.remember_token? | |
person.remember_me | |
cookies[:auth_token] = { :value => person.remember_token, :expires => Time.parse(person.remember_token_expires_at.to_s) } | |
self.current_person = person | |
end | |
end | |
end # LoginMethods | |
module RememberPerson | |
def remember_signin(domain = nil) | |
person = current_person | |
person.remember_me | |
c = { | |
:value => person.remember_token, | |
:expires => signin_session_expiration_time, | |
:domain => domain || Merb::Config[:default_cookie_domain] | |
} | |
cookies[:auth_token] = c | |
end | |
private | |
def signin_session_expiration_time | |
Time.parse(self.current_person.remember_token_expires_at.to_s) | |
end | |
end # RememberPerson | |
include Accessors | |
include BeforeFilters | |
include AccessDenial | |
include LoginMethods | |
include RememberPerson | |
end # Authentication | |
end # Application |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment