Created
June 21, 2011 22:14
-
-
Save namelessjon/1039058 to your computer and use it in GitHub Desktop.
Example user with a BCrypt password
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
require 'bcrypt' | |
class User | |
include DataMapper::Resource | |
attr_accessor :password, :password_confirmation | |
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 | |
# check validity of password if we have a new resource, or there is a plaintext password provided | |
def password_required? | |
new? or password | |
end | |
def reset_password(password, confirmation) | |
update(: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
for some reason the reset password method didn't work like that for me, so here is what I did :