-
-
Save burningTyger/1143627 to your computer and use it in GitHub Desktop.
Example user with a BCrypt password
This file contains 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
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