Skip to content

Instantly share code, notes, and snippets.

@huobazi
Forked from eladmeidar/User.rb
Created May 30, 2011 05:42
Show Gist options
  • Save huobazi/998496 to your computer and use it in GitHub Desktop.
Save huobazi/998496 to your computer and use it in GitHub Desktop.
class User
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Document::ProtectedAttributes
attr_protected :password_hash, :password_salt
attr_accessor :password, :password_confirmation
field :username, :type => String
field :email, :type => String
field :password_hash, :type => String
field :password_salt, :type => String
field :remember_token_expires_at, :type => Time
field :remember_token, :type => String
before_save :prepare_password
validates_presence_of :username
validates_uniqueness_of :username, :message => 'has already been taken'
validates_uniqueness_of :email
validates_format_of :username, :with => /^[-\w\._@]+$/i, :allow_blank => true, :message => "should only contain letters, numbers, or .-_@"
validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i, :message => "should be in an email address format (ex: [email protected])"
validate :check_password
def check_password
if self.new_record?
errors.add(:base, "Password can't be blank") if self.password.blank?
errors.add(:base, "Password and confirmation does not match") unless self.password == self.password_confirmation
errors.add(:base, "Password must be at least 4 chars long") if self.password.to_s.size.to_i < 4
else
if self.password.blank?
errors.add(:base, "Password can't be blank") if self.password.blank?
else
errors.add(:base, "Password and confirmation does not match") unless self.password == self.password_confirmation
errors.add(:base, "Password must be at least 4 chars long") if self.password.to_s.size.to_i < 4
end
end
end
# login can be either username or email address
def self.authenticate(login, pass)
user = first(:conditions => {:username => login}) || first(:conditions => {:email => login})
return user if user && user.matching_password?(pass)
end
def matching_password?(pass)
self.password_hash == encrypt_password(pass)
end
def remember_token?
(!remember_token.blank?) &&
remember_token_expires_at && (Time.now.utc < remember_token_expires_at.utc)
end
# These create and unset the fields required for remembering users between browser closes
def remember_me
remember_me_for 2.weeks
end
def remember_me_for(time)
remember_me_until time.from_now.utc
end
def remember_me_until(time)
self.remember_token_expires_at = time
self.remember_token = self.class.make_token
save(false)
end
# refresh token (keeping same expires_at) if it exists
def refresh_token
if remember_token?
self.remember_token = self.class.make_token
save(false)
end
end
#
# Deletes the server-side record of the authentication token. The
# client-side (browser cookie) and server-side (this remember_token) must
# always be deleted together.
#
def forget_me
self.remember_token_expires_at = nil
self.remember_token = nil
save(false)
end
private
def self.secure_digest(*args)
Digest::SHA1.hexdigest(args.flatten.join('--'))
end
def self.make_token
secure_digest(Time.now, (1..10).map{ rand.to_s })
end
def prepare_password
unless password.blank?
self.password_salt = self.class.secure_digest([Time.now, rand])
self.password_hash = encrypt_password(password)
end
end
def encrypt_password(pass)
self.class.secure_digest([pass, password_salt])
end
end
@huobazi
Copy link
Author

huobazi commented May 30, 2011

class User

...
field :reset_token, :type => String
...
protected

def make_reset_token
self.reset_token = self.class.make_token
end

end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment