fix(mastodon-api): harden admin moderation actions

This commit is contained in:
Lain Soykaf 2026-07-26 13:24:03 +04:00
commit 458a15bf9f
No known key found for this signature in database
10 changed files with 344 additions and 31 deletions

View file

@ -1016,6 +1016,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_state(query, _), do: query defp restrict_state(query, _), do: query
defp restrict_report_target(query, %{report_target_id: actor_id}) do
from(activity in query,
where: fragment("?->'object'->>0 = ?", activity.data, ^actor_id)
)
end
defp restrict_report_target(query, _), do: query
defp restrict_assigned_account(query, %{assigned_account: assigned_account}) do defp restrict_assigned_account(query, %{assigned_account: assigned_account}) do
from(activity in query, from(activity in query,
where: fragment("?->>'assigned_account' = ?", activity.data, ^assigned_account) where: fragment("?->>'assigned_account' = ?", activity.data, ^assigned_account)
@ -1514,6 +1522,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|> restrict_actor(opts) |> restrict_actor(opts)
|> restrict_type(opts) |> restrict_type(opts)
|> restrict_state(opts) |> restrict_state(opts)
|> restrict_report_target(opts)
|> restrict_assigned_account(opts) |> restrict_assigned_account(opts)
|> restrict_favorited_by(opts) |> restrict_favorited_by(opts)
|> restrict_blocked(restrict_blocked_opts) |> restrict_blocked(restrict_blocked_opts)

View file

@ -216,20 +216,24 @@ defmodule Pleroma.Web.ApiSpec.MastodonAdmin.AccountOperation do
properties: %{ properties: %{
type: %Schema{ type: %Schema{
type: :string, type: :string,
enum: ["none", "disable", "sensitive", "silence", "suspend"] enum: ["none", "disable"]
}, },
report_id: %Schema{ report_id: %Schema{
type: :string, type: :string,
nullable: true, nullable: true,
description: "ID of an associated report that caused this action to be taken" description: "ID of an associated report that caused this action to be taken"
} }
} },
required: [:type]
}, },
required: true required: true
), ),
responses: %{ responses: %{
204 => no_content_response(), 204 => no_content_response(),
401 => Operation.response("Error", "application/json", ApiError) 400 => Operation.response("Error", "application/json", ApiError),
401 => Operation.response("Error", "application/json", ApiError),
403 => Operation.response("Error", "application/json", ApiError),
404 => Operation.response("Error", "application/json", ApiError)
} }
} }
end end

View file

