Files
danbooru/app/logical/user_deletion.rb
evazion f117049750 users: remove 'hide deleted posts' account setting.
This setting automatically added the `-status:deleted` metatag to all searches. This meant deleted
posts were filtered out at the database level, rather than at the html level. This way searches
wouldn't have less-than-full pages.

The cost was that searches were slower, mainly because post counts weren't cached. Normally when you
search for a tag, we can get the post count from the tags table. If the search is actually like
`touhou -status:deleted`, then we don't know the count and we have to calculate it on demand.

This option is being removed because it did the opposite of what people thought it did. People
thought it made deleted posts visible, when actually it made them more hidden.
2022-05-01 00:47:46 -05:00

95 lines
2.4 KiB
Ruby

# frozen_string_literal: true
# Delete a user's account. Deleting an account really just deactivates the
# account, it doesn't fully delete the user from the database. It wipes their
# username, password, account settings, favorites, and saved searches, and logs
# the deletion.
class UserDeletion
include ActiveModel::Validations
attr_reader :user, :password, :request
validate :validate_deletion
# Initialize a user deletion.
# @param user [User] the user to delete
# @param password [String] the user's password (for confirmation)
# @param request the HTTP request (for logging the deletion in the user event log)
def initialize(user, password, request)
@user = user
@password = password
@request = request
end
# Delete the account, if the deletion is allowed.
# @return [Boolean] if the deletion failed
# @return [User] if the deletion succeeded
def delete!
return false if invalid?
clear_user_settings
remove_favorites
clear_saved_searches
rename
reset_password
create_mod_action
create_user_event
user
end
private
def create_mod_action
ModAction.log("user ##{user.id} deleted", :user_delete)
end
def create_user_event
UserEvent.create_from_request!(user, :user_deletion, request)
end
def clear_saved_searches
SavedSearch.where(user_id: user.id).destroy_all
end
def clear_user_settings
user.email_address = nil
user.last_logged_in_at = nil
user.last_forum_read_at = nil
user.favorite_tags = ""
user.blacklisted_tags = ""
user.show_deleted_children = false
user.time_zone = "Eastern Time (US & Canada)"
user.save!
end
def reset_password
user.update!(password: SecureRandom.hex(16))
end
def remove_favorites
DeleteFavoritesJob.perform_later(user)
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
end
def validate_deletion
if !user.authenticate_password(password)
errors.add(:base, "Password is incorrect")
end
if user.is_admin?
errors.add(:base, "Admins cannot delete their account")
end
if user.is_banned?
errors.add(:base, "You cannot delete your account if you are banned")
end
end
end