diff options
Diffstat (limited to 'lib/pleroma')
-rw-r--r-- | lib/pleroma/activity.ex | 30 | ||||
-rw-r--r-- | lib/pleroma/user.ex | 5 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub.ex | 10 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/utils.ex | 118 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/views/user_view.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/admin_api/admin_api_controller.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/admin_api/views/report_view.ex | 36 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 3 |
8 files changed, 204 insertions, 8 deletions
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 72e2256ea..95ca3fc2e 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -190,9 +190,33 @@ defmodule Pleroma.Activity do |> Repo.one() end + def all_by_ids(ids) do + ids + |> all_by_ids_query() + |> Repo.all() + end + + def all_by_ids_query(query \\ Activity, ids) do + from(a in query, where: a.id in ^ids) + end + def all_by_ids_with_object(ids) do - Activity - |> where([a], a.id in ^ids) + ids + |> all_by_ids_query() + |> with_preloaded_object() + |> Repo.all() + end + + def all_by_ap_ids_query(query \\ Activity, ap_ids) do + from( + a in query, + where: fragment("(?)->>'id' = ANY(?)", a.data, ^ap_ids) + ) + end + + def all_by_ap_ids_with_object(ap_ids) do + ap_ids + |> all_by_ap_ids_query() |> with_preloaded_object() |> Repo.all() end @@ -330,4 +354,6 @@ defmodule Pleroma.Activity do _ -> nil end end + + def flags_activities_query(query \\ Activity), do: Queries.by_type(query, "Flag") end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 5ea36fea3..2bca398b7 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -713,6 +713,11 @@ defmodule Pleroma.User do |> Repo.all() end + def get_all_by_ap_ids(ap_ids) do + from(u in __MODULE__, where: u.ap_id in ^ap_ids) + |> Repo.all() + end + # This is mostly an SPC migration fix. This guesses the user nickname by taking the last part # of the ap_id and the domain and tries to get that user def get_by_guessed_nickname(ap_id) do diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 5c436941a..0c2d4d6eb 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -236,7 +236,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do # only accept false as false value local = !(params[:local] == false) published = params[:published] - quick_insert? = Pleroma.Config.get([:env]) == :benchmark + quick_insert? = Config.get([:env]) == :benchmark with create_data <- make_create_data( @@ -525,6 +525,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do additional = params[:additional] || %{} + quick_insert? = Config.get(:env) == :benchmark + additional = if forward do Map.merge(additional, %{"to" => [], "cc" => [account.ap_id]}) @@ -534,6 +536,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do with flag_data <- make_flag_data(params, additional), {:ok, activity} <- insert(flag_data, local), + {:quick_insert, false, activity} <- {:quick_insert, quick_insert?, activity}, {:ok, stripped_activity} <- strip_report_status_data(activity), :ok <- maybe_federate(stripped_activity) do Enum.each(User.all_superusers(), fn superuser -> @@ -543,6 +546,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end) {:ok, activity} + else + {:quick_insert, true, activity} -> {:ok, activity} + e -> e end end @@ -1321,7 +1327,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp maybe_update_follow_information(data) do with {:enabled, true} <- - {:enabled, Pleroma.Config.get([:instance, :external_user_synchronization])}, + {:enabled, Config.get([:instance, :external_user_synchronization])}, {:ok, info} <- fetch_follow_information_for_user(data) do info = Map.merge(data[:info] || %{}, info) Map.put(data, :info, info) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 10ce5eee8..750d15ac6 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -907,12 +907,124 @@ defmodule Pleroma.Web.ActivityPub.Utils do } end - @spec get_reported_activities() :: [ + @spec get_grouped_reports() :: [ %{ - required(:activity) => String.t(), - required(:date) => String.t() + status: Activity.t(), + account: User.t(), + actors: [User.t()], + reports: [Activity.t()] } ] + def get_grouped_reports do + reports = Activity.flags_activities_query() |> Repo.all() + + flags = + Enum.map(reports, fn %{ + id: id, + actor: actor, + data: %{"object" => [account | statuses], "published" => date} + } -> + flag = %{ + report_id: id, + actor: actor, + account: account, + date: date + } + + Enum.map(statuses, fn + status when is_map(status) -> + Map.put(flag, :id, status["id"]) + + activity_id when is_binary(activity_id) -> + Map.put(flag, :id, activity_id) + end) + end) + + ids = %{accounts: [], actors: [], reports: []} + + {ids, groups} = + flags + |> List.flatten() + |> Enum.reduce({ids, %{}}, fn status, {ids, acc} -> + acc = + Map.update( + acc, + status.id, + %{ + account: status.account, + actors: [status.actor], + reports: [status.report_id], + date: status.date + }, + &update_reported_group(&1, status) + ) + + ids = + ids + |> Map.put(:accounts, [status.account | ids.accounts]) + |> Map.put(:actors, [status.actor | ids.actors]) + |> Map.put(:reports, [status.report_id | ids.reports]) + + {ids, acc} + end) + + loaded_activities = + groups + |> Map.keys() + |> Activity.all_by_ap_ids_with_object() + |> Enum.reduce(%{}, fn activity, acc -> + Map.put(acc, activity.data["id"], activity) + end) + + loaded_users = + (ids.accounts ++ ids.actors) + |> Enum.uniq() + |> User.get_all_by_ap_ids() + |> Enum.reduce(%{}, fn user, acc -> Map.put(acc, user.ap_id, user) end) + + loaded_reports = + reports + |> Enum.reduce(%{}, fn report, acc -> Map.put(acc, report.id, report) end) + + Enum.map(groups, fn {activity_id, group} -> + updated_actors = + group.actors + |> Enum.uniq() + |> Enum.map(&Map.get(loaded_users, &1)) + + updated_reports = + group.reports + |> Enum.uniq() + |> Enum.map(&Map.get(loaded_reports, &1)) + + group + |> Map.put( + :status, + Map.get(loaded_activities, activity_id, %{"id" => activity_id, "deleted" => true}) + ) + |> Map.put( + :account, + Map.get(loaded_users, group.account, %{"id" => group.account, "deleted" => true}) + ) + |> Map.put(:actors, updated_actors) + |> Map.put(:reports, updated_reports) + end) + end + + defp update_reported_group(group, status) do + if NaiveDateTime.compare( + NaiveDateTime.from_iso8601!(status.date), + NaiveDateTime.from_iso8601!(group.date) + ) == :gt do + Map.put(group, :date, status.date) + else + group + end + |> Map.put(:actors, [status.actor | group.actors]) + |> Map.put(:reports, [status.report_id | group.reports]) + end + + @spec get_reported_activities() :: [String.t()] def get_reported_activities do reported_activities_query = from(a in Activity, diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index 350c4391d..84b121ec6 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -61,6 +61,10 @@ defmodule Pleroma.Web.ActivityPub.UserView do |> Map.merge(Utils.make_json_ld_header()) end + def render("users.json", %{users: users}) do + render_many(users, Pleroma.Web.ActivityPub.UserView, "user.json") + end + # the instance itself is not a Person, but instead an Application def render("user.json", %{user: %User{nickname: nil} = user}), do: render("service.json", %{user: user}) diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index c95cd182d..245d820fe 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -670,6 +670,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do |> render("index_grouped.json", Utils.get_reports_grouped_by_status(statuses)) end + def list_grouped_reports_new(conn, _params) do + conn + |> put_view(ReportView) + |> render("index_grouped_new.json", %{groups: Utils.get_grouped_reports()}) + end + def report_show(conn, %{"id" => id}) do with %Activity{} = report <- Activity.get_by_id(id) do conn diff --git a/lib/pleroma/web/admin_api/views/report_view.ex b/lib/pleroma/web/admin_api/views/report_view.ex index 4880d2992..d27f1a21b 100644 --- a/lib/pleroma/web/admin_api/views/report_view.ex +++ b/lib/pleroma/web/admin_api/views/report_view.ex @@ -44,6 +44,42 @@ defmodule Pleroma.Web.AdminAPI.ReportView do } end + def render("index_grouped_new.json", %{groups: groups}) do + updated = + Enum.map(groups, fn report -> + status = + case report.status do + %Activity{} = activity -> StatusView.render("show.json", %{activity: activity}) + _ -> report.status + end + |> Map.put_new("deleted", false) + + report + |> Map.replace!( + :actors, + Enum.map(report[:actors], &merge_account_views/1) + ) + |> Map.replace!( + :account, + merge_account_views(report[:account]) + ) + |> Map.replace!( + :status, + status + ) + |> Map.replace!( + :reports, + report[:reports] + |> Enum.map(&Report.extract_report_info(&1)) + |> Enum.map(&render(__MODULE__, "show.json", &1)) + ) + end) + + %{ + reports: updated + } + end + def render("index_grouped.json", %{groups: groups}) do reports = Enum.map(groups, fn group -> diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 897215698..5b5facda8 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -184,7 +184,8 @@ defmodule Pleroma.Web.Router do patch("/users/resend_confirmation_email", AdminAPIController, :resend_confirmation_email) get("/reports", AdminAPIController, :list_reports) - get("/grouped_reports", AdminAPIController, :list_grouped_reports) + get("/grouped_reports", AdminAPIController, :list_grouped_reports_new) + get("/grouped_reports_new", AdminAPIController, :list_grouped_reports_new) get("/reports/:id", AdminAPIController, :report_show) patch("/reports", AdminAPIController, :reports_update) post("/reports/:id/notes", AdminAPIController, :report_notes_create) |