3

I'm a bit confused about an error I'm getting from running an integration test for users to sign in. Here are the first few lines of the trace:

invalid hash
    @ /home/benjamin/.rvm/gems/ruby-1.9.3-p194/gems/bcrypt-ruby-3.0.1/lib/bcrypt.rb:171:in `initialize'
      /home/benjamin/.rvm/gems/ruby-1.9.3-p194/gems/activemodel-3.2.6/lib/active_model/secure_password.rb:58:in `new'
      /home/benjamin/.rvm/gems/ruby-1.9.3-p194/gems/activemodel-3.2.6/lib/active_model/secure_password.rb:58:in `authenticate'
      /home/benjamin/projects/LTClone/app/controllers/sessions_controller.rb:9:in `create'

So the error is coming from this line in the create action:

if user && user.authenticate(params[:session][:password])

which calls the authenticate method defined in secure_password.rb:

def authenticate(unencrypted_password)
  if BCrypt::Password.new(password_digest) == unencrypted_password
    ...

which calls the BCrypt::Password.new method, which is defined in bcrypt.rb:

def initialize(raw_hash)
  if valid_hash?(raw_hash)
    ...
  else
    raise Errors::InvalidHash.new("invalid hash")        # line 171
  end
end

So for some reason, raw_hash is not matching the regex specified by valid_hash?, which means that the password_digest variable isn't a valid hash. Based on this answer, it would seem like the user I'm trying to authenticate has a blank or invalid password_digest, but before I call the create action in the test, I can puts @user.password_digest, and the hash is printed (and Rubular says the valid_hash? regex matches it). I also changed the create method to

if user && user.password_digest && user.authenticate(params[:session][:password])

just to make sure it really really exists.

So now I'm just completely stumped. It seems like I have a valid password_digest, but BCrypt::Password.new refuses to recognize it as such. Does anybody know why?

Community
  • 1
  • 1
bentrevor
  • 248
  • 6
  • 14

3 Answers3

2

Check your User "password_digest" column. If it's "nil" then you will get this error. Suggestion is to simply delete all users and ensure users are properly created.

sivabudh
  • 29,317
  • 56
  • 156
  • 219
1

I'm not sure if this will be the same solution for you, but my issue (very same error) was resolved by changing the password in the fixture stored in the test/fixtures/users.yml file. Once I saved and ran rails test again, the test passed.

Mitch
  • 11
  • 1
0

You can do an if/else to see if password or password_digest is nil

if user.password.nil?
  #redirect back to login with message
else

if user && user.authenticate(params[:session][:password])
  #do your stuff!
end
Sebastian Palma
  • 29,105
  • 6
  • 30
  • 48
riliwanrabo
  • 163
  • 1
  • 1
  • 10