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.