@ -34,7 +34,7 @@ defmodule Pleroma.Web.ApiSpec.MastodonAdmin.ReportOperation do
:target_account_id, :target_account_id,
:query, :query,
:string, :string,
"Filter by report target account id (not implemented)" "Filter by report target account id"
) )
] ++ ] ++
pagination_params(), pagination_params(),
@ -81,7 +81,8 @@ defmodule Pleroma.Web.ApiSpec.MastodonAdmin.ReportOperation do
responses: %{ responses: %{
200 => Operation.response("Report", "application/json", report()), 200 => Operation.response("Report", "application/json", report()),
400 => Operation.response("Error", "application/json", ApiError), 400 => Operation.response("Error", "application/json", ApiError),
401 => Operation.response("Error", "application/json", ApiError) 401 => Operation.response("Error", "application/json", ApiError),
404 => Operation.response("Error", "application/json", ApiError)
} }
} }
end end
@ -99,11 +100,43 @@ defmodule Pleroma.Web.ApiSpec.MastodonAdmin.ReportOperation do
responses: %{ responses: %{
200 => Operation.response("Report", "application/json", report()), 200 => Operation.response("Report", "application/json", report()),
400 => Operation.response("Error", "application/json", ApiError), 400 => Operation.response("Error", "application/json", ApiError),
401 => Operation.response("Error", "application/json", ApiError) 401 => Operation.response("Error", "application/json", ApiError),
404 => Operation.response("Error", "application/json", ApiError)
} }
} }
end end
def assign_to_self_operation do
%Operation{
tags: ["Report management (Mastodon API)"],
summary: "Assign report to self",
operationId: "MastodonAdmin.ReportController.assign_to_self",
security: [%{"oAuth" => ["admin:write:reports"]}],
parameters: [Operation.parameter(:id, :path, :string, "ID of the report")],
responses: report_update_responses()
}
end
def unassign_operation do
%Operation{
tags: ["Report management (Mastodon API)"],
summary: "Unassign report",
operationId: "MastodonAdmin.ReportController.unassign",
security: [%{"oAuth" => ["admin:write:reports"]}],
parameters: [Operation.parameter(:id, :path, :string, "ID of the report")],
responses: report_update_responses()
}
end
defp report_update_responses do
%{
200 => Operation.response("Report", "application/json", report()),
400 => Operation.response("Error", "application/json", ApiError),
401 => Operation.response("Error", "application/json", ApiError),
404 => Operation.response("Error", "application/json", ApiError)
}
end
defp report do defp report do
%Schema{ %Schema{
title: "Admin::Report", title: "Admin::Report",
@ -112,7 +145,7 @@ defmodule Pleroma.Web.ApiSpec.MastodonAdmin.ReportOperation do
id: FlakeID, id: FlakeID,
action_taken: %Schema{type: :boolean}, action_taken: %Schema{type: :boolean},
action_taken_at: %Schema{type: :string, format: "date-time", nullable: true}, action_taken_at: %Schema{type: :string, format: "date-time", nullable: true},
category: %Schema{type: :string, enum: ["spam", "violation", "other"]}, category: %Schema{type: :string, enum: ["spam", "legal", "violation", "other"]},
comment: %Schema{type: :string, nullable: true}, comment: %Schema{type: :string, nullable: true},
forwarded: %Schema{type: :boolean, nullable: true}, forwarded: %Schema{type: :boolean, nullable: true},
created_at: %Schema{type: :string, format: "date-time"}, created_at: %Schema{type: :string, format: "date-time"},
@ -136,7 +169,7 @@ defmodule Pleroma.Web.ApiSpec.MastodonAdmin.ReportOperation do
items: %Schema{ items: %Schema{
type: :object, type: :object,
properties: %{ properties: %{
id: %Schema{type: :integer}, id: %Schema{type: :string},
text: %Schema{type: :string} text: %Schema{type: :string}
} }
} }

View file

@ -700,7 +700,7 @@ defmodule Pleroma.Web.CommonAPI do
end end
def update_report_state(activity_id, state) do def update_report_state(activity_id, state) do
with %Activity{} = activity <- Activity.get_by_id(activity_id, filter: []) do with %Activity{} = activity <- Activity.get_report(activity_id) do
Utils.update_report_state(activity, state) Utils.update_report_state(activity, state)
else else
nil -> {:error, :not_found} nil -> {:error, :not_found}
@ -715,7 +715,7 @@ defmodule Pleroma.Web.CommonAPI do
end end
def assign_report_to_account(activity_id, user) do def assign_report_to_account(activity_id, user) do
with %Activity{} = activity <- Activity.get_by_id(activity_id) do with %Activity{} = activity <- Activity.get_report(activity_id) do
Utils.assign_report_to_account(activity, user) Utils.assign_report_to_account(activity, user)
else else
nil -> {:error, :not_found} nil -> {:error, :not_found}

View file

@ -33,6 +33,8 @@ defmodule Pleroma.Web.MastodonAPI.Admin.AccountController do
when action in [:index, :index2, :show] when action in [:index, :index2, :show]
) )
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["admin:write:accounts"]} %{scopes: ["admin:write:accounts"]}
@ -92,11 +94,18 @@ defmodule Pleroma.Web.MastodonAPI.Admin.AccountController do
conn, conn,
_params _params
) do ) do
{:ok, _user} = handle_account_action(user, admin, type) with :ok <- validate_account_action(user, type),
{:ok, report} <- associated_report(user, body_params),
:ok <- resolve_report(admin, report),
{:ok, _user} <- handle_account_action(user, admin, type) do
json_response(conn, :no_content, "")
else
{:error, :not_found} ->
{:error, :not_found}
resolve_report(admin, body_params) {:error, error} ->
json_response(conn, :bad_request, %{error: error})
json_response(conn, :no_content, "") end
end end
def delete(%{assigns: %{user: admin, account: user}} = conn, _params) do def delete(%{assigns: %{user: admin, account: user}} = conn, _params) do
@ -161,10 +170,21 @@ defmodule Pleroma.Web.MastodonAPI.Admin.AccountController do
User.set_activation(user, false) User.set_activation(user, false)
end end
defp handle_account_action(user, _admin, _type) do defp handle_account_action(%User{}, _admin, "disable") do
{:error, "Only local accounts can be disabled"}
end
defp handle_account_action(user, _admin, "none") do
{:ok, user} {:ok, user}
end end
defp validate_account_action(%User{local: true}, "disable"), do: :ok
defp validate_account_action(%User{}, "disable"),
do: {:error, "Only local accounts can be disabled"}
defp validate_account_action(%User{}, "none"), do: :ok
defp build_criteria(params) do defp build_criteria(params) do
%{} %{}
|> maybe_filter_local(params) |> maybe_filter_local(params)
@ -251,7 +271,23 @@ defmodule Pleroma.Web.MastodonAPI.Admin.AccountController do
defp unquote(:"maybe_filter_#{filter_param}")(criteria, _params), do: criteria defp unquote(:"maybe_filter_#{filter_param}")(criteria, _params), do: criteria
end end
defp resolve_report(admin, %{report_id: id}) do defp associated_report(user, %{report_id: id}) do
case Activity.get_report(id) do
%Activity{data: %{"object" => [target_ap_id | _]}} = report
when target_ap_id == user.ap_id ->
{:ok, report}
%Activity{} ->
{:error, "Report does not target this account"}
nil ->
{:error, :not_found}
end
end
defp associated_report(_user, _params), do: {:ok, nil}
defp resolve_report(admin, %Activity{id: id}) do
with {:ok, activity} <- CommonAPI.update_report_state(id, "resolved"), with {:ok, activity} <- CommonAPI.update_report_state(id, "resolved"),
report <- Activity.get_by_id_with_user_actor(activity.id) do report <- Activity.get_by_id_with_user_actor(activity.id) do
ModerationLog.insert_log(%{ ModerationLog.insert_log(%{
@ -260,9 +296,10 @@ defmodule Pleroma.Web.MastodonAPI.Admin.AccountController do
subject: activity, subject: activity,
subject_actor: report.user_actor subject_actor: report.user_actor
}) })
:ok
end end
end end
defp resolve_report(_admin, _params) do defp resolve_report(_admin, nil), do: :ok
end
end end

