From d0c92dcf9b7f4bbc698e3eaf6ed5ddfd768ee27b Mon Sep 17 00:00:00 2001 From: AntonioTerceiro Date: Wed, 25 Jul 2007 20:19:50 +0000 Subject: [PATCH] ActionItem9: implementing changing password --- app/controllers/account_controller.rb | 18 ++++++++++++++++++ app/models/profile.rb | 2 +- app/models/user.rb | 16 +++++++++++++++- test/functional/account_controller_test.rb | 27 +++++++++++++++++++++++++++ test/unit/user_test.rb | 18 ++++++++++++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb index 44baae7..e9e7e25 100644 --- a/app/controllers/account_controller.rb +++ b/app/controllers/account_controller.rb @@ -47,4 +47,22 @@ class AccountController < ApplicationController flash[:notice] = "You have been logged out." redirect_back_or_default(:controller => '/account', :action => 'index') end + + def change_password + if request.post? + @user = current_user + begin + @user.change_password!(params[:current_password], + params[:new_password], + params[:new_password_confirmation]) + flash[:notice] = _('Your password has been changed successfully!') + redirect_to :action => 'index' + rescue User::IncorrectPassword => e + render :action => 'change_password' + end + else + render :action => 'change_password' + end + end + end diff --git a/app/models/profile.rb b/app/models/profile.rb index 91b7e94..8fb6d00 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -6,7 +6,7 @@ class Profile < ActiveRecord::Base act_as_flexible_template # Valid identifiers must match this format. - IDENTIFIER_FORMAT = /^[a-z][a-z0-9_]+[a-z0-9]$/ + IDENTIFIER_FORMAT = /^[a-z][a-z0-9_]*[a-z0-9]$/ # These names cannot be used as identifiers for Profiles RESERVED_IDENTIFIERS = %w[ diff --git a/app/models/user.rb b/app/models/user.rb index a55202e..5647677 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -18,7 +18,7 @@ class User < ActiveRecord::Base validates_presence_of :password_confirmation, :if => :password_required? validates_length_of :password, :within => 4..40, :if => :password_required? validates_confirmation_of :password, :if => :password_required? - validates_length_of :login, :within => 3..40 + validates_length_of :login, :within => 2..40 validates_length_of :email, :within => 3..100 validates_uniqueness_of :login, :email, :case_sensitive => false before_save :encrypt_password @@ -60,6 +60,20 @@ class User < ActiveRecord::Base save(false) end + # Exception thrown when #change_password! is called with a wrong current + # password + class IncorrectPassword < Exception; end + + # Changes the password of a user. + def change_password!(current, new, confirmation) + raise IncorrectPassword unless self.authenticated?(current) + self.password = new + self.password_confirmation = confirmation + unless new_record? + save! + end + end + protected # before filter def encrypt_password diff --git a/test/functional/account_controller_test.rb b/test/functional/account_controller_test.rb index 580a955..70bc7f2 100644 --- a/test/functional/account_controller_test.rb +++ b/test/functional/account_controller_test.rb @@ -124,6 +124,33 @@ class AccountControllerTest < Test::Unit::TestCase assert_template 'index' end + def test_should_display_change_password_screen + get :change_password + assert_response :success + assert_template 'change_password' + assert_tag :tag => 'input', :attributes => { :name => 'current_password' } + assert_tag :tag => 'input', :attributes => { :name => 'new_password' } + assert_tag :tag => 'input', :attributes => { :name => 'new_password_confirmation' } + end + + def test_should_be_able_to_change_password + login_as 'ze' + post :change_password, :current_password => 'test', :new_password => 'blabla', :new_password_confirmation => 'blabla' + assert_response :redirect + assert_redirected_to :action => 'index' + assert User.find_by_login('ze').authenticated?('blabla') + assert_equal users(:ze), @controller.send(:current_user) + end + + def test_should_input_current_password_correctly_to_change_password + login_as 'ze' + post :change_password, :current_password => 'wrong', :new_password => 'blabla', :new_password_confirmation => 'blabla' + assert_response :success + assert_template 'change_password' + assert ! User.find_by_login('ze').authenticated?('blabla') + assert_equal users(:ze), @controller.send(:current_user) + end + protected def create_user(options = {}) post :signup, :user => { :login => 'quire', :email => 'quire@example.com', diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 12280a4..1657d65 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -106,6 +106,24 @@ class UserTest < Test::Unit::TestCase assert ! u.errors.invalid?(:login) end + def test_should_change_password + user = User.create!(:login => 'changetest', :password => 'test', :password_confirmation => 'test', :email => 'changetest@example.com') + assert_nothing_raised do + user.change_password!('test', 'newpass', 'newpass') + end + assert !user.authenticated?('test') + assert user.authenticated?('newpass') + end + + def test_should_give_correct_current_password_for_changing_password + user = User.create!(:login => 'changetest', :password => 'test', :password_confirmation => 'test', :email => 'changetest@example.com') + assert_raise User::IncorrectPassword do + user.change_password!('wrong', 'newpass', 'newpass') + end + assert !user.authenticated?('newpass') + assert user.authenticated?('test') + end + protected def create_user(options = {}) User.create({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) -- libgit2 0.21.2