I have a RoR application (Rails 4.2, Ruby 2.2.0) running Devise. I have set it up so that admin users (identified the "is_admin" boolean I added to the user model) are able to create new user account, provide them with a generated password and confirmation email. This is all working properly. I have also added the datetime column pass_changed which should be updated when a user changes their password, and then checked against created_at to make sure that the password has changed since the account was created. If the two dates are equal then the user is redirected to the password change form.
I wrote a procedure for checking that the user has changed their password and placed it in my application_controller.rb:
def check_changed_pass
@user = current_user
if @user.pass_changed == @user.created_at #make sure user has changed their password before accessing internal pages
redirect_to edit_user_registration_path, alert: "You must change your password before logging in for the first time"
end
end
Then in my internal_controller.rb (used for all internal that require the user to be logged in:
before_action :check_changed_pass
So far so good, but the problem comes with attempting to update pass_changed at the right time. I have tried various configurations, but I can't find where to put this code so that it triggers when a password is updated, but not every time the user model is updated, which includes every login and logout, when I only want it to trigger if the password gets updated.
If I place "before_save :update_pass_change, only: [:edit, :update]" in my controller it doesn't trigger on a password update, and if I place it in the User model, I have to put the procedure in the model as well and then it won't pick up current_user as its not available in the model. The ideal thing would be if Devise had a hook for after_password_edit similar to the after_database_authentication hook. I had to override Devise's registrations_controller.rb to remove the line
prepend_before_filter :require_no_authentication, only: [ :cancel]
So that admin users would be able to add new users. I tried placing update_pass_change there, but it doesn't seem to trigger before_save on a password edit.
In application_controller.rb
def update_pass_change # records that the user has changed their password
unless current_user.pass_changed != current_user.created_at
current_user.pass_changed = Time.now
end
end
Similar unanswered question: Ruby on Rails: Devise - password change on first login
Using passwd Command To force a user to change his/her password, first of all the password must have expired and to cause a user's password to expire, you can use the passwd command, which is used to change a user's password by specifying the -e or --expire switch along with username as shown.
Changing user passwords on Linux First sign on or “su” or “sudo” to the “root” account on Linux, run: sudo -i. Then type, passwd tom to change a password for tom user. The system will prompt you to enter a password twice.
Using passwd command Another way to force user for password change is to use the command passwd with -e option. The -e option expires the current user password forcing user to set a new one on next login. From the man page of passwd command : -e This is a quick way to expire a password for an account.
You could use a callback on your model and check, before save, if the changes includes your password attribute. Something like this:
class User < ActiveRecord::Base
before_save :check_password_changed
private
def check_password_changed
self.pass_changed = Time.now if changed.include? 'encrypted_password'
end
end
You can also try this
change datatype of pass_changed
to boolean
with default value false
Then in your application_controller.rb
before_action :check_pass_changed
private
def check_pass_changed
unless current_user.pass_changed
redirect_to custome_password_edit_path, alert: "You must change your password before logging in for the first time"
end
end
Then Create custom action in ur users_controller to display the password change form and to update.
eg.
To display form : custome_password_edit
To update :
update_user_password
also dont forget to write above in routes.rb
after successful change update the value of pass_changed
to true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With