Ruby on Rails
SaltedHashLoginGenerator

This article is part of the confusing world of Authentication in Rails. Feel free to get lost in a gazillion of nearly useless and/or outdated Wikipages…

Introducing the Salted Hash Login & Authentication Generator

February 15 2008.

The generator is now compatible with rails 2.0 !
Quick list of changes :
  • Fixed all deprecations
  • Fixed failing restore controller action
  • Added migration generation (mysql specific at this time)
  • Removed email field in user model : the login is now the email adress.
  • Removed passwords from notification emails. Feel free to re-add them if you think it’s better…
  • Last but not least, all tests should pass on rails 2.0.x !

FrancoisLagunas

August 20 2006.
I have modified this generator so that it works better for my needs and probably yours. In my version:

  • All of the tests pass on Rails 1.1.[4-6].
  • Example DB schema uses migrations.
  • The first_name, last_name attributes have underscores.
  • Includes a quick start zip of preconfigured default rails app files.

See LoginSugar for more info and download.
DavYaginuma

As of May 2006, I’ve taken over the Salted Hash Login Project. It’ll take me a while to get everything humming and updated, but feel free to post any bugs on the RubyForge project. Thanks. DeirdreSaoirseMoen


A generator based on the LoginGenerator by TobiasLuetke. This generator adds ActionMailer support for changed and forgotten passwords, as well as account verification via a registration email with a custom URL sent to the user’s registered address.

This generator also stores the salted, SHA1 hashed password and the SHA1 hashed salt in the database. Consequently, lost passwords cannot be recovered and require that the user generate a new password.

The project page can be found at http://rubyforge.org/projects/salted-login (and similarly, localization is at http://rubyforge.org/projects/localization.

Installation instruction are on this page, but for setup information, see SaltedLoginGeneratorQuickstart and also SaltedHashLoginUse

Features

The current revision is 1.1.1, and like LoginGenerator, includes:

but also:

Requirements

This generator requires the localization gem from RubyForge. It can be installed with:


gem install --source http://gems.rubyforge.org localization_generator

Note also that the localization gem itself requires iconv.

Installation


gem install --source http://gems.rubyforge.org salted_login_generator

script/generate salted_login User Localization

Further instructions are in the README, including tables you will need to create

Installation Problems

Rake rdoc fails

There are problems here. The first one is that rake rdoc does not work.

rake aborted!
Don't know how to build task 'rdoc'

I’m not sure what the problem is, but I could not get any rake commands to work, which meant I couldn’t get anywhere.


The reason rake rdoc doesn’t work is because no Rakefile is included with the package. To fix this, put the following code in a file called “Rakefile” inside the railsapp/vender/plugins/login_engine directory


require 'rake/clean'

CLEAN.include("rdoc")

task :default => [:rdoc]

task :rdoc => [:clean] do
  system("rdoc -o rdoc --line-numbers --inline-source --title 'Login Engine'" +
         " -T 'html' README lib/login_engine.rb app/helpers/user_helper.rb" +
         " app/controllers/user_controller.rb")
end

Adam C

rdoc loops indefinitely

I had to give gem the --no-rdoc flag to complete the install successfully. On my system (Debian unstable, Ruby 1.8.2 from the Debian package) RDoc emits a number of parse errors and loops forever. – bruce@perens.com


Why is the gem still puking when it tries to generate RDoc? This is likely going to be one of the first gems newbs will try to install after their initial installation of Rails itself and they are going to get a bunch of errors if they do unless they read Bruce Perens’ comment above. It will reflect poorly on the framework.


Again, I don’t have Debian so I’m not sure. It works fine with me. I’d be happy to help fix this if someone with Debian can send me the output when rake is run.


As it happens, I have errors on rdoc generation on both localization_generator (“File not found: lib”) and salted_login_generator (parse rrors + hang/loop) on my side of the planet (Debian mixed from stable to experimental, ruby 1.8.4, rails 1.0.0). I’ve notice recurrent issues with rdoc generation in gem with other packages as well, so my guess would be that the issue lies in the Debianized ruby or gem. Here might not be the best place to report it. But I’m still to much of a n00b on this Ruby and RoR scenes to be able to provide a good bug report. Later maybe…

Edit: Removed Spam


This package does need some cleaning up. I mean… It is released with both a table schema with a “not null” constraint on the “email” column, and a test unit that tries to save objects without caring to put anything in this field. In three bloody tests! Come on… Please run those tests before packaging that beast. Or is it that MySQL does not enforce “not null”? ;) I run it on PostgreSQL 8.1.3 by the way…

