diff --git a/app/assets/javascripts/admin/models/admin_user.js b/app/assets/javascripts/admin/models/admin_user.js index 2f5ad9514..7b04290d4 100644 --- a/app/assets/javascripts/admin/models/admin_user.js +++ b/app/assets/javascripts/admin/models/admin_user.js @@ -391,6 +391,7 @@ Discourse.AdminUser = Discourse.User.extend({ block_email: true, block_urls: true, block_ip: true, + delete_as_spammer: true, context: window.location.pathname } }).then(function(result) { diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 3b3244133..7c7a6953d 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -211,22 +211,31 @@ class Admin::UsersController < Admin::AdminController end def reject_bulk - d = UserDestroyer.new(current_user) success_count = 0 + d = UserDestroyer.new(current_user) + User.where(id: params[:users]).each do |u| success_count += 1 if guardian.can_delete_user?(u) and d.destroy(u, params.slice(:context)) rescue UserDestroyer::PostsExistError end - render json: {success: success_count, failed: (params[:users].try(:size) || 0) - success_count} + + render json: { + success: success_count, + failed: (params[:users].try(:size) || 0) - success_count + } end def destroy user = User.find_by(id: params[:id].to_i) guardian.ensure_can_delete_user!(user) begin - if UserDestroyer.new(current_user).destroy(user, params.slice(:delete_posts, :block_email, :block_urls, :block_ip, :context)) - render json: {deleted: true} + options = params.slice(:delete_posts, :block_email, :block_urls, :block_ip, :context, :delete_as_spammer) + if UserDestroyer.new(current_user).destroy(user, options) + render json: { deleted: true } else - render json: {deleted: false, user: AdminDetailedUserSerializer.new(user, root: false).as_json} + render json: { + deleted: false, + user: AdminDetailedUserSerializer.new(user, root: false).as_json + } end rescue UserDestroyer::PostsExistError raise Discourse::InvalidAccess.new("User #{user.username} has #{user.post_count} posts, so can't be deleted.") diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index adba1eeca..b68ae9ae5 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -505,7 +505,7 @@ class UsersController < ApplicationController @user = fetch_user_from_params guardian.ensure_can_delete_user!(@user) - UserDestroyer.new(current_user).destroy(@user, {delete_posts: true, context: params[:context]}) + UserDestroyer.new(current_user).destroy(@user, { delete_posts: true, context: params[:context] }) render json: success_json end diff --git a/app/services/user_destroyer.rb b/app/services/user_destroyer.rb index 0049c6775..def4bc3a9 100644 --- a/app/services/user_destroyer.rb +++ b/app/services/user_destroyer.rb @@ -15,9 +15,14 @@ class UserDestroyer raise Discourse::InvalidParameters.new('user is nil') unless user and user.is_a?(User) @guardian.ensure_can_delete_user!(user) raise PostsExistError if !opts[:delete_posts] && user.posts.count != 0 + User.transaction do if opts[:delete_posts] user.posts.each do |post| + # agree with flags + PostAction.agree_flags!(post, @actor) if opts[:delete_as_spammer] + + # block all external urls if opts[:block_urls] post.topic_links.each do |link| unless link.internal or Oneboxer.oneboxer_exists_for_url?(link.url) @@ -25,15 +30,19 @@ class UserDestroyer end end end + PostDestroyer.new(@actor.staff? ? @actor : Discourse.system_user, post).destroy + if post.topic and post.post_number == 1 Topic.unscoped.where(id: post.topic.id).update_all(user_id: nil) end end end + user.post_actions.each do |post_action| post_action.remove_act!(Discourse.system_user) end + user.destroy.tap do |u| if u if opts[:block_email] diff --git a/lib/flag_query.rb b/lib/flag_query.rb index 11c016eb2..3949ddd70 100644 --- a/lib/flag_query.rb +++ b/lib/flag_query.rb @@ -12,7 +12,7 @@ module FlagQuery post_ids = actions.limit(per_page) .offset(offset) .group(:post_id) - .order('min(post_actions.created_at) DESC') + .order('MIN(post_actions.created_at) DESC') .pluck(:post_id) .uniq @@ -114,7 +114,6 @@ module FlagQuery .joins("INNER JOIN posts ON posts.id = post_actions.post_id") .joins("INNER JOIN topics ON topics.id = posts.topic_id") .joins("LEFT JOIN users ON users.id = posts.user_id") - .where("users.id IS NOT NULL") if filter == "old" post_actions.where("post_actions.disagreed_at IS NOT NULL OR diff --git a/spec/services/user_destroyer_spec.rb b/spec/services/user_destroyer_spec.rb index b3a71db98..efb50f0bd 100644 --- a/spec/services/user_destroyer_spec.rb +++ b/spec/services/user_destroyer_spec.rb @@ -128,6 +128,23 @@ describe UserDestroyer do spammer_topic.reload.deleted_at.should_not == nil spammer_topic.user_id.should == nil end + + context "delete_as_spammer is true" do + + before { destroy_opts[:delete_as_spammer] = true } + + it "agrees with flags on user's posts" do + spammer_post = Fabricate(:post, user: @user) + flag = PostAction.act(@admin, spammer_post, PostActionType.types[:inappropriate]) + flag.agreed_at.should == nil + + destroy + + flag.reload + flag.agreed_at.should_not == nil + end + + end end context "users deletes self" do