Tiny Sunday coding project: has_password

Just a little announcement about something I cooked up this afternoon. It’s nothing ground-breaking but might save you a little time. Basically, I was getting super-tired of writing the same authentication code for every project so I extracted it into a plugin called has_password. Install like so:

ruby script/plugin install git://github.com/jcoglan/has_password

Now, this plugin is tiny and does almost nothing for you, but that’s kind of the point. All I wanted was a simple way to reuse all the password-hashing stuff, not something to generate migrations and controller code. So, all has_password does is abstract out the idea of a model class being password-protected and storing hashed passwords and salts. To use it:

class User < ActiveRecord::Base
  has_password :salt_size => 16
end

Your model should have password_hash and password_salt fields. Hashes are 160-bit (40-char) SHA1 hashes and salts are random hexadecimal strings of the bit-length you specify (16 bits gives you 4 hex digits). Your model will gain three methods:

user.password=(pwd): sets the hash and salt values of user from the given plain-text value pwd. The plain-text password is stored in user while in memory but is not persisted to the database.

user.password returns the current plain-text password if one has been set since user was pulled from the database. An object freshly pulled from the DB will return nil for this method.

user.has_password?(pwd): returns true iff user’s plain-text password is equal to pwd.

Finally, you get a callback in case you want to do stuff like send password confirmation emails. In your model class, put, for example:

after_password_change :send_notification

or

after_password_change do |model|
  UserMailer::deliver_email_notification(model)
end

In terms of validation, it automatically validates_confirmation_of :password and checks supplied passwords for a few obvious silly phrases like, say, password and test. Passwords are only validated if password is non-blank.

Give it a whirl, and do let me know if you find any bugs.