diff --git a/app/controllers/public/account_controller.rb b/app/controllers/public/account_controller.rb index 8687b2c..72eca77 100644 --- a/app/controllers/public/account_controller.rb +++ b/app/controllers/public/account_controller.rb @@ -70,19 +70,43 @@ class AccountController < PublicController end end - # posts back + # The user requests a password change. She forgot her old password. + # + # Posts back. def forgot_password @change_password = ChangePassword.new(params[:change_password]) if request.post? begin - @change_password.confirm! + @change_password.save! render :action => 'password_recovery_sent' - rescue Exception => e + rescue ActiveRecord::RecordInvalid => e nil # just pass and render at the end of the action end end end + # The user has a code for a ChangePassword request object. + # + # Posts back. + def new_password + @change_password = ChangePassword.find_by_code(params[:code]) + + unless @change_password + render :action => 'invalid_change_password_code' + return + end + + if request.post? + begin + @change_password.update_attributes!(params[:change_password]) + @change_password.finish + render :action => 'new_password_ok' + rescue ActiveRecord::RecordInvalid => e + nil # just render new_password + end + end + end + protected before_filter :load_profile_for_user diff --git a/app/models/change_password.rb b/app/models/change_password.rb index bdc7e8b..6b4eabd 100644 --- a/app/models/change_password.rb +++ b/app/models/change_password.rb @@ -8,12 +8,18 @@ class ChangePassword < Task end attr_accessor :login, :email, :password, :password_confirmation + N_('ChangePassword|Login') + N_('ChangePassword|Email') + N_('ChangePassword|Password') + N_('ChangePassword|Password Confirmation') ################################################### # validations for creating a ChangePassword task validates_presence_of :login, :email, :on => :create + validates_presence_of :requestor_id + validates_format_of :email, :on => :create, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda { |obj| !obj.email.blank? }) validates_each :login, :on => :create do |data,attr,value| @@ -29,7 +35,7 @@ class ChangePassword < Task end end - before_create do |change_password| + before_validation_on_create do |change_password| change_password.requestor = Person.find_by_identifier(change_password.login) end @@ -47,7 +53,7 @@ class ChangePassword < Task end def perform - user = User.find_by_login(self.login) + user = self.requestor.user user.force_change_password!(self.password, self.password_confirmation) end diff --git a/app/views/account/new_password.rhtml b/app/views/account/new_password.rhtml new file mode 100644 index 0000000..f627aa7 --- /dev/null +++ b/app/views/account/new_password.rhtml @@ -0,0 +1,11 @@ +
+<%= _('%s, your new password was successfully installed.') % @change_password.requestor.identifier %> +
+ ++<%= _("You can login now.") % url_for(:action => 'login') %> +
diff --git a/app/views/account/password_recovery_sent.rhtml b/app/views/account/password_recovery_sent.rhtml new file mode 100644 index 0000000..ee6a142 --- /dev/null +++ b/app/views/account/password_recovery_sent.rhtml @@ -0,0 +1,5 @@ ++<%= _('An e-mail was just sent to your e-mail address, with instructions for changing your password. You should receive it in a few minutes.') %> +
diff --git a/test/functional/account_controller_test.rb b/test/functional/account_controller_test.rb index 095385a..8b3a68f 100644 --- a/test/functional/account_controller_test.rb +++ b/test/functional/account_controller_test.rb @@ -183,11 +183,43 @@ class AccountControllerTest < Test::Unit::TestCase end should 'respond to forgotten password change request' do - flunk 'not implemented yet' + change = ChangePassword.new + ChangePassword.expects(:new).returns(change) + change.expects(:save!).returns(true) + + post :forgot_password + assert_template 'password_recovery_sent' + end + + should 'provide interface for entering new password' do + change = ChangePassword.new + ChangePassword.expects(:find_by_code).with('osidufgiashfkjsadfhkj99999').returns(change) + + get :new_password, :code => 'osidufgiashfkjsadfhkj99999' + assert_equal change, assigns(:change_password) end - should 'provide interface for entering new password to replace forgotten one' do - flunk 'not implemented yet' + should 'actually change password after entering new password' do + change = ChangePassword.new + ChangePassword.expects(:find_by_code).with('osidufgiashfkjsadfhkj99999').returns(change) + + requestor = mock + requestor.stubs(:identifier).returns('joe') + change.stubs(:requestor).returns(requestor) + change.expects(:update_attributes!).with({'password' => 'newpass', 'password_confirmation' => 'newpass'}) + change.expects(:finish) + + post :new_password, :code => 'osidufgiashfkjsadfhkj99999', :change_password => { :password => 'newpass', :password_confirmation => 'newpass' } + + assert_template 'new_password_ok' + end + + should 'require a valid change_password code' do + ChangePassword.destroy_all + + assert_raise RuntimeError do + get :new_password, :code => 'dontexist' + end end protected diff --git a/test/unit/change_password_test.rb b/test/unit/change_password_test.rb index 588a974..83201c5 100644 --- a/test/unit/change_password_test.rb +++ b/test/unit/change_password_test.rb @@ -74,21 +74,18 @@ class ChangePasswordTest < Test::Unit::TestCase should 'actually change password' do User.destroy_all - User.create!(:login => 'testuser', :password => 'test', :password_confirmation => 'test', :email => 'test@example.com') + person = User.create!(:login => 'testuser', :password => 'test', :password_confirmation => 'test', :email => 'test@example.com').person change = ChangePassword.new change.login = 'testuser' change.email = 'test@example.com' change.save! - user = User.new - User.expects(:find_by_login).with('testuser').returns(user) - user.expects(:force_change_password!).with('newpass', 'newpass') + change.expects(:requestor).returns(person).at_least_once change.password = 'newpass' change.password_confirmation = 'newpass' change.finish - end end -- libgit2 0.21.2