# Password, hashed\_password and validation

**URL:** <https://www.ruby-forum.com/t/password-hashed-password-and-validation/65796>\
**Category:** Rails\
**Created:** [August 21, 2006, 3:01pm UTC](https://www.ruby-forum.com/t/password-hashed-password-and-validation/65796 "2006-08-21T15:01:57Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [August 21, 2006, 3:01pm UTC](https://www.ruby-forum.com/t/password-hashed-password-and-validation/65796/1 "2006-08-21T15:01:57Z")

</div>

(Oringinally posted with several other titles with no response…maybe  
third time is the charm!)

I’m using a virtual attribute for password in my user model and a  
hashed\_password field for the persisted hashed value (a la AWDWR).

However, I am having issues using fixtures and unit tests to validate my  
models.

Example, I have a User model that has a password validation clause that  
looks something like this:

validates\_length\_of :password, :within =\> 6…30

And I have a fixture for a test user that looks something like this:

user\_jeff:  
id: 1  
username: jeff  
real\_name: Jeff Shmeff  
salt: \<%= SALT %\>  
hashed\_password: \<%= User.encrypted\_password(‘secret’, SALT) %\>  
email: removed\_email\_address@domain.invalid

if I ever attempt something like this in my User unit tests…

user = users(:user\_jeff)  
assert user.valid?

I will get an assertion failure like this:  
‘Password is too short (minimum is 6 characters)’

temporarily to get around this, I’ve taken to doing something like this  
in my test setup method:

def setup  
@user = User.find(1)  
@user.password = “this is a hack”  
end

and using @user for most of my tests instead of users(:user\_jeff).  
But, that sucks.

Any suggestions as to what I SHOULD be doing?

Jeff

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [August 21, 2006, 3:39pm UTC](https://www.ruby-forum.com/t/password-hashed-password-and-validation/65796/2 "2006-08-21T15:39:25Z")

</div>

i think you have a password= method in your model and a validation for  
that.  
instead SALTing and hashing the pass yourself, user passwor: foopasswd  
in  
your fixture. works.

2006/8/21, J Amiel [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> ```
> real_name: Jeff Shmeff
> 
> ```
> 
> ‘Password is too short (minimum is 6 characters)’  
> But, that sucks.
> 
> Any suggestions as to what I SHOULD be doing?
> 
> Jeff
> 
> –  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
> 
> >

–  
Michael S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

[www.siebert-wd.de](http://www.siebert-wd.de) - Gedanken lesen  
[www.stellar-legends.de](http://www.stellar-legends.de) - Weltraum-Browsergame im Alpha-Stadium

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [August 21, 2006, 4:32pm UTC](https://www.ruby-forum.com/t/password-hashed-password-and-validation/65796/3 "2006-08-21T16:32:03Z")

</div>

I do have a password= method in the model…

def password=(pwd)  
@password = pwd  
create\_new\_salt  
self.hashed\_password = User.encrypted\_password(self.password,  
self.salt)  
end

Butif I attempt to put password: whatever in my fixture, rails throws a  
database error while trying to populate a non-existant column in the  
table (I guess the fixtures logic doesn’t really refer back to the  
activerecord to determine the difference between virtual and ‘real’  
attributes)

Michael S. wrote:

> i think you have a password= method in your model and a validation for  
> that.  
> instead SALTing and hashing the pass yourself, user passwor: foopasswd  
> in  
> your fixture. works.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [August 21, 2006, 5:39pm UTC](https://www.ruby-forum.com/t/password-hashed-password-and-validation/65796/4 "2006-08-21T17:39:44Z")

</div>

Maybe I should also have mentioned that User also contains:

```
    def password=(password_)
            @password.password = password_
    end
```

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [August 21, 2006, 5:37pm UTC](https://www.ruby-forum.com/t/password-hashed-password-and-validation/65796/5 "2006-08-21T17:37:43Z")

</div>

\*\*\* Disclaimer: I am new to rails myself. \*\*\*

> if I ever attempt something like this in my User unit tests…
> 
> user = users(:user\_jeff)  
> assert user.valid?
> 
> I will get an assertion failure like this:  
> ‘Password is too short (minimum is 6 characters)’

> Any suggestions as to what I SHOULD be doing?

I’m not sure what the “best practice” way of doing it is, but I was  
coming up  
against the same problem recently myself. I will probably eventually  
use one  
of the popular user management generators, but I wanted to implement it  
myself first, so that I understood properly the issues involved. I  
don’t  
have time right now to give a detailed explanation of how I handled it,  
but  
the gist of it is this:

I created a separate Password class that was responsible for handling  
all  
password functionality. This class could be initialized either via the  
hashed password and salt (for when it is initialized from the database),  
or  
by passing it a plain text password. Rather than doing a  
“validates\_length\_of :password” in the user model, I did  
##############  
def validate  
errorString = @password.validation\_errors  
if errorString then  
errors.add :password, errorString  
end  
end  
##############

where @password is an instance of my Password class. So the Password  
class  
does the actual validation in validation\_errors(). If it is initialized  
with  
the password hash, it will assume that everything is ok, and return nil  
from  
validation\_errors (the user class does not allow the password\_hash or  
password\_salt to be set by a params hash). If it was initialized from a  
plaintext password, it will check that everything is ok, and return an  
error  
string if anything is wrong. This way, errors are checked when the  
password  
is first stored, but you won’t get spurious errors when the password  
info is  
loaded from the database.

I also have (in my User model)

##############  
before\_save :encrypt\_password

def encrypt\_password  
self.password\_hash, self.password\_salt =  
@password.encrypted\_version  
end  
##############

Hmm, it seems that I have given a reasonably detailed explanation after  
all.  
Let me know if you need more clarification though (there were a couple  
of  
other things I had to do… I had to add the following functions to User  
as  
well; let me know if you need me to explain why):

##############  
protected  
# This is only called when explicitly creating an object,  
# not when it is pulled from the database  
def initialize(\*params)  
@password = Password.new(nil, nil)  
super  
end

```
    # This is called regardless of whether the object
    # is explicitly created or not.
    def after_initialize
            @password ||= Password.new(self.password_hash,

```

self.password\_salt)  
end  
##############

Oh, and if anyone thinks I’ve done something stupid, let me know too…  
(see  
disclaimer at the beginning of this mail 🙂 )

Michael.