View file

@ -26,6 +26,13 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportController do
plug(OAuthScopesPlug, %{scopes: ["admin:write:reports"]} when action in [:resolve, :reopen]) plug(OAuthScopesPlug, %{scopes: ["admin:write:reports"]} when action in [:resolve, :reopen])
plug(
OAuthScopesPlug,
%{scopes: ["admin:write:reports"]} when action in [:assign_to_self, :unassign]
)
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.MastodonAdmin.ReportOperation defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.MastodonAdmin.ReportOperation
def index(conn, params) do def index(conn, params) do
@ -37,6 +44,7 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportController do
|> Map.put(:total, true) |> Map.put(:total, true)
|> restrict_state(params) |> restrict_state(params)
|> restrict_actor(params) |> restrict_actor(params)
|> restrict_target(params)
reports = reports =
ActivityPub.fetch_activities_query([], opts) ActivityPub.fetch_activities_query([], opts)
@ -67,6 +75,9 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportController do
render(conn, "show.json", Report.extract_report_info(report)) render(conn, "show.json", Report.extract_report_info(report))
else else
{:error, :not_found} ->
{:error, :not_found}
{:error, error} -> {:error, error} ->
json_response(conn, :bad_request, %{error: error}) json_response(conn, :bad_request, %{error: error})
end end
@ -84,6 +95,9 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportController do
render(conn, "show.json", Report.extract_report_info(report)) render(conn, "show.json", Report.extract_report_info(report))
else else
{:error, :not_found} ->
{:error, :not_found}
{:error, error} -> {:error, error} ->
json_response(conn, :bad_request, %{error: error}) json_response(conn, :bad_request, %{error: error})
end end
@ -102,6 +116,9 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportController do
render(conn, "show.json", Report.extract_report_info(report)) render(conn, "show.json", Report.extract_report_info(report))
else else
{:error, :not_found} ->
{:error, :not_found}
{:error, error} -> {:error, error} ->
json_response(conn, :bad_request, %{error: error}) json_response(conn, :bad_request, %{error: error})
end end
@ -119,14 +136,17 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportController do
render(conn, "show.json", Report.extract_report_info(report)) render(conn, "show.json", Report.extract_report_info(report))
else else
{:error, :not_found} ->
{:error, :not_found}
{:error, error} -> {:error, error} ->
json_response(conn, :bad_request, %{error: error}) json_response(conn, :bad_request, %{error: error})
end end
end end
defp restrict_state(opts, %{resolved: true}), do: Map.put(opts, :state, "resolved") defp restrict_state(opts, %{resolved: true, unresolved: true}), do: opts
defp restrict_state(opts, %{resolved: _}), do: Map.put(opts, :state, "resolved") defp restrict_state(opts, %{resolved: true}), do: Map.put(opts, :state, "resolved")
defp restrict_state(opts, _params), do: Map.put(opts, :state, "open") defp restrict_state(opts, _params), do: Map.put(opts, :state, "open")
@ -139,4 +159,13 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportController do
end end
defp restrict_actor(opts, _params), do: opts defp restrict_actor(opts, _params), do: opts
defp restrict_target(opts, %{target_account_id: actor}) do
case User.get_by_id(actor) do
%User{ap_id: ap_id} -> Map.put(opts, :report_target_id, ap_id)
_ -> Map.put(opts, :report_target_id, actor)
end
end
defp restrict_target(opts, _params), do: opts
end end

