diff --git a/app/logical/user_deletion.rb b/app/logical/user_deletion.rb index a31ce3b50..90fd1080d 100644 --- a/app/logical/user_deletion.rb +++ b/app/logical/user_deletion.rb @@ -42,6 +42,15 @@ class UserDeletion true end + def undelete! + user.with_lock do + user.update!(is_deleted: false, password: password) + UserNameChangeRequest.create!(user: user, desired_name: user.user_name_change_requests.order(id: :desc).first.original_name, original_name: user.name) + ModAction.log("undeleted user ##{user.id}", :user_undelete, subject: user, user: deleter) + UserEvent.create_from_request!(user, :user_undeletion, request) if request.present? + end + end + # Calls `delete_user`. def async_delete_user DeleteUserJob.perform_later(user) diff --git a/app/models/mod_action.rb b/app/models/mod_action.rb index 465301eb0..9f21fc2ff 100644 --- a/app/models/mod_action.rb +++ b/app/models/mod_action.rb @@ -17,6 +17,7 @@ class ModAction < ApplicationRecord # Misc: 6-19 enum category: { user_delete: 2, + user_undelete: 3, user_ban: 4, user_unban: 5, user_name_change: 6, diff --git a/app/models/user_event.rb b/app/models/user_event.rb index baddf7e65..c27f0e7d3 100644 --- a/app/models/user_event.rb +++ b/app/models/user_event.rb @@ -15,6 +15,7 @@ class UserEvent < ApplicationRecord logout: 100, user_creation: 200, user_deletion: 300, + user_undeletion: 310, password_reset: 400, password_change: 500, email_change: 600, diff --git a/app/views/user_actions/index.html.erb b/app/views/user_actions/index.html.erb index e22b738ff..a7ff9213d 100644 --- a/app/views/user_actions/index.html.erb +++ b/app/views/user_actions/index.html.erb @@ -116,6 +116,8 @@ <%= link_to_user user %> created their account. <% when "user_deletion" %> <%= link_to_user user %> deleted their account. + <% when "user_undeletion" %> + <%= link_to_user user %>'s account was undeleted. <% when "password_reset" %> <%= link_to_user user %> reset their password. <% when "password_change" %> diff --git a/test/unit/user_deletion_test.rb b/test/unit/user_deletion_test.rb index 30e783c9b..d44d9bd73 100644 --- a/test/unit/user_deletion_test.rb +++ b/test/unit/user_deletion_test.rb @@ -172,4 +172,29 @@ class UserDeletionTest < ActiveSupport::TestCase assert_equal(0, ModAction.count) end end + + context "undeleting a user's account" do + should "restore the user's name and reset their password" do + @user = create(:user, name: "fumimi", password: "hunter2") + @deletion = UserDeletion.new(user: @user, deleter: create(:owner_user), password: "hunter2") + + @deletion.delete! + assert_equal("user_#{@user.id}", @user.reload.name) + assert_equal(true, @user.is_deleted) + assert_equal(false, @user.authenticate_password("hunter2").present?) + assert_equal("deleted user ##{@user.id}", ModAction.last.description) + assert_equal("user_delete", ModAction.last.category) + assert_equal(@deletion.deleter, ModAction.last.creator) + assert_equal(@user, ModAction.last.subject) + + @deletion.undelete! + assert_equal("fumimi", @user.reload.name) + assert_equal(false, @user.is_deleted) + assert_equal(true, @user.authenticate_password("hunter2").present?) + assert_equal("undeleted user ##{@user.id}", ModAction.last.description) + assert_equal("user_undelete", ModAction.last.category) + assert_equal(@deletion.deleter, ModAction.last.creator) + assert_equal(@user, ModAction.last.subject) + end + end end