diff --git a/app/logical/user_deletion.rb b/app/logical/user_deletion.rb index 5ae143379..8b6c555a8 100644 --- a/app/logical/user_deletion.rb +++ b/app/logical/user_deletion.rb @@ -87,15 +87,11 @@ class UserDeletion end def reset_password - user.update!(password: SecureRandom.hex(16)) + user.update!(is_deleted: true, password: SecureRandom.hex(16)) end def rename - name = "user_#{user.id}" - name += "~" while User.exists?(name: name) - - request = UserNameChangeRequest.new(user: user, desired_name: name, original_name: user.name) - request.save!(validate: false) # XXX don't validate so that the 1 name change per week rule doesn't interfere + UserNameChangeRequest.create!(user: user, desired_name: "user_#{user.id}", original_name: user.name, is_deletion: true) end def validate_deletion diff --git a/app/models/user.rb b/app/models/user.rb index 518171d21..57ce3c3ab 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -88,6 +88,7 @@ class User < ApplicationRecord attribute :theme, default: :auto attribute :upload_points, default: Danbooru.config.initial_upload_points.to_i attribute :bit_prefs, default: 0 + attribute :is_deleted, default: false has_bit_flags BOOLEAN_ATTRIBUTES, :field => "bit_prefs" enum theme: { auto: 0, light: 50, dark: 100 }, _suffix: true diff --git a/app/models/user_name_change_request.rb b/app/models/user_name_change_request.rb index 2c6f94e39..85dbd632f 100644 --- a/app/models/user_name_change_request.rb +++ b/app/models/user_name_change_request.rb @@ -3,11 +3,11 @@ class UserNameChangeRequest < ApplicationRecord belongs_to :user - attr_accessor :updater + attr_accessor :updater, :is_deletion validate :not_limited, on: :create validates :original_name, presence: true - validates :desired_name, user_name: true, presence: true, on: :create + validates :desired_name, presence: true, user_name: true, on: :create, unless: :is_deletion after_create :update_name! after_create :create_mod_action @@ -33,6 +33,7 @@ class UserNameChangeRequest < ApplicationRecord end def not_limited + return if is_deletion return if user.name_invalid? return if updater && updater != user diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index e8145fbf1..4f0a87e23 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -65,7 +65,7 @@ class UserPolicy < ApplicationPolicy def api_attributes attributes = %i[ id created_at name inviter_id level level_string - post_upload_count post_update_count note_update_count is_banned + post_upload_count post_update_count note_update_count is_banned is_deleted ] if record.id == user.id diff --git a/test/unit/user_deletion_test.rb b/test/unit/user_deletion_test.rb index c13ec67d5..424344452 100644 --- a/test/unit/user_deletion_test.rb +++ b/test/unit/user_deletion_test.rb @@ -18,6 +18,7 @@ class UserDeletionTest < ActiveSupport::TestCase @deletion = UserDeletion.new(user: @user, password: "wrongpassword", request: @request) @deletion.delete! assert_includes(@deletion.errors[:base], "Password is incorrect") + assert_equal(false, @user.reload.is_deleted) end end @@ -27,6 +28,7 @@ class UserDeletionTest < ActiveSupport::TestCase @deletion = UserDeletion.new(user: @user, password: "password", request: @request) @deletion.delete! assert_includes(@deletion.errors[:base], "Admins cannot delete their account") + assert_equal(false, @user.reload.is_deleted) end end @@ -36,6 +38,7 @@ class UserDeletionTest < ActiveSupport::TestCase @deletion = UserDeletion.new(user: @user, password: "password", request: @request) @deletion.delete! assert_includes(@deletion.errors[:base], "You cannot delete your account if you are banned") + assert_equal(false, @user.reload.is_deleted) end end end @@ -64,6 +67,11 @@ class UserDeletionTest < ActiveSupport::TestCase assert_equal("user_#{@user.id}", @user.reload.name) end + should "mark the user as deleted" do + @deletion.delete! + assert_equal(true, @user.reload.is_deleted) + end + should "generate a user name change request" do @deletion.delete! assert_equal(1, @user.user_name_change_requests.count) @@ -78,6 +86,7 @@ class UserDeletionTest < ActiveSupport::TestCase should "generate a modaction" do @deletion.delete! + assert_match(/deleted user ##{@user.id}/, ModAction.last.description) assert_equal(@user, ModAction.last.subject) assert_equal("user_delete", ModAction.last.category) @@ -148,9 +157,12 @@ class UserDeletionTest < ActiveSupport::TestCase @deletion.delete! assert_equal("user_#{@user.id}", @user.reload.name) + assert_equal(true, @user.is_deleted) assert_equal("deleted user ##{@user.id}", ModAction.last.description) assert_equal(@deletion.deleter, ModAction.last.creator) assert_equal(@user, ModAction.last.subject) + assert_equal(false, ModAction.user_name_change.exists?) + assert_equal(1, ModAction.count) end should "not work for other users" do @@ -159,6 +171,7 @@ class UserDeletionTest < ActiveSupport::TestCase @deletion.delete! assert_not_equal("user_#{@user.id}", @user.reload.name) + assert_equal(false, @user.is_deleted) assert_equal(0, ModAction.count) end end