View file

@ -6,6 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportView do
use Pleroma.Web, :view use Pleroma.Web, :view
alias Pleroma.HTML alias Pleroma.HTML
alias Pleroma.Rule
alias Pleroma.Web.AdminAPI.Report alias Pleroma.Web.AdminAPI.Report
alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI.Admin.AccountView alias Pleroma.Web.MastodonAPI.Admin.AccountView
@ -21,9 +22,12 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportView do
report: report, report: report,
user: account, user: account,
account: target_account, account: target_account,
statuses: statuses statuses: statuses,
assigned_account: assigned_account
}) do }) do
created_at = Utils.to_masto_date(report.data["published"]) created_at = Utils.to_masto_date(report.data["published"])
updated_at = Utils.to_masto_date(report.updated_at)
action_taken = report.data["state"] != "open"
content = content =
unless is_nil(report.data["content"]) do unless is_nil(report.data["content"]) do
@ -34,23 +38,34 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportView do
%{ %{
id: report.id, id: report.id,
action_taken: report.data["state"] != "open", action_taken: action_taken,
action_taken_at: nil, action_taken_at: if(action_taken, do: updated_at),
category: "other", category: "other",
comment: content, comment: content,
forwarded: nil, forwarded: false,
created_at: created_at, created_at: created_at,
updated_at: created_at, updated_at: updated_at,
account: AccountView.render("show.json", %{user: account}), account: AccountView.render("show.json", %{user: account}),
target_account: AccountView.render("show.json", %{user: target_account}), target_account: AccountView.render("show.json", %{user: target_account}),
assigned_account: nil, assigned_account: render_account(assigned_account),
action_taken_by_account: nil, action_taken_by_account: nil,
statuses: statuses:
StatusView.render("index.json", %{ StatusView.render("index.json", %{
activities: statuses, activities: statuses,
as: :activity as: :activity
}), }),
rules: [] rules: rules(report.data["rules"])
} }
end end
defp render_account(nil), do: nil
defp render_account(account), do: AccountView.render("show.json", %{user: account})
defp rules(nil), do: []
defp rules(rule_ids) do
rule_ids
|> Rule.get()
|> Enum.map(&%{id: to_string(&1.id), text: &1.text})
end
end end

