Browse Source

Admin API: Allow changing the state of multiple reports at once

fix/admin-api-grouped-reports-closed-reports
Maxim Filippov 4 years ago
parent
commit
8dcc2f9f5e
7 changed files with 142 additions and 27 deletions
  1. +1
    -0
      CHANGELOG.md
  2. +12
    -0
      lib/pleroma/web/activity_pub/utils.ex
  3. +19
    -10
      lib/pleroma/web/admin_api/admin_api_controller.ex
  4. +7
    -0
      lib/pleroma/web/common_api/common_api.ex
  5. +1
    -1
      lib/pleroma/web/router.ex
  6. +73
    -16
      test/web/admin_api/admin_api_controller_test.exs
  7. +29
    -0
      test/web/common_api/common_api_test.exs

+ 1
- 0
CHANGELOG.md View File

@@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed
- **Breaking:** Elixir >=1.8 is now required (was >= 1.7)
- **Breaking:** Admin API: Return link alongside with token on password reset
- **Breaking:** Admin API: Changing report state now uses `PATCH` (it was `PUT` before) and allows updating multiple reports at once (API changed)
- Replaced [pleroma_job_queue](https://git.pleroma.social/pleroma/pleroma_job_queue) and `Pleroma.Web.Federator.RetryQueue` with [Oban](https://github.com/sorentwo/oban) (see [`docs/config.md`](docs/config.md) on migrating customized worker / retry settings)
- Introduced [quantum](https://github.com/quantum-elixir/quantum-core) job scheduler
- Admin API: Return `total` when querying for reports


+ 12
- 0
lib/pleroma/web/activity_pub/utils.ex View File

@@ -672,6 +672,18 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|> Repo.update()
end

def update_report_state(activity_ids, state) when state in @supported_report_states do
activities_num = length(activity_ids)

from(a in Activity, where: a.id in ^activity_ids)
|> update(set: [data: fragment("jsonb_set(data, '{state}', ?)", ^state)])
|> Repo.update_all([])
|> case do
{^activities_num, _} -> :ok
_ -> {:error, activity_ids}
end
end

def update_report_state(_, _), do: {:error, "Unsupported state"}

def update_activity_visibility(activity, visibility) when visibility in @valid_visibilities do


+ 19
- 10
lib/pleroma/web/admin_api/admin_api_controller.ex View File

@@ -480,17 +480,26 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
end
end

def report_update_state(%{assigns: %{user: admin}} = conn, %{"id" => id, "state" => state}) do
with {:ok, report} <- CommonAPI.update_report_state(id, state) do
ModerationLog.insert_log(%{
action: "report_update",
actor: admin,
subject: report
})
def reports_update(%{assigns: %{user: admin}} = conn, %{"reports" => reports}) do
result =
reports
|> Enum.map(fn report ->
with {:ok, activity} <- CommonAPI.update_report_state(report["id"], report["state"]) do
ModerationLog.insert_log(%{
action: "report_update",
actor: admin,
subject: activity
})

activity
else
{:error, message} -> %{id: report["id"], error: message}
end
end)

conn
|> put_view(ReportView)
|> render("show.json", Report.extract_report_info(report))
case Enum.any?(result, &Map.has_key?(&1, :error)) do
true -> json_response(conn, :bad_request, result)
false -> json_response(conn, :no_content, "")
end
end



+ 7
- 0
lib/pleroma/web/common_api/common_api.ex View File

@@ -346,6 +346,13 @@ defmodule Pleroma.Web.CommonAPI do
end
end

def update_report_state(activity_ids, state) when is_list(activity_ids) do
case Utils.update_report_state(activity_ids, state) do
:ok -> {:ok, activity_ids}
_ -> {:error, dgettext("errors", "Could not update state")}
end
end

def update_report_state(activity_id, state) do
with %Activity{} = activity <- Activity.get_by_id(activity_id) do
Utils.update_report_state(activity, state)


+ 1
- 1
lib/pleroma/web/router.ex View File

@@ -194,7 +194,7 @@ defmodule Pleroma.Web.Router do

get("/reports", AdminAPIController, :list_reports)
get("/reports/:id", AdminAPIController, :report_show)
put("/reports/:id", AdminAPIController, :report_update_state)
patch("/reports", AdminAPIController, :reports_update)
post("/reports/:id/respond", AdminAPIController, :report_respond)

put("/statuses/:id", AdminAPIController, :status_update)


+ 73
- 16
test/web/admin_api/admin_api_controller_test.exs View File

@@ -1224,7 +1224,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
end

describe "PUT /api/pleroma/admin/reports/:id" do
describe "PATCH /api/pleroma/admin/reports" do
setup %{conn: conn} do
admin = insert(:user, info: %{is_admin: true})
[reporter, target_user] = insert_pair(:user)
@@ -1237,16 +1237,32 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"status_ids" => [activity.id]
})

