-
Notifications
You must be signed in to change notification settings - Fork 5.5k
How To: Migration legacy database
Migrate a legacy user database to devise, which is using password MD5 hexdigest without salt, put this code in initializers:
Josevalim suggested the following solution in (issue #1858), just override valid_password? and reset_password? and use 'super' in your devise model
class User
def valid_password?(password)
if self.legacy_password_hash.present?
if ::Digest::MD5.hexdigest(password).upcase == self.legacy_password_hash
self.password = password
self.legacy_password_hash = nil
self.save!
true
else
false
end
else
super
end
end
def reset_password!(*args)
self.legacy_password_hash = nil
super
end
end
From version 3.5.1, reset_password!
has been deprecated in favor of reset_password
, so be aware of removing the ending ! from the last method.
If you are migrating from a system containing unencrypted plain text passwords, it is straight forward to update all of the records without waiting for some users to log in. I did this in the rails console:
users = User.where("legacy_password"!=''); users.each do |i|; i.valid_password?(i.legacy_password); end
This makes two assumptions:
-
That you called your legacy password field "legacy_password" instead of "legacy_password_hash" and changed all references in the methods.
-
Instead of doing
::Digest::MD5.hexdigest(password).upcase == self.legacy_password_hash
you can simply replace it withpassword == self.legacy_password
-
That your legacy data will satisfy your validation criteria on save. I had an issue of some legacy passwords being only 4 characters long, so you would have to reduce the min-length in devise.rb to allow successful saving. Some of my legacy fields were also blank when in the new system they were required, so you may need to set defaults as part of the console script.
You can then delete your legacy_password column, as all the passwords will now be encrypted. Before doing this check that you don't have any non-nil legacy_password instances which need manual correction before running the console script again.