View file

@ -137,6 +137,12 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Web.Plugs.EnsurePrivilegedPlug, :users_manage_activation_state) plug(Pleroma.Web.Plugs.EnsurePrivilegedPlug, :users_manage_activation_state)
end end
pipeline :require_privileged_role_account_actions do
plug(:admin_api)
plug(Pleroma.Web.Plugs.EnsurePrivilegedPlug, :users_manage_activation_state)
plug(Pleroma.Web.Plugs.EnsurePrivilegedPlug, :reports_manage_reports)
end
pipeline :require_privileged_role_users_manage_invites do pipeline :require_privileged_role_users_manage_invites do
plug(:admin_api) plug(:admin_api)
plug(Pleroma.Web.Plugs.EnsurePrivilegedPlug, :users_manage_invites) plug(Pleroma.Web.Plugs.EnsurePrivilegedPlug, :users_manage_invites)
@ -443,10 +449,15 @@ defmodule Pleroma.Web.Router do
scope "/api/v1/admin", Pleroma.Web.MastodonAPI.Admin do scope "/api/v1/admin", Pleroma.Web.MastodonAPI.Admin do
pipe_through([:require_privileged_role_users_manage_activation_state]) pipe_through([:require_privileged_role_users_manage_activation_state])
post("/accounts/:id/action", AccountController, :account_action)
post("/accounts/:id/enable", AccountController, :enable) post("/accounts/:id/enable", AccountController, :enable)
end end
scope "/api/v1/admin", Pleroma.Web.MastodonAPI.Admin do
pipe_through([:require_privileged_role_account_actions])
post("/accounts/:id/action", AccountController, :account_action)
end
# Mastodon AdminAPI: admins and mods (staff) can perform these actions (if privileged by role) # Mastodon AdminAPI: admins and mods (staff) can perform these actions (if privileged by role)
scope "/api/v1/admin", Pleroma.Web.MastodonAPI.Admin do scope "/api/v1/admin", Pleroma.Web.MastodonAPI.Admin do
pipe_through([:require_privileged_role_users_manage_invites]) pipe_through([:require_privileged_role_users_manage_invites])
@ -462,6 +473,8 @@ defmodule Pleroma.Web.Router do
get("/reports/:id", ReportController, :show) get("/reports/:id", ReportController, :show)
post("/reports/:id/resolve", ReportController, :resolve) post("/reports/:id/resolve", ReportController, :resolve)
post("/reports/:id/reopen", ReportController, :reopen) post("/reports/:id/reopen", ReportController, :reopen)
post("/reports/:id/assign_to_self", ReportController, :assign_to_self)
post("/reports/:id/unassign", ReportController, :unassign)
end end
# Mastodon AdminAPI: admins and mods (staff) can perform these actions (if privileged by role) # Mastodon AdminAPI: admins and mods (staff) can perform these actions (if privileged by role)

View file

