Skip to content

Instantly share code, notes, and snippets.

@burningTyger
Forked from namelessjon/user.rb
Created August 13, 2011 08:35
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 burningTyger/1143627 to your computer and use it in GitHub Desktop.
Save burningTyger/1143627 to your computer and use it in GitHub Desktop.
Example user with a BCrypt password
require 'bcrypt'
class User
include DataMapper::Resource
attr_accessor :password, :password_confirmation, :password_reset
timestamps :at
property :id, Serial
property :username, String, :length => 4..30, :unique => true, :required => true
property :crypted_pass, String, :length => 60..60, :required => true, :writer => :protected
property :email, String, :length => 5..200, :required => true,
:format => :email_address
validates_presence_of :password, :password_confirmation, :if => :password_required?
validates_confirmation_of :password, :if => :password_required?
before :valid?, :crypt_password
def password_required?
new? or password_reset
end
def reset_password(password, confirmation)
update(:password_reset => true, :password => password, :password_confirmation => confirmation)
end
# Hash the password using BCrypt
#
# BCrypt is a lot more secure than a hash made for speed such as the SHA algorithm. BCrypt also
# takes care of adding a salt before hashing. The whole thing is encoded in a string 60 bytes long.
def crypt_password
self.crypted_pass = BCrypt::Password.create(password) if password
end
# Prepare a BCrypt hash from the stored password, overriding the default reader
#
# return the `:no_password` symbol if the property has no content. This is for
# the safety of the authenticate method. It's easy to pass a nil password to
# that method, but passing a specific symbol takes effort.
def crypted_pass
pass = super
if pass
BCrypt::Password.new(pass)
else
:no_password
end
end
def authenticate(password)
crypted_pass == password
end
def self.authenticate(username, password)
un = username.to_s.downcase
u = first(:conditions => ['lower(email) = ? OR lower(username) = ?', un, un])
if u && u.authenticate(password)
u
else
nil
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment