Idiomatic password encryption.
Let's talk theory, specifically, from the model's point of view in a user management system. What is the idiomatic way of handling password encryption? Basically, I'm shooting for:
-Validation before the password is encrypted.
-Password encryption when a user is created or said user's password is updated.
Nothing to complex, but I can think of a hand full of solutions, none of which seem ideal:
1) Take the syntactic sugar approach.
This would be good because the password is encrypted whenever it's set, however it makes validation a hassle. One could validat the encrypted_password parameter, but that seems half baked.
self.salt = generate_salt
self.password_hash = Digest::SHA1.hexdigest(unencrypted_password + self.salt)
2) Use callbacks.
There are a number of possibilities here, this would be good because you could validate the user submitted password and then encrypt it. However, it would make subsequent validations inaccurate (If you were validating the password for a length between 5 and 30 characters, a 40 character SHA1 hash and an update would break things.). Another play on this one, pass around a constant, REQUIRES_ENCRYPTION perhaps.
I've been playing with this for a couple of hours now, but I still cannot find a solution that I'm happy with. No luck with Google, Agile Web Development with Rails and Rails Recipes only cover authentication and authorization. How are you guys going about things? Thanks for any insight.
Edit: Another play on number two, I like this idea a bit better. Limit the user submitted password to 30 characters or so. Since an SHA1 hash is 40 characters the password's length could be checked in a callback, if it's anything but 40 characters it could be encrypted. Validating the user submitted password (Prior to encryption.) would still be odd though.