@ -183,6 +183,20 @@ defmodule Pleroma.Web.MastodonAPI.Admin.AccountControllerTest do
assert %{is_active: false} = user assert %{is_active: false} = user
end end
test "does not disable a remote account", %{conn: conn} do
%{id: id} = user = insert(:user, local: false)
assert %{"error" => "Only local accounts can be disabled"} =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/admin/accounts/#{id}/action", %{
"type" => "disable"
})
|> json_response_and_validate_schema(400)
assert %{is_active: true} = Repo.reload!(user)
end
test "perform action with assigned report", %{conn: conn} do test "perform action with assigned report", %{conn: conn} do
[reporter, target_user] = insert_pair(:user) [reporter, target_user] = insert_pair(:user)
@ -191,11 +205,9 @@ defmodule Pleroma.Web.MastodonAPI.Admin.AccountControllerTest do
account_id: target_user.id account_id: target_user.id
}) })
%{id: id} = insert(:user)
conn conn
|> put_req_header("content-type", "application/json") |> put_req_header("content-type", "application/json")
|> post("/api/v1/admin/accounts/#{id}/action", %{ |> post("/api/v1/admin/accounts/#{target_user.id}/action", %{
"type" => "none", "type" => "none",
"report_id" => report_id "report_id" => report_id
}) })
@ -205,6 +217,56 @@ defmodule Pleroma.Web.MastodonAPI.Admin.AccountControllerTest do
assert %{data: %{"state" => "resolved"}} = report assert %{data: %{"state" => "resolved"}} = report
end end
test "requires the report management privilege", %{conn: conn} do
clear_config([:instance, :admin_privileges], [:users_manage_activation_state])
%{id: id} = insert(:user)
assert %{"error" => _} =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/admin/accounts/#{id}/action", %{"type" => "none"})
|> json_response(403)
end
test "does not resolve a report for another account", %{conn: conn} do
[reporter, target_user, other_user] = insert_list(3, :user)
{:ok, report} =
CommonAPI.report(reporter, %{
account_id: target_user.id
})
assert %{"error" => _} =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/admin/accounts/#{other_user.id}/action", %{
"type" => "none",
"report_id" => report.id
})
|> json_response_and_validate_schema(400)
assert %{data: %{"state" => "open"}} = Repo.reload!(report)
end
test "requires an action type", %{conn: conn} do
%{id: id} = insert(:user)
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/admin/accounts/#{id}/action", %{})
|> json_response_and_validate_schema(400)
end
test "rejects unsupported action types", %{conn: conn} do
%{id: id} = insert(:user)
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/admin/accounts/#{id}/action", %{"type" => "sensitive"})
|> json_response_and_validate_schema(400)
end
end end
describe "POST /api/v1/admin/accounts/:id/enable" do describe "POST /api/v1/admin/accounts/:id/enable" do

View file

