restful_authentication: Where is 'crypted_password' ?

Hi,

I'm using the latest version of RoR installed on Fedora Core 6 Linux
with Apache 2.2. I just installed the plugin
"restful_authentication" (http://agilewebdevelopment.com/plugins/
restful_authentication), but whenever I try and create a new user, via
this code:

        def userconfirm
                @user = User.new(params[:user]) # line 59
                if @user.save
                        flash[:notice] = 'User was successfully
created.'
                        redirect_to :action => 'list'
                else
                        render :action => 'userinfo'
                end
        end

but I get this error. Where do I find this "crypted_password" method?
- Dave

NameError in RegisterController#userconfirm

undefined local variable or method `crypted_password' for #<User:
0xb766e3a8>

RAILS_ROOT: ./script/../config/..
Application Trace | Framework Trace | Full Trace

/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/
active_record/base.rb:1863:in `method_missing'
/usr/local/apache2/htdocs/easyrx/app/models/user.rb:93:in
`password_required?'
/usr/local/apache2/htdocs/easyrx/app/controllers/
register_controller.rb:59:in `userconfirm'

that should be a column on the table users

If you ran the command

    script/generate authenticated user session

after installing the plugin, then it should have generated a migration
which creates the users table with the necessary attributes.

If you didn't and your Users table already exists, you can generate
the rest of the stuff by using the --skip-migration option on the
generate.

You can see the fields which are needed in this case by looking in
vendor/plugins/restful_authentication/generators/authenticated/templates/migration.rb

Ok, I added the column "crypted_password" to my users table. I assume
this means I should have deleted the column "password". Anyway, now I
get another warning when I try and create a user. Upon completing the
fields and entering a password and a confirmed password, I get

There were problems with the following fields:
    * Password confirmation can't be blank

even though I'm entering a value for password confirmation. I don't
have a field "password_confirmation" in my database ... didn't think I
needed one. This is what the code looks like:

<p><label for="user_login">Username</label><br/>
<%= text_field 'user', 'login' %></p>

<p><label for="user_password">Password</label><br/>
<%= password_field 'user', 'password' %></p>

<p><label for="password_confirmation">Confirm Password</label><br/>
<%= password_field 'password_confirmation', '' %></p>

Any ideas? - Dave

You should have bits in your user model that look like these (nearly all of it is pure generated code from acts_as_authenticated):

   # Virtual attribute for the unencrypted password
   attr_accessor :password

   validates_presence_of :login, :email
   validates_presence_of :password, :if => :password_required?
   validates_presence_of :password_confirmation, :if => :password_required?
   validates_length_of :password, :within => 4..40, :if => :password_required?
   validates_confirmation_of :password, :if => :password_required?
   validates_length_of :login, :within => 3..40
   validates_length_of :email, :within => 3..100
   validates_uniqueness_of :login, :email, :case_sensitive => false, :message => "has already been taken. Please choose another."

   before_save :encrypt_password

   # Authenticates a user by their email and unencrypted password. Returns the user or nil.

<%= password_field ‘password_confirmation’, ‘’ %>

should be

<%= password_field ‘user’, ‘password_confirmation’ %>

I think Ryan probably took better aim on this one. I’m used to use form_for and not form_tag so my brain saw:

<%= f.password_field ‘password_confirmation’ %>

and filled in the rest!

But perhaps what I said helps someone else :wink:

-Rob

Rob Biedenharn http://agileconsultingllc.com

Rob@AgileConsultingLLC.com

Thanks. This cured the problem. On to the next one. When I create
the user, I now see an error:

NoMethodError in RegisterController#userconfirm
undefined method `salt=' for #<User:0xb76961c8>
RAILS_ROOT: ./script/../config/..
Application Trace | Framework Trace | Full Trace

/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/
active_record/base.rb:1860:in `method_missing'
/usr/local/apache2/htdocs/easyrx/app/models/user.rb:88:in
`encrypt_password'
/usr/local/apache2/htdocs/easyrx/app/controllers/
register_controller.rb:59:in `userconfirm'