%{conn: assign(conn, :user, admin), id: report_id, admin: admin}
{:ok, %{id: second_report_id}} =
CommonAPI.report(reporter, %{
"account_id" => target_user.id,
"comment" => "I feel very offended",
"status_ids" => [activity.id]
})

%{
conn: assign(conn, :user, admin),
id: report_id,
admin: admin,
second_report_id: second_report_id
}
end

test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
response =
conn
|> put("/api/pleroma/admin/reports/#{id}", %{"state" => "resolved"})
|> json_response(:ok)
conn
|> patch("/api/pleroma/admin/reports", %{
"reports" => [
%{"state" => "resolved", "id" => id}
]
})
|> json_response(:no_content)

assert response["state"] == "resolved"
activity = Activity.get_by_id(id)
assert activity.data["state"] == "resolved"

log_entry = Repo.one(ModerationLog)

@@ -1255,12 +1271,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end

test "closes report", %{conn: conn, id: id, admin: admin} do
response =
conn
|> put("/api/pleroma/admin/reports/#{id}", %{"state" => "closed"})
|> json_response(:ok)
conn
|> patch("/api/pleroma/admin/reports", %{
"reports" => [
%{"state" => "closed", "id" => id}
]
})
|> json_response(:no_content)

assert response["state"] == "closed"
activity = Activity.get_by_id(id)
assert activity.data["state"] == "closed"

log_entry = Repo.one(ModerationLog)

@@ -1271,17 +1291,54 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
test "returns 400 when state is unknown", %{conn: conn, id: id} do
conn =
conn
|> put("/api/pleroma/admin/reports/#{id}", %{"state" => "test"})
|> patch("/api/pleroma/admin/reports", %{
"reports" => [
%{"state" => "test", "id" => id}
]
})

assert json_response(conn, :bad_request) == "Unsupported state"
assert hd(json_response(conn, :bad_request))["error"] == "Unsupported state"
end

test "returns 404 when report is not exist", %{conn: conn} do
conn =
conn
|> put("/api/pleroma/admin/reports/test", %{"state" => "closed"})
|> patch("/api/pleroma/admin/reports", %{
"reports" => [
%{"state" => "closed", "id" => "test"}
]
})

assert json_response(conn, :not_found) == "Not found"
assert hd(json_response(conn, :bad_request))["error"] == "not_found"
end

test "updates state of multiple reports", %{
conn: conn,
id: id,
admin: admin,
second_report_id: second_report_id
} do
conn
|> patch("/api/pleroma/admin/reports", %{
"reports" => [
%{"state" => "resolved", "id" => id},
%{"state" => "closed", "id" => second_report_id}
]
})
|> json_response(:no_content)

activity = Activity.get_by_id(id)
second_activity = Activity.get_by_id(second_report_id)
assert activity.data["state"] == "resolved"
assert second_activity.data["state"] == "closed"

[first_log_entry, second_log_entry] = Repo.all(ModerationLog)

assert ModerationLog.get_log_entry_message(first_log_entry) ==
"@#{admin.nickname} updated report ##{id} with 'resolved' state"

assert ModerationLog.get_log_entry_message(second_log_entry) ==
"@#{admin.nickname} updated report ##{second_report_id} with 'closed' state"
end
end



+ 29
- 0
test/web/common_api/common_api_test.exs View File

@@ -423,6 +423,35 @@ defmodule Pleroma.Web.CommonAPITest do

assert CommonAPI.update_report_state(report_id, "test") == {:error, "Unsupported state"}
end

test "updates state of multiple reports" do
[reporter, target_user] = insert_pair(:user)
activity = insert(:note_activity, user: target_user)

{:ok, %Activity{id: first_report_id}} =
CommonAPI.report(reporter, %{
"account_id" => target_user.id,
"comment" => "I feel offended",
"status_ids" => [activity.id]
})

{:ok, %Activity{id: second_report_id}} =
CommonAPI.report(reporter, %{
"account_id" => target_user.id,
"comment" => "I feel very offended!",
"status_ids" => [activity.id]
})

{:ok, report_ids} =
CommonAPI.update_report_state([first_report_id, second_report_id], "resolved")

first_report = Activity.get_by_id(first_report_id)
second_report = Activity.get_by_id(second_report_id)

assert report_ids -- [first_report_id, second_report_id] == []
assert first_report.data["state"] == "resolved"
assert second_report.data["state"] == "resolved"
end
end

describe "reblog muting" do


Loading…
Cancel
Save