Question

I'm quite new with DataMapper and Sinatra and especially attr_encrypted. What I want is to store my passwords encrypted and then be able to search for a user by username and password. I read the documentation of attr_encrypted, but I still don't get what to do :(

Can you please give my some example of a project using these two technologies or tell how to change my code to work :(

My User Class:

  class User
    include DataMapper::Resource

    attr_encryptor :password, :key => 'secret key'

    property :id,       Serial
    property :encrypted_password, Text
  end

When I save a User, I do it this way:

  username = params[:username]
  password = params[:password]
  user = User.new(:username => username, :encrypted_password => password)
  user.save

which is saving the original password, not the encrypted one.

And I have no idea how to search for users when the password is encrypted :(

Now it is something like this:

  @user = User.all(:username => username, :password => password)

Please excuse me for the newbie quiestion, but I really can't quite understand it :(

Thank you very much in advance!

Was it helpful?

Solution

You need to add the attr_encryptor line after you have specified the Data Mapper properties. This prevents DataMapper simply replacing the encrypted_password accessors with its own:

class User
  include DataMapper::Resource

  property :id,       Serial
  property :encrypted_password, Text

  # this line moved down from above
  attr_encryptor :password, :key => 'secret key'
end

and then create the user with:

user = User.new(:username => username, :password => password)

Are you sure you want to search for a User based on an encrypted password? Normally you would find the user based on e.g. username and then just check the password matches.

If you do want to do this, you will have to either recreate the encrypted password in your code and search with that (you’ll need to check the docs to see how encryption is done):

User.all(:username => username, :encrypted_password => encrypt(password))

Alternatively fetch all matching users and filter them in your code:

User.all(:username => name).select {|u| u.password == password}

OTHER TIPS

Your encrypted password is :password, so you have to do

User.new(:username => username, :password => password)

To find an user by username and password, you should just do

User.first(:username => username, :password => password)

Anyway you could avoid that gem using instead bcrypt doing a thing like this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top