|attr_accessor :password, :password_confirmation|
|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|
|new? or password|
|def reset_password(password, confirmation)|
|update(:password => password, :password_confirmation => confirmation)|
|# 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.|
|self.crypted_pass = BCrypt::Password.create(password) if password|
|# 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.|
|pass = super|
|crypted_pass == password|
|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)|
What about using the Bcrypt property from dm-types? Could that remove the need for the
If I was worried about future devise compatibility, I might recommend changing crypted_password to encrypted_password.
This comes up often enough I wonder if we should have a semi-official example of how to do this somewhere? Or even a module that you can include in a User class.
I had some reason for not using the BCryptHash type at the time this code was originally written. I think it might have been as simple as at the time the model was added, I was only using that type and didn't want the extra gem dependency for what is very few lines of code.
Yes, it could.
I've never used devise. It's always seemed like a massive sledgehammer compared to the nut of a few methods needed to implement a simple auth scheme. Which is all I've ever needed.
I think an example is better than a module. Things like the
for some reason the reset password method didn't work like that for me, so here is what I did :