public
Description: Rails authentication with email & password.
Home | Edit | New

restful_authentication to Clearance

Updating Models

  • Install clearance as normal, using script/generate clearance
  • The database migration automatically runs, which sort of sucks. Bring it back down with rake db:migrate:down VERSION=<whatever date given for the migration created>
  • Edit the migration that was just generated. I changed it to this:
class CreateOrUpdateUsersWithClearanceColumns < ActiveRecord::Migration
  def self.up
    change_table(:users) do |t|
      t.boolean :email_confirmed, :default => false, :null => false
    end
    rename_column :users, :crypted_password, :encrypted_password
    rename_column :users, :remember_token, :token
    rename_column :users, :remember_token_expires_at, :token_expires_at

    add_index :users, [:id, :token]
    add_index :users, :email
    add_index :users, :token

    User.all.each { |u| u.update_attribute(:email_confirmed, true) unless u.activation_code }
  end

  def self.down
    change_table(:users) do |t|
      t.remove :email_confirmed
    end

    rename_column :users, :encrypted_password, :crypted_password
    rename_column :users, :token, :remember_token
    rename_column :users, :token_expires_at, :remember_token_expires_at

    remove_index :users [:id, :token]
    remove_index :users, :email
    remove_index :users, :token
  end
end
  • At this point, I made a backup of my production DB and imported it into my own machine, mostly to test if the passwords were working correctly or not. You may or may not want to do the same.
  • Since all of the passwords are still in restful-auth’s format, we want to keep it that way. You have to tell the user model to use restful-auth’s password encryption. I added this to my user model:
  class << self
    def secure_digest(*args)
      Digest::SHA1.hexdigest(args.flatten.join('--'))
    end

    def password_digest(password, salt)
      digest = REST_AUTH_SITE_KEY
      REST_AUTH_DIGEST_STRETCHES.times do
        digest = secure_digest(digest, salt, password, REST_AUTH_SITE_KEY)
      end
      digest
    end
  end

  def encrypt(password)
    self.class.password_digest(password, salt)
  end
  • Of course, our tests will fail now. I haven’t figured out how to override tests, but I went into vendor/gems/clearance-0.5.3/lib/clearance/test/unit/user_test.rb, and changed line 46 to:
@expected = User.password_digest(@password, @salt)
  • Hopefully now your unit tests are passing with flying colors! Make sure to try User.authenticate on some user you know of in your imported DB just to make sure it’s working as well.

Updating Controllers

I used logged_in? extensively and most likely will continue to just for consistency, so I had to add this to my ApplicationController:

alias_method :logged_in?, :signed_in?
helper_method :logged_in?

Also make sure you bring over any other methods you stuck into lib/authenticated_system.rb that were not in there originally. I built in some role checks in there that I had to dredge up. Other than this, I didn’t have many other issues updating the controllers.

Last edited by qrush, Sun Mar 15 12:02:17 -0700 2009
Home | Edit | New
Versions: