Class: UserDestroyer
- Inherits:
-
Object
- Object
- UserDestroyer
- Defined in:
- app/services/user_destroyer.rb
Overview
Responsible for destroying a User record
Defined Under Namespace
Classes: PostsExistError
Instance Method Summary collapse
-
#destroy(user, opts = {}) ⇒ Object
Returns false if the user failed to be deleted.
-
#initialize(actor) ⇒ UserDestroyer
constructor
A new instance of UserDestroyer.
Constructor Details
#initialize(actor) ⇒ UserDestroyer
Returns a new instance of UserDestroyer.
8 9 10 11 12 |
# File 'app/services/user_destroyer.rb', line 8 def initialize(actor) @actor = actor raise Discourse::InvalidParameters.new("acting user is nil") unless @actor && @actor.is_a?(User) @guardian = Guardian.new(actor) end |
Instance Method Details
#destroy(user, opts = {}) ⇒ Object
Returns false if the user failed to be deleted. Returns a frozen instance of the User if the delete succeeded.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'app/services/user_destroyer.rb', line 16 def destroy(user, opts = {}) raise Discourse::InvalidParameters.new("user is nil") unless user && user.is_a?(User) raise PostsExistError if !opts[:delete_posts] && user.posts.joins(:topic).count != 0 @guardian.ensure_can_delete_user!(user) # default to using a transaction opts[:transaction] = true if opts[:transaction] != false prepare_for_destroy(user) if opts[:prepare_for_destroy] == true result = nil optional_transaction(open_transaction: opts[:transaction]) do UserSecurityKey.where(user_id: user.id).delete_all Bookmark.where(user_id: user.id).delete_all Draft.where(user_id: user.id).delete_all Reviewable.where(created_by_id: user.id).delete_all category_topic_ids = Category.where("topic_id IS NOT NULL").pluck(:topic_id) if opts[:delete_posts] DiscoursePluginRegistry.user_destroyer_on_content_deletion_callbacks.each do |cb| cb.call(user, @guardian, opts) end agree_with_flags(user) if opts[:delete_as_spammer] block_external_urls(user) if opts[:block_urls] delete_posts(user, category_topic_ids, opts) end user.post_actions.find_each { |post_action| post_action.remove_act!(Discourse.system_user) } # Add info about the user to staff action logs UserHistory.staff_action_records( Discourse.system_user, acting_user: user.username, ).update_all( ["details = CONCAT(details, ?)", "\nuser_id: #{user.id}\nusername: #{user.username}"], ) # keep track of emails used user_emails = user.user_emails.pluck(:email) if result = user.destroy if opts[:block_email] user_emails.each do |email| ScreenedEmail.block(email, ip_address: result.ip_address)&.record_match! end end if opts[:block_ip] && result.ip_address ScreenedIpAddress.watch(result.ip_address)&.record_match! if result.registration_ip_address && result.ip_address != result.registration_ip_address ScreenedIpAddress.watch(result.registration_ip_address)&.record_match! end end Post.unscoped.where(user_id: result.id).update_all(user_id: nil) # If this user created categories, fix those up: Category .where(user_id: result.id) .each do |c| c.user_id = Discourse::SYSTEM_USER_ID c.save! if topic = Topic.unscoped.find_by(id: c.topic_id) topic.recover! topic.user_id = Discourse::SYSTEM_USER_ID topic.save! end end Invite .where(email: user_emails) .each do |invite| # invited_users will be removed by dependent destroy association when user is destroyed invite.invited_groups.destroy_all invite.topic_invites.destroy_all invite.destroy end unless opts[:quiet] if @actor == user deleted_by = Discourse.system_user opts[:context] = I18n.t("staff_action_logs.user_delete_self", url: opts[:context]) else deleted_by = @actor end StaffActionLogger.new(deleted_by).log_user_deletion(user, opts.slice(:context)) if opts.slice(:context).blank? Rails.logger.warn("User destroyed without context from: #{caller_locations(14, 1)[0]}") end end MessageBus.publish "/logout/#{result.id}", result.id, user_ids: [result.id] end end # After the user is deleted, remove the reviewable if reviewable = ReviewableUser.pending.find_by(target: user) reviewable.perform(@actor, :delete_user) end result end |