@ -8,6 +8,9 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportControllerTest do
import Pleroma.Factory import Pleroma.Factory
alias Pleroma.Activity
alias Pleroma.Repo
alias Pleroma.Rule
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
setup_all do setup_all do
@ -58,6 +61,11 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportControllerTest do
|> get("/api/v1/admin/reports") |> get("/api/v1/admin/reports")
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)
assert [%{"id" => ^report_id1}] =
conn
|> get("/api/v1/admin/reports?resolved=false")
|> json_response_and_validate_schema(200)
assert [%{"id" => ^report_id2}, %{"id" => ^report_id1}] = assert [%{"id" => ^report_id2}, %{"id" => ^report_id1}] =
conn conn
|> get("/api/v1/admin/reports?resolved=true&unresolved=true") |> get("/api/v1/admin/reports?resolved=true&unresolved=true")
@ -68,6 +76,25 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportControllerTest do
|> get("/api/v1/admin/reports?resolved=true") |> get("/api/v1/admin/reports?resolved=true")
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)
end end
test "get reports by target account", %{conn: conn} do
[reporter, target_user, other_target] = insert_list(3, :user)
{:ok, %{id: report_id}} =
CommonAPI.report(reporter, %{
account_id: target_user.id
})
{:ok, _report} =
CommonAPI.report(reporter, %{
account_id: other_target.id
})
assert [%{"id" => ^report_id}] =
conn
|> get("/api/v1/admin/reports?target_account_id=#{target_user.id}")
|> json_response_and_validate_schema(200)
end
end end
describe "GET /api/v1/admin/reports/:id" do describe "GET /api/v1/admin/reports/:id" do
@ -86,6 +113,34 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportControllerTest do
|> get("/api/v1/admin/reports/#{report_id}") |> get("/api/v1/admin/reports/#{report_id}")
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)
end end
test "returns report rules", %{conn: conn} do
[reporter, target_user] = insert_pair(:user)
rule = Rule.create(%{text: "Be excellent to each other"})
{:ok, %{id: report_id}} =
CommonAPI.report(reporter, %{
account_id: target_user.id,
rule_ids: [rule.id]
})
assert %{
"rules" => [
%{"id" => rule_id, "text" => "Be excellent to each other"}
]
} =
conn
|> get("/api/v1/admin/reports/#{report_id}")
|> json_response_and_validate_schema(200)
assert rule_id == to_string(rule.id)
end
test "returns 404 for a missing report", %{conn: conn} do
conn
|> get("/api/v1/admin/reports/0")
|> json_response_and_validate_schema(404)
end
end end
describe "POST /api/v1/admin/reports/:id/resolve" do describe "POST /api/v1/admin/reports/:id/resolve" do
@ -104,6 +159,16 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportControllerTest do
|> post("/api/v1/admin/reports/#{report_id}/resolve") |> post("/api/v1/admin/reports/#{report_id}/resolve")
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)
end end
test "does not mutate a non-report activity", %{conn: conn} do
activity = insert(:note_activity)
conn
|> post("/api/v1/admin/reports/#{activity.id}/resolve")
|> json_response_and_validate_schema(404)
refute Repo.reload!(activity).data["state"]
end
end end
describe "POST /api/v1/admin/reports/:id/reopen" do describe "POST /api/v1/admin/reports/:id/reopen" do
@ -124,5 +189,51 @@ defmodule Pleroma.Web.MastodonAPI.Admin.ReportControllerTest do
|> post("/api/v1/admin/reports/#{report_id}/reopen") |> post("/api/v1/admin/reports/#{report_id}/reopen")
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)
end end
test "does not mutate a non-report activity", %{conn: conn} do
activity = insert(:note_activity)
conn
|> post("/api/v1/admin/reports/#{activity.id}/reopen")
|> json_response_and_validate_schema(404)
refute Repo.reload!(activity).data["state"]
end
end
describe "POST /api/v1/admin/reports/:id/assign_to_self" do
test "assign and unassign a report", %{admin: admin, conn: conn} do
[reporter, target_user] = insert_pair(:user)
{:ok, report} =
CommonAPI.report(reporter, %{
account_id: target_user.id
})
assert %{"assigned_account" => %{"id" => admin_id}} =
conn
|> post("/api/v1/admin/reports/#{report.id}/assign_to_self")
|> json_response_and_validate_schema(200)
assert admin_id == admin.id
assert Repo.reload!(report).data["assigned_account"] == admin.id
assert %{"assigned_account" => nil} =
conn
|> post("/api/v1/admin/reports/#{report.id}/unassign")
|> json_response_and_validate_schema(200)
refute Repo.reload!(report).data["assigned_account"]
end
test "does not assign a non-report activity", %{conn: conn} do
%Activity{id: id} = activity = insert(:note_activity)
conn
|> post("/api/v1/admin/reports/#{id}/assign_to_self")
|> json_response_and_validate_schema(404)
refute Repo.reload!(activity).data["assigned_account"]
end
end end
end end