The blog of freelance Designer & Developer, David Rice.
14 May 2006
acts_as_authenticated is a great plugin for ruby on rails that handles a lot of the common user account functions you might find yourself developing, time and time again. The great thing is that a couple of commands and everything is generated in your app so it’s easy to modify should you need.
Some recent work i’ve been doing needed a forgotten passwords system, when I went over to the acts_as_authenticated wiki to find the Password Resetting page blank I knew it might be nice to share things when i’d finished.
First of all, i’m assuming that you’ve actually setup acts_as_authenticated and the user activation / mailer extras
It’s a little bit of work to get everything setup, but following on from the practices displayed in the other two enhancements, things should be pretty familiar.
Migration
First we’ll generate a migration to add the password reset code field, that we’ll use to ensure that our user has indeed requested to change their password
class AddPasswordResetCode < ActiveRecord::Migration
def self.up
add_column "users", "password_reset_code", :string, :limit => 40
end
def self.down
remove_column "users", "password_reset_code"
end
end
Model ( user.rb )
Okay, lets set up a couple more methods in our User model
def forgot_password
@forgotten_password = true
self.make_password_reset_code
end
def reset_password
@reset_password = true
update_attributes(:password_reset_code => nil)
end
def recently_reset_password?
@reset_password
end
def recently_forgot_password?
@forgotten_password
end
protected
def make_password_reset_code
self.password_reset_code = Digest::SHA1.hexdigest( Time.now.to_s.split('//').sort_by {rand}.join )
end
Controller ( account_controller.rb )
Now the two methods for requesting to change the password, and then reseting it to the users choice
def forgot_password
return unless request.post?
@user = User.find_by_email(params[:email])
@user.forgot_password
if @user and @user.save
redirect_back_or_default(:controller => '/account', :action => 'index')
flash[:notice] = "A Password reset link has been sent to your email address"
else
flash[:notice] = "Could not find a user with that email address"
end
end
def reset_password
@user = User.find_by_password_reset_code(params[:id])
return if @user unless params[:password]
if (params[:password] == params[:password_confirmation])
current_user.password_confirmation = params[:password_confirmation]
current_user.password = params[:password]
@user.reset_password
flash[:notice] = current_user.save ? "Password reset" : "Password not reset"
else
flash[:notice] = "Password mismatch"
end
redirect_back_or_default(:controller => '/account', :action => 'index')
end
Views
Add these two new views to views/accounts
reset_password.rhtml
<%= start_form_tag %>
<p><label for="password">Password</label><br/>
<%= password_field_tag 'password' %></p>
<p><label for="password_confirmation">Confirm Password</label><br/>
<%= password_field_tag 'password_confirmation' %></p>
<p><%= submit_tag 'Reset password' %></p>
<%= end_form_tag %>
forgot_password.rhtml
<%= start_form_tag %>
<p><label for="email">Email Address</label><br/>
<%= text_field_tag 'email' %></p>
<p><%= submit_tag 'Forgot password' %></p>
<%= end_form_tag %>
user_notifier.rb
Add these two new methods
def forgot_password(user)
setup_email(user)
@subject += 'Request to change your password'
@body[:url] = "http://localhost:3000/account/reset_password/#{user.password_reset_code}"
end
def reset_password(user)
setup_email(user)
@subject += 'Your password has been reset'
end
user_observer
Add two new lines to the after_save function
def after_save(user)
...
UserNotifier.deliver_forgot_password(user) if user.recently_forgot_password?
UserNotifier.deliver_reset_password(user) if user.recently_reset_password?
end
Mailer Templates
Add these two new templates to views/user_notifier
forgot_password.rhtml
<%= @user.login %>, follow the link to reset your password
<%= @url %>
reset_password.rhtml
<%= @user.login %>, Your password has been reset
- email me@davidjrice.co.uk
- phone me on +44 7590 538 303
If you need help with the Design, Build, Management, Hosting or Support of your project do get in touch, I'd love to hear from you!
Recently
- 22 Apr » HTML5 Validator.nu ruby gem
- 28 Sep » ActiveMerchant Support for Realex
- 09 Sep » Getting Real with Realex
- 04 Sep » Back in Black
- 25 Nov » Rails Session Storage Cookie Vs Active Record
- 06 Jun » Get Exceptional
- 21 Apr » git and github ftw
- 19 Apr » Co-Working Belfast, Put Your Money Where Your Mouth Is
- 28 Mar » Co-working Belfast Plan
- 26 Feb » Do Not Buy an Apple AirPort Extreme Base Station, They Crash and Burn
- 13 Feb » Ssh, Presentation in Progress