From 61a4f52873396c769bfd986f58162319775e66d9 Mon Sep 17 00:00:00 2001 From: EchoEkhi Date: Wed, 14 Aug 2024 21:25:34 +0800 Subject: [PATCH] AO3-6728 Delete comments properly for spammer bans (#4855) * AO3-6728 Do comment deletions separately for spammer mass deletes * AO3-6728 Implement i18n properly * AO3-6728 Fix link * AO3-6728 Normalise i18n file * AO3-6728 Skip Akismet for comment deletes --- .../admin/admin_users_controller.rb | 13 +++++++++-- app/controllers/application_controller.rb | 12 +++++----- config/i18n-tasks.yml | 3 --- config/locales/controllers/en.yml | 7 ++++++ .../admins/users/admin_abuse_users.feature | 22 +++++++++++++++++++ 5 files changed, 46 insertions(+), 11 deletions(-) diff --git a/app/controllers/admin/admin_users_controller.rb b/app/controllers/admin/admin_users_controller.rb index 94a7e96e298..9f923cbfa85 100644 --- a/app/controllers/admin/admin_users_controller.rb +++ b/app/controllers/admin/admin_users_controller.rb @@ -139,13 +139,22 @@ def confirm_delete_user_creations def destroy_user_creations authorize @user - creations = @user.works + @user.bookmarks + @user.sole_owned_collections + @user.comments + + creations = @user.works + @user.bookmarks + @user.sole_owned_collections creations.each do |creation| AdminActivity.log_action(current_admin, creation, action: "destroy spam", summary: creation.inspect) creation.mark_as_spam! if creation.respond_to?(:mark_as_spam!) creation.destroy end - flash[:notice] = ts("All creations by user %{login} have been deleted.", login: @user.login) + + # comments are special and needs to be handled separately + @user.comments.each do |comment| + AdminActivity.log_action(current_admin, comment, action: "destroy spam", summary: comment.inspect) + # Akismet spam procedures are skipped, since logged-in comments aren't spam-checked anyways + comment.destroy_or_mark_deleted # comments with replies cannot be destroyed, mark deleted instead + end + + flash[:notice] = t(".success", login: @user.login) redirect_to(admin_users_path) end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5cf4afd6843..53f5b0b37f0 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -389,11 +389,11 @@ def use_caching? # Prevents banned and suspended users from adding/editing content def check_user_status if current_user.is_a?(User) && (current_user.suspended? || current_user.banned?) - if current_user.suspended? - flash[:error] = t("suspension_notice", default: "Your account has been suspended until %{suspended_until}. You may not add or edit content until your suspension has been resolved. Please contact Abuse for more information.", suspended_until: localize(current_user.suspended_until)).html_safe - else - flash[:error] = t("ban_notice", default: "Your account has been banned. You are not permitted to add or edit archive content. Please contact Abuse for more information.").html_safe - end + flash[:error] = if current_user.suspended? + t("users.status.suspension_notice_html", contact_abuse_link: view_context.link_to(t("users.status.contact_abuse"), new_abuse_report_path), suspended_until: localize(current_user.suspended_until)) + else + t("users.status.ban_notice_html", contact_abuse_link: view_context.link_to(t("users.status.contact_abuse"), new_abuse_report_path)) + end redirect_to current_user end end @@ -402,7 +402,7 @@ def check_user_status def check_user_not_suspended return unless current_user.is_a?(User) && current_user.suspended? - flash[:error] = t("suspension_notice", default: "Your account has been suspended until %{suspended_until}. You may not add or edit content until your suspension has been resolved. Please contact Abuse for more information.", suspended_until: localize(current_user.suspended_until)).html_safe + flash[:error] = t("users.status.suspension_notice_html", contact_abuse_link: view_context.link_to(t("users.status.contact_abuse"), new_abuse_report_path), suspended_until: localize(current_user.suspended_until)) redirect_to current_user end diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 38d80aa9583..bea108f0aac 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -123,9 +123,6 @@ ignore_missing: - no_email # should be admin.admin_invitations.create.no_email - sent # should be admin.admin_invitations.create.sent - user_not_found # should be admin.admin_invitations.find.user_not_found - # File: app/controllers/application_controller.rb - - ban_notice # should be application.check_user_status.ban_notice - - suspension_notice # should be application.check_user_status.suspension_notice # File: app/controllers/challenge_assignments_controller.rb - challenge_assignments.assignments_not_sent - challenge_assignments.assignments_sent diff --git a/config/locales/controllers/en.yml b/config/locales/controllers/en.yml index 354b593554b..bc8d7c3a86c 100644 --- a/config/locales/controllers/en.yml +++ b/config/locales/controllers/en.yml @@ -8,6 +8,9 @@ en: success: one: "%{count} person from the invite queue is being invited." other: "%{count} people from the invite queue are being invited." + admin_users: + destroy_user_creations: + success: All creations by user %{login} have been deleted. blocked: users: create: @@ -101,3 +104,7 @@ en: one: You may reset your password %{count} more time. other: You may reset your password %{count} more times. user_not_found: We couldn't find an account with that email address or username. Please try again. + status: + ban_notice_html: Your account has been banned. You are not permitted to add or edit archive content. Please %{contact_abuse_link} for more information. + contact_abuse: contact Abuse + suspension_notice_html: Your account has been suspended until %{suspended_until}. You may not add or edit content until your suspension has been resolved. Please %{contact_abuse_link} for more information. diff --git a/features/admins/users/admin_abuse_users.feature b/features/admins/users/admin_abuse_users.feature index 5e091a8be05..781002d215e 100644 --- a/features/admins/users/admin_abuse_users.feature +++ b/features/admins/users/admin_abuse_users.feature @@ -183,6 +183,28 @@ Feature: Admin Abuse actions And there should be no bookmarks on the work "Not Spam" And there should be no comments on the work "Not Spam" + Scenario: A permabanned spammer's comments' replies from others should stay visible + Given I have a work "Generic Work" + And a comment "I like spam" by "Spamster" on the work "Generic Work" + And a reply "I don't :(" by "NotSpamster" on the work "Generic Work" + And a comment "A thread of spams" by "Spamster" on the work "Generic Work" + And a reply "more spam" by "Spamster" on the work "Generic Work" + When I am logged in as a "policy_and_abuse" admin + And I go to the user administration page for "Spamster" + And I choose "Spammer: ban and delete all creations" + And I press "Update" + Then I should see "permanently suspended" + And the user "Spamster" should be permanently banned + And I should see "I like spam" + When I press "Yes, Delete All Spammer Creations" + Then I should see "All creations by user Spamster have been deleted." + When I go to the work comments page for "Generic Work" + Then I should not see "I like spam" + And I should see "(Previous comment deleted.)" + And I should see "I don't :(" + And I should not see "A thread of spams" + And I should not see "more spam" + Scenario: A user's works cannot be destroyed unless they are banned Given I am logged in as "Spamster" And I post the work "Loads of Spam"