I’m on my way to try and find why do all the “UserController” tests fail, now…




"Bath and Shower":http://astore.amazon.com/nodebuy-20/?node=35
"Fragrance":http://astore.amazon.com/nodebuy-20/?node=36
"Gift Sets":http://astore.amazon.com/nodebuy-20/?node=37
"Hair Care":http://astore.amazon.com/nodebuy-20/?node=38
"Makeup":http://astore.amazon.com/nodebuy-20/?node=39
"Men's Grooming":http://astore.amazon.com/nodebuy-20/?node=40
"Shaving and Hair Removal":http://astore.amazon.com/nodebuy-20/?node=41
"Skin Care":http://astore.amazon.com/nodebuy-20/?node=42
"Tools and Accessories":http://astore.amazon.com/nodebuy-20/?node=43

"Computers - Computer Add-Ons":http://astore.amazon.com/computersbuy-20/?node=2
"Computers - Desktops":http://astore.amazon.com/computersbuy-20/?node=3
"Computers - Handhelds & PDAs":http://astore.amazon.com/computersbuy-20/?node=4
"Computers - Notebooks":http://astore.amazon.com/computersbuy-20/?node=5

"Baby Diapering":http://astore.amazon.com/babybuy-20/?node=6
"Baby Feeding":http://astore.amazon.com/babybuy-20/?node=7
"For Moms":http://astore.amazon.com/babybuy-20/?node=8
"Baby Furniture":http://astore.amazon.com/babybuy-20/?node=9
"Baby Gear":http://astore.amazon.com/babybuy-20/?node=10
"Baby Gifts":http://astore.amazon.com/babybuy-20/?node=11
"Baby Health & Baby Care":http://astore.amazon.com/babybuy-20/?node=12
"Nursery Décor":http://astore.amazon.com/babybuy-20/?node=13
"Potty Training":http://astore.amazon.com/babybuy-20/?node=14
"Baby Safety":http://astore.amazon.com/babybuy-20/?node=15
"Baby Strollers":http://astore.amazon.com/babybuy-20/?node=16

Well it looks like we are making some progress here.

The tests work.
At least they all passed on my Mac.

My current setup:

bash mac maco /pt/webprops/sysadmin/tst 104 $ script/about
script/about
About your application's environment
Ruby version                 1.8.4 (powerpc-darwin8.7.0)
RubyGems version             0.8.11
Active Record version        1.14.2
Action Pack version          1.12.1
Action Web Service version   1.1.2
Action Mailer version        1.2.1
Active Support version       1.3.1
Edge Rails revision          4814
Application root             /pt/webprops/sysadmin/tst
Environment                  development
Database adapter             postgresql
Database schema version      2
bash mac maco /pt/webprops/sysadmin/tst 105 $ 

I cannot, however, get it to work in my dev environment.

I found Clock in two places.

lib/clock.rb
and 
test/mocks/test/clock.rb

The mock clock has been debugged so that the tests will pass.

The real clock has 4 bugs in it and it's only 14 lines long.

Here is what mine looks like now after I fixed what I could:

class Clock
  def self.at( t )
    Time.at t
  end

  def self.now
    Time.now
  end

  def self.time=
    raise "Cannot set time on real Clock class" 
  end
end

At this point, I can get past the signup page once I post some data there.

I then get sent to the login page.

There, I cannot get authenticated.

I see a bunch of errors in my webserver window related to things that are deprecated:

Here is information related to the POST :

Processing UserController#login (for 127.0.0.1 at 2006-08-23 23:50:28) [POST]
  Session ID: 1d00e5031629fcf5268a5abe39172d06
  Parameters: {"user"=>{"login"=>"bbbbbb", "password"=>"bbbbbb"}, "commit"=>"Login", "action"=>"login", "controller"=>"user"}
@params is deprecated! Call params.[] instead of @params.[]. Args: ["user"] (login at /pt/webprops/sysadmin/tst/public/../config/../app/controllers/user_controller.rb:7)
  SQL (0.002785)    SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
 FROM pg_attribute a LEFT JOIN pg_attrdef d
 ON a.attrelid = d.adrelid AND a.attnum = d.adnum
 WHERE a.attrelid = 'users'::regclass
 AND a.attnum > 0 AND NOT a.attisdropped
 ORDER BY a.attnum

