From ea1bae56ed2f1bea2a4886e75b93eeb4cea5953a Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Tue, 3 May 2022 21:24:23 -0400 Subject: [PATCH] Enable bulk reversion of bulk tag vandalism --- lib/philomena/tag_changes.ex | 10 +++++ .../workers/tag_change_revert_worker.ex | 30 +++++++++++++ .../tag_change/full_revert_controller.ex | 43 +++++++++++++++++++ lib/philomena_web/router.ex | 5 +++ .../fingerprint_profile/show.html.slime | 4 ++ .../templates/ip_profile/show.html.slime | 4 ++ .../templates/profile/_admin_block.html.slime | 41 ++++++++++-------- 7 files changed, 120 insertions(+), 17 deletions(-) create mode 100644 lib/philomena/workers/tag_change_revert_worker.ex create mode 100644 lib/philomena_web/controllers/tag_change/full_revert_controller.ex diff --git a/lib/philomena/tag_changes.ex b/lib/philomena/tag_changes.ex index 8e3e1cef..e92c35a3 100644 --- a/lib/philomena/tag_changes.ex +++ b/lib/philomena/tag_changes.ex @@ -6,6 +6,7 @@ defmodule Philomena.TagChanges do import Ecto.Query, warn: false alias Philomena.Repo + alias Philomena.TagChangeRevertWorker alias Philomena.TagChanges.TagChange alias Philomena.Images.Tagging alias Philomena.Tags.Tag @@ -99,6 +100,15 @@ defmodule Philomena.TagChanges do end end + def full_revert(%{user_id: _user_id, attributes: _attributes} = params), + do: Exq.enqueue(Exq, "indexing", TagChangeRevertWorker, [params]) + + def full_revert(%{ip: _ip, attributes: _attributes} = params), + do: Exq.enqueue(Exq, "indexing", TagChangeRevertWorker, [params]) + + def full_revert(%{fingerprint: _fingerprint, attributes: _attributes} = params), + do: Exq.enqueue(Exq, "indexing", TagChangeRevertWorker, [params]) + @doc """ Gets a single tag_change. diff --git a/lib/philomena/workers/tag_change_revert_worker.ex b/lib/philomena/workers/tag_change_revert_worker.ex new file mode 100644 index 00000000..7822dc15 --- /dev/null +++ b/lib/philomena/workers/tag_change_revert_worker.ex @@ -0,0 +1,30 @@ +defmodule Philomena.TagChangeRevertWorker do + alias Philomena.TagChanges.TagChange + alias Philomena.TagChanges + alias Philomena.Batch + import Ecto.Query + + def perform(%{"user_id" => user_id, "attributes" => attributes}) do + TagChange + |> where(user_id: ^user_id) + |> revert_all(attributes) + end + + def perform(%{"ip" => ip, "attributes" => attributes}) do + TagChange + |> where(ip: ^ip) + |> revert_all(attributes) + end + + def perform(%{"fingerprint" => fp, "attributes" => attributes}) do + TagChange + |> where(fingerprint: ^fp) + |> revert_all(attributes) + end + + defp revert_all(queryable, attributes) do + Batch.query_batches(queryable, [batch_size: 100], fn ids -> + TagChanges.mass_revert(ids, attributes) + end) + end +end diff --git a/lib/philomena_web/controllers/tag_change/full_revert_controller.ex b/lib/philomena_web/controllers/tag_change/full_revert_controller.ex new file mode 100644 index 00000000..6978cba1 --- /dev/null +++ b/lib/philomena_web/controllers/tag_change/full_revert_controller.ex @@ -0,0 +1,43 @@ +defmodule PhilomenaWeb.TagChange.FullRevertController do + use PhilomenaWeb, :controller + + alias Philomena.TagChanges.TagChange + alias Philomena.TagChanges + + plug :verify_authorized + plug PhilomenaWeb.UserAttributionPlug + + def create(conn, params) do + attributes = conn.assigns.attributes + + attributes = %{ + ip: to_string(attributes[:ip]), + fingerprint: attributes[:fingerprint], + referrer: attributes[:referrer], + user_agent: attributes[:referrer], + user_id: attributes[:user].id + } + + case params do + %{"user_id" => user_id} -> + TagChanges.full_revert(%{user_id: user_id, attributes: attributes}) + + %{"ip" => ip} -> + TagChanges.full_revert(%{ip: ip, attributes: attributes}) + + %{"fingerprint" => fp} -> + TagChanges.full_revert(%{fingerprint: fp, attributes: attributes}) + end + + conn + |> put_flash(:info, "Reversion of tag changes enqueued.") + |> redirect(external: conn.assigns.referrer) + end + + defp verify_authorized(conn, _params) do + case Canada.Can.can?(conn.assigns.current_user, :revert, TagChange) do + true -> conn + _false -> PhilomenaWeb.NotAuthorizedPlug.call(conn) + end + end +end diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index c5d48d9d..55eb951a 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -439,6 +439,11 @@ defmodule PhilomenaWeb.Router do only: [:create], singleton: true + resources "/tag_changes/full_revert", TagChange.FullRevertController, + as: :tag_change_full_revert, + only: [:create], + singleton: true + resources "/pages", PageController, only: [:index, :new, :create, :edit, :update] resources "/channels", ChannelController, only: [:new, :create, :edit, :update, :delete] end diff --git a/lib/philomena_web/templates/fingerprint_profile/show.html.slime b/lib/philomena_web/templates/fingerprint_profile/show.html.slime index e6f73f91..b065f86a 100644 --- a/lib/philomena_web/templates/fingerprint_profile/show.html.slime +++ b/lib/philomena_web/templates/fingerprint_profile/show.html.slime @@ -17,6 +17,10 @@ ul li = link "View fingerprint ban history", to: Routes.admin_fingerprint_ban_path(@conn, :index, fingerprint: @fingerprint) li = link "Ban this sucker", to: Routes.admin_fingerprint_ban_path(@conn, :new, fingerprint: @fingerprint) +h2 Actions +ul + li = link "Revert all tag changes", to: Routes.tag_change_full_revert_path(@conn, :create, [fingerprint: @fingerprint]), data: [confirm: "Are you really, really sure?", method: "create"] + h4 Observed users table.table thead diff --git a/lib/philomena_web/templates/ip_profile/show.html.slime b/lib/philomena_web/templates/ip_profile/show.html.slime index 0a886778..ac6ead35 100644 --- a/lib/philomena_web/templates/ip_profile/show.html.slime +++ b/lib/philomena_web/templates/ip_profile/show.html.slime @@ -17,6 +17,10 @@ ul li = link "View IP ban history", to: Routes.admin_subnet_ban_path(@conn, :index, ip: to_string(@ip)) li = link "Ban this sucker", to: Routes.admin_subnet_ban_path(@conn, :new, specification: to_string(@ip)) +h2 Actions +ul + li = link "Revert all tag changes", to: Routes.tag_change_full_revert_path(@conn, :create, [ip: to_string(@ip)]), data: [confirm: "Are you really, really sure?", method: "create"] + h4 Observed users table.table thead diff --git a/lib/philomena_web/templates/profile/_admin_block.html.slime b/lib/philomena_web/templates/profile/_admin_block.html.slime index fdb3bd53..44c0fe4f 100644 --- a/lib/philomena_web/templates/profile/_admin_block.html.slime +++ b/lib/philomena_web/templates/profile/_admin_block.html.slime @@ -84,6 +84,12 @@ a.label.label--primary.label--block href="#" data-click-toggle=".js-admin__optio i.fa.fa-fw.fa-users span.admin__button Potential Aliases + = if can?(@conn, :index, %Philomena.Donations.Donation{}) do + li + = link to: Routes.admin_donation_user_path(@conn, :show, @user) do + i.fas.fa-fw.fa-dollar-sign + span.admin__button Donations + ul.profile-admin__options__column = if can?(@conn, :edit, @user) do li @@ -124,23 +130,6 @@ a.label.label--primary.label--block href="#" data-click-toggle=".js-admin__optio i.fas.fa-fw.fa-eraser span.admin__button Wipe PII - = if can?(@conn, :index, Philomena.Users.User) do - li - = link to: Routes.admin_user_vote_path(@conn, :delete, @user), data: [confirm: "Are you really, really sure?", method: "delete"] do - i.far.fa-fw.fa-file-excel - span.admin__button Remove All Votes/Faves - - li - = link to: Routes.admin_user_downvote_path(@conn, :delete, @user), data: [confirm: "Are you really, really sure?", method: "delete"] do - i.fa.fa-fw.fa-arrow-down - span.admin__button Remove All Downvotes - - = if can?(@conn, :index, %Philomena.Donations.Donation{}) do - li - = link to: Routes.admin_donation_user_path(@conn, :show, @user) do - i.fas.fa-fw.fa-dollar-sign - span.admin__button Donations - = if can?(@conn, :edit, %Philomena.ArtistLinks.ArtistLink{}) do li = link to: Routes.profile_artist_link_path(@conn, :new, @user) do @@ -169,3 +158,21 @@ a.label.label--primary.label--block href="#" data-click-toggle=".js-admin__optio = link to: Routes.admin_user_verification_path(@conn, :create, @user), data: [confirm: "Are you really, really sure?", method: "create"] do i.fas.fa-fw.fa-user-check span.admin__button Grant Verification + + ul.profile-admin__options__column + = if can?(@conn, :index, Philomena.Users.User) do + li + = link to: Routes.admin_user_vote_path(@conn, :delete, @user), data: [confirm: "Are you really, really sure?", method: "delete"] do + i.far.fa-fw.fa-file-excel + span.admin__button Remove All Votes/Faves + + li + = link to: Routes.admin_user_downvote_path(@conn, :delete, @user), data: [confirm: "Are you really, really sure?", method: "delete"] do + i.fa.fa-fw.fa-arrow-down + span.admin__button Remove All Downvotes + + = if can?(@conn, :revert, Philomena.TagChanges.TagChange) do + li + = link to: Routes.tag_change_full_revert_path(@conn, :create, [user_id: @user.id]), data: [confirm: "Are you really, really sure?", method: "create"] do + i.fa.fa-fw.fa-tag + span.admin__button Revert All Tag Changes