diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 2fb297874..1572cd9f0 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -184,6 +184,13 @@ class UsersController < ApplicationController end def destroy + if @user == User.current && !@user.own_account_deletable? + respond_to do |format| + format.html { return render_error message: l(:error_unable_delete_own_account), status: 422 } + format.api { return render_api_errors(l(:error_unable_delete_own_account)) } + end + end + @user.destroy respond_to do |format| format.html { redirect_back_or_default(users_path) } diff --git a/config/locales/en.yml b/config/locales/en.yml index c3f4925cd..bfbccbacc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -233,6 +233,7 @@ en: error_can_not_delete_auth_source: "This authentication mode is in use and cannot be deleted." error_spent_on_future_date: "Cannot log time on a future date" error_not_allowed_to_log_time_for_other_users: "You are not allowed to log time for other users" + error_unable_delete_own_account: "This user is your own user and cannot be deleted" mail_subject_lost_password: "Your %{value} password" mail_body_lost_password: 'To change your password, click on the following link:' diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb index 0362d1fc8..629ac9343 100644 --- a/test/functional/users_controller_test.rb +++ b/test/functional/users_controller_test.rb @@ -852,4 +852,29 @@ class UsersControllerTest < Redmine::ControllerTest ) end end + + def test_destroy_without_unsubscribe_is_denied + user = User.find(2) + user.update(admin: true) # Create other admin so self can be deleted + @request.session[:user_id] = user.id + with_settings unsubscribe: 0 do + assert_no_difference 'User.count' do + delete :destroy, params: {id: user.id} + end + assert_response 422 + assert_select '#errorExplanation', :text => I18n.t(:error_unable_delete_own_account) + end + end + + def test_destroy_last_admin_is_denied + user = User.find(1) + @request.session[:user_id] = user.id + with_settings unsubscribe: 1 do + assert_no_difference 'User.count' do + delete :destroy, params: {id: user.id} + end + assert_response 422 + assert_select '#errorExplanation', :text => I18n.t(:error_unable_delete_own_account) + end + end end diff --git a/test/integration/api_test/users_test.rb b/test/integration/api_test/users_test.rb index 8320b4e0a..3c3c95df6 100644 --- a/test/integration/api_test/users_test.rb +++ b/test/integration/api_test/users_test.rb @@ -348,4 +348,22 @@ class Redmine::ApiTest::UsersTest < Redmine::ApiTest::Base assert_response :no_content assert_equal '', @response.body end + + test "DELETE /users/:id.xml without unsubscribe should fail delete the own user" do + assert_no_difference('User.count') do + delete '/users/1.xml', :headers => credentials('admin') + end + + assert_response 422 + assert_select 'errors error', :text => I18n.t('error_unable_delete_own_account') + end + + test "DELETE /users/:id.json without unsubscribe should fail delete the own user" do + assert_no_difference('User.count') do + delete '/users/1.json', :headers => credentials('admin') + end + + assert_response 422 + assert_equal({ 'errors' => [I18n.t('error_unable_delete_own_account')] }, ActiveSupport::JSON.decode(response.body)) + end end