Reed G. Law
Reed G. Law

Reputation: 3945

Migrating from Restful Authentication to Devise

A number of Rails 2.3 apps are using Restful Authentication but that plugin seems to have some issues with Rails 3. In upgrading to Rails 3 I have been using Devise. Is there any way to smoothly transition from Restful Authentication to Devise? Has anyone done a migration that shows how to update the User model?

Upvotes: 19

Views: 5873

Answers (5)

In my case it works (analized authentication.rb and by_password.rb in old gem restful_authentication):

config/initializers/devise.rb add this:

config.encryptor = :restful_authentication
config.stretches = 10 #REST_AUTH_DIGEST_STRETCHES frome Restful Authentication file config/initializers/site_key.rb
config.pepper = 'mashauronilavrechkumyachik' #REST_AUTH_SITE_KEY frome Restful Authentication file config/initializers/site_key.rb

app/models/user.rb add :encryptable

devise :database_authenticatable, :registerable,
       :recoverable, :rememberable, :trackable, :validatable,
       :encryptable, :omniauthable, :authentication_keys => [:login]

config/initializers/devise_encryptor.rb create with this this:

# -*- encoding : utf-8 -*-
require "digest/sha1"

module Devise
  module Encryptable
    module Encryptors
      class RestfulAuthentication < Base

        def self.digest(password, stretches, salt, pepper)
          digest = pepper
          stretches.times do
            digest = secure_digest(digest, salt, password, pepper)
          end
          digest
        end

        def self.secure_digest(*args)
          Digest::SHA1.hexdigest(args.flatten.join('--'))
        end

        def self.encrypt_password
          return if password.blank?
          self.password_salt = make_token if new_record?
          self.encrypted_password = encrypt(password)
        end

        def self.make_token
          secure_digest(Time.now, (1..10).map{ rand.to_s })
        end

        def self.encrypt(password)
          self.password_digest(password, stretches, salt, pepper)
        end
      end
    end
   end
end

Upvotes: 1

Anand
Anand

Reputation: 10400

Here is a good guide on migration from restful_authentication to devise

https://github.com/plataformatec/devise/wiki/How-To:-Migrate-from-restful_authentication-to-Devise

Reason for edit: prior link took folks to a blank page.

Upvotes: 15

Reed G. Law
Reed G. Law

Reputation: 3945

I was having problems with the password encryption (but I found the answer, see my other response). The old app used an old version of Restful Authentication. It was handling the password encryption like so:

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

# Encrypts some data with the salt.
def self.encrypt(password, salt)
  Digest::SHA1.hexdigest("--#{salt}--#{password}--")
end

# Encrypts the password with the user salt
def encrypt(password)
  self.class.encrypt(password, salt)
end

If I set Devise's config.encryptor to :restful_authentication_sha1 it doesn't work.

Upvotes: 2

Reed G. Law
Reed G. Law

Reputation: 3945

Here's how to overcome the password problem:

You need to make a custom encryptor like so:

# /config/initializers/devise_encryptor.rb
require "digest/sha1"  

module Devise
  module Encryptors
    class OldRestfulAuthentication < Base
      def self.digest(password, stretches, salt, pepper)
        Digest::SHA1.hexdigest("--#{salt}--#{password}--")
      end
    end
  end
end

And then choose it in devise.rb like so:

config.encryptor = :old_restful_authentication

That should do it!

Upvotes: 11

Andreas Richter
Andreas Richter

Reputation: 298

I updated my application from Restful Authentication to Devise already. Here is my migration:

class AlterUsersForDevise < ActiveRecord::Migration
  def self.up
    remove_column :users, :name
    change_column :users, :email, :string, :default => "", :null => false, :limit => 128
    rename_column :users, :crypted_password, :encrypted_password
    change_column :users, :encrypted_password, :string, :limit => 128, :default => "", :null => false
    rename_column :users, :salt, :password_salt
    change_column :users, :password_salt, :string, :default => "", :null => false, :limit => 255
    add_column :users, :reset_password_token, :string
    change_column :users, :remember_token, :string, :limit => 255
    rename_column :users, :remember_token_expires_at, :remember_created_at

    add_column :users, :sign_in_count, :integer, :default => 0
    add_column :users, :current_sign_in_at, :datetime
    add_column :users, :last_sign_in_at, :datetime
    add_column :users, :current_sign_in_ip, :string
    add_column :users, :last_sign_in_ip, :string

    rename_column :users, :activation_code, :confirmation_token
    change_column :users, :confirmation_token, :string, :limit => 255
    rename_column :users, :activated_at, :confirmed_at

    add_column :users, :confirmation_sent_at, :datetime
  end

  def self.down
    add_column :users, :name, :string, :limit => 100, :default => ""
    rename_column :users, :encrypted_password, :crypted_password
    change_column :users, :crypted_password, :string, :limit => 40
    rename_column :users, :password_salt, :salt
    change_column :users, :salt, :string, :limit => 40
    remove_column :users, :reset_password_token
    change_column :users, :remember_token, :string, :limit => 40
    rename_column :users, :remember_created_at, :remember_token_expires_at

    remove_column :users, :sign_in_count
    remove_column :users, :current_sign_in_at
    remove_column :users, :last_sign_in_at
    remove_column :users, :current_sign_in_ip
    remove_column :users, :last_sign_in_ip

    rename_column :users, :confirmation_token, :activation_code
    change_column :users, :confirmation_token, :string, :limit => 40
    rename_column :users, :confirmed_at, :activated_at

    remove_column :users, :confirmation_sent_at
  end
end

My application isn't live so far. So i use the password encryption from Devise instead the one from Restful Authorization. If you application is already alive, and you have active users you should configure Devise to use SHA1 from Restful Authentication to en- and decrypt passwords. Otherwise all your users must request a new password.

You can configure this in the devise initializer.

Hope that helps...

Upvotes: 14

Related Questions