@params is deprecated! Call params.[] instead of @params.[]. Args: ["user"] (login at /pt/webprops/sysadmin/tst/public/../config/../app/controllers/user_controller.rb:8)
@params is deprecated! Call params.[] instead of @params.[]. Args: ["user"] (login at /pt/webprops/sysadmin/tst/public/../config/../app/controllers/user_controller.rb:8)
WARNING: find_first is deprecated and will be removed from the next Rails release (find_first at /pt/webprops/sysadmin/tst/public/../config/../vendor/rails/activerecord/lib/../../activesupport/lib/active_support/deprecation.rb:54)
  User Load (0.001495)   SELECT * FROM users WHERE (login = 'bbbbbb' AND verified = 1 AND deleted = 0) LIMIT 1
@session is deprecated! Call session.[]= instead of @session.[]=. Args: ["user", nil] (login at /pt/webprops/sysadmin/tst/public/../config/../app/controllers/user_controller.rb:8)
@params is deprecated! Call params.[] instead of @params.[]. Args: ["user"] (login at /pt/webprops/sysadmin/tst/public/../config/../app/controllers/user_controller.rb:12)
Rendering  within layouts/scaffold
Rendering user/login
@flash is deprecated! Call flash.[] instead of @flash.[]. Args: ["notice"] (head_helper at /pt/webprops/sysadmin/tst/public/../config/../app/helpers/user_helper.rb:72)
@flash is deprecated! Call flash.[] instead of @flash.[]. Args: ["message"] (head_helper at /pt/webprops/sysadmin/tst/public/../config/../app/helpers/user_helper.rb:76)
@flash is deprecated! Call flash.[] instead of @flash.[]. Args: ["message"] (head_helper at /pt/webprops/sysadmin/tst/public/../config/../app/helpers/user_helper.rb:77)
Completed in 0.02749 (36 reqs/sec) | Rendering: 0.01372 (49%) | DB: 0.00428 (15%) | 200 OK [<a href="http://hostel411/user/login">http://hostel411/user/login</a>]

If anyone can figure out how to get this stuff working,
I might be tempted to use it.

Thanks,

-Dan

Well,

it turns out that this piece of software requires that a new user
call the welcome action. The welcome action changes the user’s state
to verified. Once the user is verified, he will be allowed to
attempt authentication. The login page actually states this
which is useful to me once I read it.
I get the URL to the welcome action from the e-mail sent out
or the development.log if that is more convenient.
It looks like this:
http://localhost:3000/user/welcome?user[id]=5&key=1150518daf9bea2e7b5db68b43b0c7d2cc77182e

-Dan


Somehow I can’t get the login to work, the verified field is never set to “1”, even if I visit the welcome-URL as above.

I have tried deleting the session-files, but the database simply does not get updated.

If I set verified to “1” manually everything works ok, though.

-Sebastian


Sebastian, did you ever manage to find a sollution to the ‘verified’ key not updating? I’m running into the same problem here. Did you manage to quick-hack around it?

- Max


Sebastian and Max, look here:
http://rubyforge.org/tracker/index.php?func=detail&aid=5189&group_id=659&atid=2601

- Magnus


Thanks, Magnus, that did the trick

- Max



Two tests fail out of the box:
test_create
test_disallowed_users

In both tests you’ll need to set the email address since it’s not null in the db, ie:
u.email = “foo@bar.com

- Jeff



In my test environment (script/about -e test):
Ruby version 1.8.4 (i686-darwin8.6.2)
RubyGems version 0.8.11
Rails version 1.1.6
Active Record version 1.14.4
Action Pack version 1.12.5
Action Web Service version 1.1.6
Action Mailer version 1.2.5
Active Support version 1.3.1
Application root /Users/avilladg/svn_projects/net.avilla.cashx/trunk
Environment development
Database adapter sqlite3

test_create
test_disallowed_passwords
test_bad_logins

all needed Jeff’s

u.email = “foo@bar.com

before the call to

assert u.save

-DGA



After a default install, when trying to send out the signup message, ActionMailer throws the following error:

ArgumentError: wrong number of arguments (1 for 2) from (eval):3:in `initialize_template_class’ from (eval):3:in `render_message’

It turns out that in vendor/plugins/engines/lib/engines/action_mailer_extensions.rb initalizalize_template_class is overridden to include the method name. However, render_message is not overridden, so the default one in /usr/lib/ruby/gems/1.8/gems/actionmailer-1.2.5/lib/action_mailer/base.rb is still called. That calls initalizalize_template_class, with only one argument. Thus the error. Workaround is to comment out the one in action_mailer_extensions. perhaps I’m missing something about engines…

—Chad

Clarification

I have the same problem as Chad above, but am too noobish to clearly follow his suggestion. Should I just comment out that whole

def initalizalize_template_class ... end
?

Is that all?

Ben


When un-installing SHLG:

$ script/destroy salted_login User Localization

...the following files are removed:

          rm  public/stylesheets/scaffold.css
          rm  app/views/layouts/scaffold.rhtml

Eek! I think that just broke my application :(

—Michael


The README file includes DDL for MySQL, PostgreSQL, and SQLite – well, here’s the ActiveMigration:

class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.column :login, :string, :length => 80, :null => false
      t.column :salted_password, :string, :length => 40, :null => false
      t.column :email, :string, :length => 60, :null => false
      t.column :firstname, :string, :length => 40
      t.column :lastname, :string, :length=> 40
      t.column :salt, :string, :length => 40, :null => false
      t.column :verified, :integer, :default => 0
      t.column :role, :string, :length => 40
      t.column :security_token, :string, :length => 40
      t.column :token_expiry, :datetime
      t.column :created_at, :datetime
      t.column :updated_at, :datetime
      t.column :logged_in_at, :datetime
      t.column :deleted, :integer, :default => 0
      t.column :delete_after, :datetime
    end
  end

  def self.down
    drop_table :users
  end
end

—Michael



Warning I am an extreme NOOBI.

I recently downloaded this to use it but I ran into several test errors. After fixing up the fixture/users.ymal I got the unit tests to pass but I still run hav 2 failures and 1 error in the functioanl test that are eluding me.

1) Failure:
test_change_password0(UserControllerTest)

[c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/depr
ecated_assertions.rb:23:in `assert_session_has’

./test/functional/user_controller_test.rb:186:in `do_change_password’

./test/functional/user_controller_test.rb:194:in `test_change_password0’]:
<”user”> is not in the session <#nil, “flash”=>{}}>>

2) Error:
test_delete(UserControllerTest):
NoMethodError: undefined method `advance_by_days=’ for Time:Class

./test/functional/user_controller_test.rb:132:in `test_delete’

3) Failure:
test_signup(UserControllerTest)

[c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/depr
ecated_assertions.rb:13:in `assert_redirect’

c:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/depr
ecated_assertions.rb:98:in `assert_redirect_url’

./test/functional/user_controller_test.rb:37:in `do_test_signup’

./test/functional/user_controller_test.rb:145:in `test_signup’]:
Expected response to be a <:redirect>, but was <200>


9 tests, 80 assertions, 2 failures, 1 errors
rake aborted!
Command failed with status (1): [c:/ruby/bin/ruby Ilib;test “c:/ruby/lib/r…]


(See full trace by running task with—trace)


Can some one point me in the right direction on any of these issues?

If you are seeing a problem in Rails 1.2.1 with a 404 error page, look in the code, and especially in the salted hash login code for any places session or @request are used. The salted hash login generator (at least previously) used this convention, which is invalid as of rails 1.2.1 and will cause a 404 page, or alternately a link which says you are being redirected. The fix is to remove the sign from @session and @request everywhere it is used.

Rails 1.2.2 – Deprecated ActionMailer Configuration
check this link out if you get the rather confusing error
uninitialized constant ActiveSupport::Deprecation::RAILS_DEFAULT_LOGGER (NameError)
when using rails 1.2.2
http://www.sneaq.net/2007/02/13/rails-122-deprecated-actionmailer-configuration-server_settings/



I’m unable to install with gem. When I run the command I get success

gem install --source "http://gems.rubyforge.org":http://www.tenandtracer.com/3.html salted_login_generator
Successfully installed salted_login_generator-1.1.1


However, nothing is in my project, I installed it once to play with it. Got an idea of what I wanted to do, then rolled back my project to my last subversion commit to start real work. What do I need to do to get this installed again?

Thanks,
Todd


There is a big problem, which I can’t find a solution to anywhere on the web. For some incredibly strange reason redirect pages are being cached, so everytime anything is updated, added, logged in/out a static page comes up saying “you are being redirected”. I have set everything up exactly as described above three times over, always with the same problem. Any thoughts? And no the solution two posts above doesn’t work, removing the @ from session and request makes no difference!


I just solved this issue after one day struggling with it: it was happening here because of a class method name “hash” in a model. It somehow conflicted with rails, although the application still works perfectly unless for that annoying “you are being redirected” message. Renaming that method solved it.





Finally the issue of the functional tests failing has still not been resolved. I am also having this problem and would like to know how to fix it.



I am also having the same problem. 4 functional tests are failing for us.