Skip to content

Instantly share code, notes, and snippets.

@oleganza
Created December 3, 2008 16:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oleganza/31604 to your computer and use it in GitHub Desktop.
Save oleganza/31604 to your computer and use it in GitHub Desktop.
auto_sign_in.rb
module AutoSignIn
PARAM = :sign_in_token
protected
# usage:
# before :auto_sign_in
# url(..., auto_sign_in_params(person))
#
def auto_sign_in
if tk = params[PARAM]
if person = AutoSignInToken.person_for_token(tk)
self.current_person = token.person
remember_signin
end
throw(:halt, :redirect_after_auto_sign_in)
end
end
# this method does redirect to the requested URI stripping auth token from it
# to prevent infinite looping
def redirect_after_auto_sign_in
qp = request.send(:query_params).dup # we use private Merb API here
qp.delete(PARAM)
redirect(request.uri + "?" + Merb::Parse.params_to_query_string(qp))
end
module Helper
# Usage:
# url(..., auto_sign_in_params(person))
# url(..., {:a => 1}.merge(auto_sign_in_params(person)))
def auto_sign_in_params(person)
{ AutoSignIn::PARAM => auto_sign_in_token_for_person(person) }
end
def auto_sign_in_token_for_person(person)
at = AutoSignInToken.create(:person => person)
at.valid? or raise "AutoSignInToken is invalid!"
at.token
end
end
include Helper
end
# Okay, we keep this model here just for keeping this tiny feature in one file.
# Blame me, but consider this as a "MVC subcomponent"
class AutoSignInToken
include DataMapper::Resource
property :id, DataMapper::Types::Serial, :key => true
property :created_at, DateTime
property :token, String, :unique_index => true
belongs_to :person
validates_present :person
before :valid? do
self.token ||= rand(2**160).to_s(16)
end
TIMEOUT = 3600*24*7
class <<self
# Call this to get a person if all security conditions are met
def person_for_token(tk)
token = first(:token => tk) or return nil
Time.now - token.created_at < TIMEOUT or return nil
token.person
end
end
end # AutoSignInToken
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment