Commit d0c92dcf9b7f4bbc698e3eaf6ed5ddfd768ee27b

Authored by AntonioTerceiro
1 parent bacd2c10

ActionItem9: implementing changing password

git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@156 3f533792-8f58-4932-b0fe-aaf55b0a4547
app/controllers/account_controller.rb
@@ -47,4 +47,22 @@ class AccountController < ApplicationController @@ -47,4 +47,22 @@ class AccountController < ApplicationController
47 flash[:notice] = "You have been logged out." 47 flash[:notice] = "You have been logged out."
48 redirect_back_or_default(:controller => '/account', :action => 'index') 48 redirect_back_or_default(:controller => '/account', :action => 'index')
49 end 49 end
  50 +
  51 + def change_password
  52 + if request.post?
  53 + @user = current_user
  54 + begin
  55 + @user.change_password!(params[:current_password],
  56 + params[:new_password],
  57 + params[:new_password_confirmation])
  58 + flash[:notice] = _('Your password has been changed successfully!')
  59 + redirect_to :action => 'index'
  60 + rescue User::IncorrectPassword => e
  61 + render :action => 'change_password'
  62 + end
  63 + else
  64 + render :action => 'change_password'
  65 + end
  66 + end
  67 +
50 end 68 end
app/models/profile.rb
@@ -6,7 +6,7 @@ class Profile < ActiveRecord::Base @@ -6,7 +6,7 @@ class Profile < ActiveRecord::Base
6 act_as_flexible_template 6 act_as_flexible_template
7 7
8 # Valid identifiers must match this format. 8 # Valid identifiers must match this format.
9 - IDENTIFIER_FORMAT = /^[a-z][a-z0-9_]+[a-z0-9]$/ 9 + IDENTIFIER_FORMAT = /^[a-z][a-z0-9_]*[a-z0-9]$/
10 10
11 # These names cannot be used as identifiers for Profiles 11 # These names cannot be used as identifiers for Profiles
12 RESERVED_IDENTIFIERS = %w[ 12 RESERVED_IDENTIFIERS = %w[
app/models/user.rb
@@ -18,7 +18,7 @@ class User < ActiveRecord::Base @@ -18,7 +18,7 @@ class User < ActiveRecord::Base
18 validates_presence_of :password_confirmation, :if => :password_required? 18 validates_presence_of :password_confirmation, :if => :password_required?
19 validates_length_of :password, :within => 4..40, :if => :password_required? 19 validates_length_of :password, :within => 4..40, :if => :password_required?
20 validates_confirmation_of :password, :if => :password_required? 20 validates_confirmation_of :password, :if => :password_required?
21 - validates_length_of :login, :within => 3..40 21 + validates_length_of :login, :within => 2..40
22 validates_length_of :email, :within => 3..100 22 validates_length_of :email, :within => 3..100
23 validates_uniqueness_of :login, :email, :case_sensitive => false 23 validates_uniqueness_of :login, :email, :case_sensitive => false
24 before_save :encrypt_password 24 before_save :encrypt_password
@@ -60,6 +60,20 @@ class User < ActiveRecord::Base @@ -60,6 +60,20 @@ class User < ActiveRecord::Base
60 save(false) 60 save(false)
61 end 61 end
62 62
  63 + # Exception thrown when #change_password! is called with a wrong current
  64 + # password
  65 + class IncorrectPassword < Exception; end
  66 +
  67 + # Changes the password of a user.
  68 + def change_password!(current, new, confirmation)
  69 + raise IncorrectPassword unless self.authenticated?(current)
  70 + self.password = new
  71 + self.password_confirmation = confirmation
  72 + unless new_record?
  73 + save!
  74 + end
  75 + end
  76 +
63 protected 77 protected
64 # before filter 78 # before filter
65 def encrypt_password 79 def encrypt_password
test/functional/account_controller_test.rb
@@ -124,6 +124,33 @@ class AccountControllerTest &lt; Test::Unit::TestCase @@ -124,6 +124,33 @@ class AccountControllerTest &lt; Test::Unit::TestCase
124 assert_template 'index' 124 assert_template 'index'
125 end 125 end
126 126
  127 + def test_should_display_change_password_screen
  128 + get :change_password
  129 + assert_response :success
  130 + assert_template 'change_password'
  131 + assert_tag :tag => 'input', :attributes => { :name => 'current_password' }
  132 + assert_tag :tag => 'input', :attributes => { :name => 'new_password' }
  133 + assert_tag :tag => 'input', :attributes => { :name => 'new_password_confirmation' }
  134 + end
  135 +
  136 + def test_should_be_able_to_change_password
  137 + login_as 'ze'
  138 + post :change_password, :current_password => 'test', :new_password => 'blabla', :new_password_confirmation => 'blabla'
  139 + assert_response :redirect
  140 + assert_redirected_to :action => 'index'
  141 + assert User.find_by_login('ze').authenticated?('blabla')
  142 + assert_equal users(:ze), @controller.send(:current_user)
  143 + end
  144 +
  145 + def test_should_input_current_password_correctly_to_change_password
  146 + login_as 'ze'
  147 + post :change_password, :current_password => 'wrong', :new_password => 'blabla', :new_password_confirmation => 'blabla'
  148 + assert_response :success
  149 + assert_template 'change_password'
  150 + assert ! User.find_by_login('ze').authenticated?('blabla')
  151 + assert_equal users(:ze), @controller.send(:current_user)
  152 + end
  153 +
127 protected 154 protected
128 def create_user(options = {}) 155 def create_user(options = {})
129 post :signup, :user => { :login => 'quire', :email => 'quire@example.com', 156 post :signup, :user => { :login => 'quire', :email => 'quire@example.com',
test/unit/user_test.rb
@@ -106,6 +106,24 @@ class UserTest &lt; Test::Unit::TestCase @@ -106,6 +106,24 @@ class UserTest &lt; Test::Unit::TestCase
106 assert ! u.errors.invalid?(:login) 106 assert ! u.errors.invalid?(:login)
107 end 107 end
108 108
  109 + def test_should_change_password
  110 + user = User.create!(:login => 'changetest', :password => 'test', :password_confirmation => 'test', :email => 'changetest@example.com')
  111 + assert_nothing_raised do
  112 + user.change_password!('test', 'newpass', 'newpass')
  113 + end
  114 + assert !user.authenticated?('test')
  115 + assert user.authenticated?('newpass')
  116 + end
  117 +
  118 + def test_should_give_correct_current_password_for_changing_password
  119 + user = User.create!(:login => 'changetest', :password => 'test', :password_confirmation => 'test', :email => 'changetest@example.com')
  120 + assert_raise User::IncorrectPassword do
  121 + user.change_password!('wrong', 'newpass', 'newpass')
  122 + end
  123 + assert !user.authenticated?('newpass')
  124 + assert user.authenticated?('test')
  125 + end
  126 +
109 protected 127 protected
110 def create_user(options = {}) 128 def create_user(options = {})
111 User.create({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) 129 User.create({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options))