How do I get salt defined? Here is the code in my user.rb file:

  protected
    # before filter
    def encrypt_password
      return if password.blank?
      self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--
#{login}--") if new_record? # line 88
      self.crypted_password = encrypt(password)
    end

and here is code from my register_controller.rb file:

        def userconfirm
                @user = User.new(params[:user])
                if @user.save # line 59
                        flash[:notice] = 'User was successfully
created.'
                        redirect_to :action => 'list'
                else
                        render :action => 'userinfo'
                end
        end

Thanks for your continued help, - Dave

Did you run script/generate authenticated account user? I’m beginning to think not.

salt is a required string field of your users table

Thanks. This cured the problem. On to the next one. When I create
the user, I now see an error:

NoMethodError in RegisterController#userconfirm
undefined method `salt=' for #<User:0xb76961c8>
RAILS_ROOT: ./script/../config/..
Application Trace | Framework Trace | Full Trace

/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/
active_record/base.rb:1860:in `method_missing'
/usr/local/apache2/htdocs/easyrx/app/models/user.rb:88:in
`encrypt_password'
/usr/local/apache2/htdocs/easyrx/app/controllers/
register_controller.rb:59:in `userconfirm'

How do I get salt defined? Here is the code in my user.rb file:

That should be a column in your database (and thus an attribute of your user model).

-Rob
Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

Hi,

This was the problem. I also had forgotten to add a column named
"activation_code".

Did I download this plugin from the wrong web site (http://
agilewebdevelopment.com/plugins/)? I didn't find any of this info on
there.

Thanks for all your help, - Dave

Did you read the instructions there:

http://agilewebdevelopment.com/plugins/restful_authentication

The plugin is used as a generator which creates the models,
controllers, and the migration.

Used correctly, there's no need to add any fields, the generated
migration does it for you.

Thanks for this. One problem I'm having right now is setting up a
form that logs the user in. I couldn't find any documentation on your
page. Here's my form right now:

<%= form_tag('/login', :method => :post) %>
<table>
        <tr>
                <td align="right">Login:</td>
                <td align="left"><%= text_field_tag("login", '') %></

        </tr>
        <tr>
                <td align="right">Password:</td>
                <td align="left"><%= password_field_tag("password",
'') %></td>
        </tr>
        <tr><td colspan="2"><%= submit_tag("Login") %></td></tr>
</table>
<%= end_form_tag %>

and added this to my config/routes.rb file

  map.signup '/signup', :controller => 'users', :action => 'new'
  map.login '/login', :controller => 'session', :action => 'new'
  map.logout '/logout', :controller => 'session', :action => 'destroy'

but whenever I submit the above form, with correct or incorrect
credentials, I get this error:

Unknown action
No action responded to show

Any ideas? - Dave

Rick DeNatale said the following on 23/01/08 08:16 PM:

Hi,

This was the problem. I also had forgotten to add a column named
"activation_code".

Did I download this plugin from the wrong web site (http://
agilewebdevelopment.com/plugins/)? I didn't find any of this info on
there.

Did you read the instructions there:

http://agilewebdevelopment.com/plugins/restful_authentication

The plugin is used as a generator which creates the models,
controllers, and the migration.

Used correctly, there's no need to add any fields, the generated
migration does it for you.

Ah,not quite.
The migration will create a table, yes, but it has the line

    create_table "users", :force => true do |t|

Doesn't this zap any previous table?
In the ActiveRecord code I see the lines

  if options[:force]
       drop_table(table_name, options) rescue nil
  end

Which means that any previous information that may have been in the
table such as 'address' is now lost. Id rather that didn't happen.

I've written here before about this problem with plugins and the
migrations they generate but no-one picked up on it.

This is particularly pernicious in the case of restful_authentication
when security is being added to an already partially developed
application. It really does need to be addressed.