Move report actions to AdminAPI.ReportController
This commit is contained in:
parent
18b050dfd1
commit
9d572f2f66
|
@ -7,28 +7,22 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
||||||
|
|
||||||
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
|
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
|
||||||
|
|
||||||
alias Pleroma.Activity
|
|
||||||
alias Pleroma.Config
|
alias Pleroma.Config
|
||||||
alias Pleroma.ConfigDB
|
alias Pleroma.ConfigDB
|
||||||
alias Pleroma.MFA
|
alias Pleroma.MFA
|
||||||
alias Pleroma.ModerationLog
|
alias Pleroma.ModerationLog
|
||||||
alias Pleroma.Plugs.OAuthScopesPlug
|
alias Pleroma.Plugs.OAuthScopesPlug
|
||||||
alias Pleroma.ReportNote
|
|
||||||
alias Pleroma.Stats
|
alias Pleroma.Stats
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Builder
|
alias Pleroma.Web.ActivityPub.Builder
|
||||||
alias Pleroma.Web.ActivityPub.Pipeline
|
alias Pleroma.Web.ActivityPub.Pipeline
|
||||||
alias Pleroma.Web.ActivityPub.Relay
|
alias Pleroma.Web.ActivityPub.Relay
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
|
||||||
alias Pleroma.Web.AdminAPI
|
alias Pleroma.Web.AdminAPI
|
||||||
alias Pleroma.Web.AdminAPI.AccountView
|
alias Pleroma.Web.AdminAPI.AccountView
|
||||||
alias Pleroma.Web.AdminAPI.ConfigView
|
alias Pleroma.Web.AdminAPI.ConfigView
|
||||||
alias Pleroma.Web.AdminAPI.ModerationLogView
|
alias Pleroma.Web.AdminAPI.ModerationLogView
|
||||||
alias Pleroma.Web.AdminAPI.Report
|
|
||||||
alias Pleroma.Web.AdminAPI.ReportView
|
|
||||||
alias Pleroma.Web.AdminAPI.Search
|
alias Pleroma.Web.AdminAPI.Search
|
||||||
alias Pleroma.Web.CommonAPI
|
|
||||||
alias Pleroma.Web.Endpoint
|
alias Pleroma.Web.Endpoint
|
||||||
alias Pleroma.Web.Router
|
alias Pleroma.Web.Router
|
||||||
|
|
||||||
|
@ -71,18 +65,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
||||||
when action in [:user_follow, :user_unfollow, :relay_follow, :relay_unfollow]
|
when action in [:user_follow, :user_unfollow, :relay_follow, :relay_unfollow]
|
||||||
)
|
)
|
||||||
|
|
||||||
plug(
|
|
||||||
OAuthScopesPlug,
|
|
||||||
%{scopes: ["read:reports"], admin: true}
|
|
||||||
when action in [:list_reports, :report_show]
|
|
||||||
)
|
|
||||||
|
|
||||||
plug(
|
|
||||||
OAuthScopesPlug,
|
|
||||||
%{scopes: ["write:reports"], admin: true}
|
|
||||||
when action in [:reports_update, :report_notes_create, :report_notes_delete]
|
|
||||||
)
|
|
||||||
|
|
||||||
plug(
|
plug(
|
||||||
OAuthScopesPlug,
|
OAuthScopesPlug,
|
||||||
%{scopes: ["read:statuses"], admin: true}
|
%{scopes: ["read:statuses"], admin: true}
|
||||||
|
@ -645,85 +627,6 @@ def update_user_credentials(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_reports(conn, params) do
|
|
||||||
{page, page_size} = page_params(params)
|
|
||||||
|
|
||||||
reports = Utils.get_reports(params, page, page_size)
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> put_view(ReportView)
|
|
||||||
|> render("index.json", %{reports: reports})
|
|
||||||
end
|
|
||||||
|
|
||||||
def report_show(conn, %{"id" => id}) do
|
|
||||||
with %Activity{} = report <- Activity.get_by_id(id) do
|
|
||||||
conn
|
|
||||||
|> put_view(ReportView)
|
|
||||||
|> render("show.json", Report.extract_report_info(report))
|
|
||||||
else
|
|
||||||
_ -> {:error, :not_found}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
def report_notes_create(%{assigns: %{user: user}} = conn, %{
|
|
||||||
"id" => report_id,
|
|
||||||
"content" => content
|
|
||||||
}) do
|
|
||||||
with {:ok, _} <- ReportNote.create(user.id, report_id, content) do
|
|
||||||
ModerationLog.insert_log(%{
|
|
||||||
action: "report_note",
|
|
||||||
actor: user,
|
|
||||||
subject: Activity.get_by_id(report_id),
|
|
||||||
text: content
|
|
||||||
})
|
|
||||||
|
|
||||||
json_response(conn, :no_content, "")
|
|
||||||
else
|
|
||||||
_ -> json_response(conn, :bad_request, "")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def report_notes_delete(%{assigns: %{user: user}} = conn, %{
|
|
||||||
"id" => note_id,
|
|
||||||
"report_id" => report_id
|
|
||||||
}) do
|
|
||||||
with {:ok, note} <- ReportNote.destroy(note_id) do
|
|
||||||
ModerationLog.insert_log(%{
|
|
||||||
action: "report_note_delete",
|
|
||||||
actor: user,
|
|
||||||
subject: Activity.get_by_id(report_id),
|
|
||||||
text: note.content
|
|
||||||
})
|
|
||||||
|
|
||||||
json_response(conn, :no_content, "")
|
|
||||||
else
|
|
||||||
_ -> json_response(conn, :bad_request, "")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_log(conn, params) do
|
def list_log(conn, params) do
|
||||||
{page, page_size} = page_params(params)
|
{page, page_size} = page_params(params)
|
||||||
|
|
||||||
|
|
129
lib/pleroma/web/admin_api/controllers/report_controller.ex
Normal file
129
lib/pleroma/web/admin_api/controllers/report_controller.ex
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.AdminAPI.ReportController do
|
||||||
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
|
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
|
||||||
|
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.ModerationLog
|
||||||
|
alias Pleroma.Plugs.OAuthScopesPlug
|
||||||
|
alias Pleroma.ReportNote
|
||||||
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
|
alias Pleroma.Web.AdminAPI
|
||||||
|
alias Pleroma.Web.AdminAPI.Report
|
||||||
|
alias Pleroma.Web.CommonAPI
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
|
||||||
|
@users_page_size 50
|
||||||
|
|
||||||
|
plug(OAuthScopesPlug, %{scopes: ["read:reports"], admin: true} when action in [:index, :show])
|
||||||
|
|
||||||
|
plug(
|
||||||
|
OAuthScopesPlug,
|
||||||
|
%{scopes: ["write:reports"], admin: true}
|
||||||
|
when action in [:update, :notes_create, :notes_delete]
|
||||||
|
)
|
||||||
|
|
||||||
|
action_fallback(AdminAPI.FallbackController)
|
||||||
|
|
||||||
|
def index(conn, params) do
|
||||||
|
{page, page_size} = page_params(params)
|
||||||
|
|
||||||
|
reports = Utils.get_reports(params, page, page_size)
|
||||||
|
|
||||||
|
render(conn, "index.json", reports: reports)
|
||||||
|
end
|
||||||
|
|
||||||
|
def show(conn, %{"id" => id}) do
|
||||||
|
with %Activity{} = report <- Activity.get_by_id(id) do
|
||||||
|
render(conn, "show.json", Report.extract_report_info(report))
|
||||||
|
else
|
||||||
|
_ -> {:error, :not_found}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def 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)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def notes_create(%{assigns: %{user: user}} = conn, %{
|
||||||
|
"id" => report_id,
|
||||||
|
"content" => content
|
||||||
|
}) do
|
||||||
|
with {:ok, _} <- ReportNote.create(user.id, report_id, content) do
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
action: "report_note",
|
||||||
|
actor: user,
|
||||||
|
subject: Activity.get_by_id(report_id),
|
||||||
|
text: content
|
||||||
|
})
|
||||||
|
|
||||||
|
json_response(conn, :no_content, "")
|
||||||
|
else
|
||||||
|
_ -> json_response(conn, :bad_request, "")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def notes_delete(%{assigns: %{user: user}} = conn, %{
|
||||||
|
"id" => note_id,
|
||||||
|
"report_id" => report_id
|
||||||
|
}) do
|
||||||
|
with {:ok, note} <- ReportNote.destroy(note_id) do
|
||||||
|
ModerationLog.insert_log(%{
|
||||||
|
action: "report_note_delete",
|
||||||
|
actor: user,
|
||||||
|
subject: Activity.get_by_id(report_id),
|
||||||
|
text: note.content
|
||||||
|
})
|
||||||
|
|
||||||
|
json_response(conn, :no_content, "")
|
||||||
|
else
|
||||||
|
_ -> json_response(conn, :bad_request, "")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp page_params(params) do
|
||||||
|
{get_page(params["page"]), get_page_size(params["page_size"])}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp get_page(page_string) when is_nil(page_string), do: 1
|
||||||
|
|
||||||
|
defp get_page(page_string) do
|
||||||
|
case Integer.parse(page_string) do
|
||||||
|
{page, _} -> page
|
||||||
|
:error -> 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp get_page_size(page_size_string) when is_nil(page_size_string), do: @users_page_size
|
||||||
|
|
||||||
|
defp get_page_size(page_size_string) do
|
||||||
|
case Integer.parse(page_size_string) do
|
||||||
|
{page_size, _} -> page_size
|
||||||
|
:error -> @users_page_size
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -183,11 +183,11 @@ defmodule Pleroma.Web.Router do
|
||||||
patch("/users/confirm_email", AdminAPIController, :confirm_email)
|
patch("/users/confirm_email", AdminAPIController, :confirm_email)
|
||||||
patch("/users/resend_confirmation_email", AdminAPIController, :resend_confirmation_email)
|
patch("/users/resend_confirmation_email", AdminAPIController, :resend_confirmation_email)
|
||||||
|
|
||||||
get("/reports", AdminAPIController, :list_reports)
|
get("/reports", ReportController, :index)
|
||||||
get("/reports/:id", AdminAPIController, :report_show)
|
get("/reports/:id", ReportController, :show)
|
||||||
patch("/reports", AdminAPIController, :reports_update)
|
patch("/reports", ReportController, :update)
|
||||||
post("/reports/:id/notes", AdminAPIController, :report_notes_create)
|
post("/reports/:id/notes", ReportController, :notes_create)
|
||||||
delete("/reports/:report_id/notes/:id", AdminAPIController, :report_notes_delete)
|
delete("/reports/:report_id/notes/:id", ReportController, :notes_delete)
|
||||||
|
|
||||||
get("/statuses/:id", StatusController, :show)
|
get("/statuses/:id", StatusController, :show)
|
||||||
put("/statuses/:id", StatusController, :update)
|
put("/statuses/:id", StatusController, :update)
|
||||||
|
|
|
@ -17,7 +17,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
||||||
alias Pleroma.MFA
|
alias Pleroma.MFA
|
||||||
alias Pleroma.ModerationLog
|
alias Pleroma.ModerationLog
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.ReportNote
|
|
||||||
alias Pleroma.Tests.ObanHelpers
|
alias Pleroma.Tests.ObanHelpers
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web
|
alias Pleroma.Web
|
||||||
|
@ -1198,286 +1197,6 @@ test "returns 404 if user not found", %{conn: conn} do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /api/pleroma/admin/reports/:id" do
|
|
||||||
test "returns report by its id", %{conn: conn} do
|
|
||||||
[reporter, target_user] = insert_pair(:user)
|
|
||||||
activity = insert(:note_activity, user: target_user)
|
|
||||||
|
|
||||||
{:ok, %{id: report_id}} =
|
|
||||||
CommonAPI.report(reporter, %{
|
|
||||||
account_id: target_user.id,
|
|
||||||
comment: "I feel offended",
|
|
||||||
status_ids: [activity.id]
|
|
||||||
})
|
|
||||||
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> get("/api/pleroma/admin/reports/#{report_id}")
|
|
||||||
|> json_response(:ok)
|
|
||||||
|
|
||||||
assert response["id"] == report_id
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns 404 when report id is invalid", %{conn: conn} do
|
|
||||||
conn = get(conn, "/api/pleroma/admin/reports/test")
|
|
||||||
|
|
||||||
assert json_response(conn, :not_found) == %{"error" => "Not found"}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "PATCH /api/pleroma/admin/reports" do
|
|
||||||
setup do
|
|
||||||
[reporter, target_user] = insert_pair(:user)
|
|
||||||
activity = insert(:note_activity, user: target_user)
|
|
||||||
|
|
||||||
{:ok, %{id: report_id}} =
|
|
||||||
CommonAPI.report(reporter, %{
|
|
||||||
account_id: target_user.id,
|
|
||||||
comment: "I feel offended",
|
|
||||||
status_ids: [activity.id]
|
|
||||||
})
|
|
||||||
|
|
||||||
{:ok, %{id: second_report_id}} =
|
|
||||||
CommonAPI.report(reporter, %{
|
|
||||||
account_id: target_user.id,
|
|
||||||
comment: "I feel very offended",
|
|
||||||
status_ids: [activity.id]
|
|
||||||
})
|
|
||||||
|
|
||||||
%{
|
|
||||||
id: report_id,
|
|
||||||
second_report_id: second_report_id
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "requires admin:write:reports scope", %{conn: conn, id: id, admin: admin} do
|
|
||||||
read_token = insert(:oauth_token, user: admin, scopes: ["admin:read"])
|
|
||||||
write_token = insert(:oauth_token, user: admin, scopes: ["admin:write:reports"])
|
|
||||||
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> assign(:token, read_token)
|
|
||||||
|> patch("/api/pleroma/admin/reports", %{
|
|
||||||
"reports" => [%{"state" => "resolved", "id" => id}]
|
|
||||||
})
|
|
||||||
|> json_response(403)
|
|
||||||
|
|
||||||
assert response == %{
|
|
||||||
"error" => "Insufficient permissions: admin:write:reports."
|
|
||||||
}
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> assign(:token, write_token)
|
|
||||||
|> patch("/api/pleroma/admin/reports", %{
|
|
||||||
"reports" => [%{"state" => "resolved", "id" => id}]
|
|
||||||
})
|
|
||||||
|> json_response(:no_content)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
|
|
||||||
conn
|
|
||||||
|> patch("/api/pleroma/admin/reports", %{
|
|
||||||
"reports" => [
|
|
||||||
%{"state" => "resolved", "id" => id}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|> json_response(:no_content)
|
|
||||||
|
|
||||||
activity = Activity.get_by_id(id)
|
|
||||||
assert activity.data["state"] == "resolved"
|
|
||||||
|
|
||||||
log_entry = Repo.one(ModerationLog)
|
|
||||||
|
|
||||||
assert ModerationLog.get_log_entry_message(log_entry) ==
|
|
||||||
"@#{admin.nickname} updated report ##{id} with 'resolved' state"
|
|
||||||
end
|
|
||||||
|
|
||||||
test "closes report", %{conn: conn, id: id, admin: admin} do
|
|
||||||
conn
|
|
||||||
|> patch("/api/pleroma/admin/reports", %{
|
|
||||||
"reports" => [
|
|
||||||
%{"state" => "closed", "id" => id}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|> json_response(:no_content)
|
|
||||||
|
|
||||||
activity = Activity.get_by_id(id)
|
|
||||||
assert activity.data["state"] == "closed"
|
|
||||||
|
|
||||||
log_entry = Repo.one(ModerationLog)
|
|
||||||
|
|
||||||
assert ModerationLog.get_log_entry_message(log_entry) ==
|
|
||||||
"@#{admin.nickname} updated report ##{id} with 'closed' state"
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns 400 when state is unknown", %{conn: conn, id: id} do
|
|
||||||
conn =
|
|
||||||
conn
|
|
||||||
|> patch("/api/pleroma/admin/reports", %{
|
|
||||||
"reports" => [
|
|
||||||
%{"state" => "test", "id" => id}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
assert hd(json_response(conn, :bad_request))["error"] == "Unsupported state"
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns 404 when report is not exist", %{conn: conn} do
|
|
||||||
conn =
|
|
||||||
conn
|
|
||||||
|> patch("/api/pleroma/admin/reports", %{
|
|
||||||
"reports" => [
|
|
||||||
%{"state" => "closed", "id" => "test"}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
describe "GET /api/pleroma/admin/reports" do
|
|
||||||
test "returns empty response when no reports created", %{conn: conn} do
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> get("/api/pleroma/admin/reports")
|
|
||||||
|> json_response(:ok)
|
|
||||||
|
|
||||||
assert Enum.empty?(response["reports"])
|
|
||||||
assert response["total"] == 0
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns reports", %{conn: conn} do
|
|
||||||
[reporter, target_user] = insert_pair(:user)
|
|
||||||
activity = insert(:note_activity, user: target_user)
|
|
||||||
|
|
||||||
{:ok, %{id: report_id}} =
|
|
||||||
CommonAPI.report(reporter, %{
|
|
||||||
account_id: target_user.id,
|
|
||||||
comment: "I feel offended",
|
|
||||||
status_ids: [activity.id]
|
|
||||||
})
|
|
||||||
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> get("/api/pleroma/admin/reports")
|
|
||||||
|> json_response(:ok)
|
|
||||||
|
|
||||||
[report] = response["reports"]
|
|
||||||
|
|
||||||
assert length(response["reports"]) == 1
|
|
||||||
assert report["id"] == report_id
|
|
||||||
|
|
||||||
assert response["total"] == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns reports with specified state", %{conn: conn} do
|
|
||||||
[reporter, target_user] = insert_pair(:user)
|
|
||||||
activity = insert(:note_activity, user: target_user)
|
|
||||||
|
|
||||||
{:ok, %{id: first_report_id}} =
|
|
||||||
CommonAPI.report(reporter, %{
|
|
||||||
account_id: target_user.id,
|
|
||||||
comment: "I feel offended",
|
|
||||||
status_ids: [activity.id]
|
|
||||||
})
|
|
||||||
|
|
||||||
{:ok, %{id: second_report_id}} =
|
|
||||||
CommonAPI.report(reporter, %{
|
|
||||||
account_id: target_user.id,
|
|
||||||
comment: "I don't like this user"
|
|
||||||
})
|
|
||||||
|
|
||||||
CommonAPI.update_report_state(second_report_id, "closed")
|
|
||||||
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> get("/api/pleroma/admin/reports", %{
|
|
||||||
"state" => "open"
|
|
||||||
})
|
|
||||||
|> json_response(:ok)
|
|
||||||
|
|
||||||
[open_report] = response["reports"]
|
|
||||||
|
|
||||||
assert length(response["reports"]) == 1
|
|
||||||
assert open_report["id"] == first_report_id
|
|
||||||
|
|
||||||
assert response["total"] == 1
|
|
||||||
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> get("/api/pleroma/admin/reports", %{
|
|
||||||
"state" => "closed"
|
|
||||||
})
|
|
||||||
|> json_response(:ok)
|
|
||||||
|
|
||||||
[closed_report] = response["reports"]
|
|
||||||
|
|
||||||
assert length(response["reports"]) == 1
|
|
||||||
assert closed_report["id"] == second_report_id
|
|
||||||
|
|
||||||
assert response["total"] == 1
|
|
||||||
|
|
||||||
response =
|
|
||||||
conn
|
|
||||||
|> get("/api/pleroma/admin/reports", %{
|
|
||||||
"state" => "resolved"
|
|
||||||
})
|
|
||||||
|> json_response(:ok)
|
|
||||||
|
|
||||||
assert Enum.empty?(response["reports"])
|
|
||||||
assert response["total"] == 0
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns 403 when requested by a non-admin" do
|
|
||||||
user = insert(:user)
|
|
||||||
token = insert(:oauth_token, user: user)
|
|
||||||
|
|
||||||
conn =
|
|
||||||
build_conn()
|
|
||||||
|> assign(:user, user)
|
|
||||||
|> assign(:token, token)
|
|
||||||
|> get("/api/pleroma/admin/reports")
|
|
||||||
|
|
||||||
assert json_response(conn, :forbidden) ==
|
|
||||||
%{"error" => "User is not an admin or OAuth admin scope is not granted."}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "returns 403 when requested by anonymous" do
|
|
||||||
conn = get(build_conn(), "/api/pleroma/admin/reports")
|
|
||||||
|
|
||||||
assert json_response(conn, :forbidden) == %{"error" => "Invalid credentials."}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "GET /api/pleroma/admin/config" do
|
describe "GET /api/pleroma/admin/config" do
|
||||||
setup do: clear_config(:configurable_from_database, true)
|
setup do: clear_config(:configurable_from_database, true)
|
||||||
|
|
||||||
|
@ -3195,66 +2914,6 @@ test "it resend emails for two users", %{conn: conn, admin: admin} do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "POST /reports/:id/notes" do
|
|
||||||
setup %{conn: conn, admin: admin} do
|
|
||||||
[reporter, target_user] = insert_pair(:user)
|
|
||||||
activity = insert(:note_activity, user: target_user)
|
|
||||||
|
|
||||||
{:ok, %{id: report_id}} =
|
|
||||||
CommonAPI.report(reporter, %{
|
|
||||||
account_id: target_user.id,
|
|
||||||
comment: "I feel offended",
|
|
||||||
status_ids: [activity.id]
|
|
||||||
})
|
|
||||||
|
|
||||||
post(conn, "/api/pleroma/admin/reports/#{report_id}/notes", %{
|
|
||||||
content: "this is disgusting!"
|
|
||||||
})
|
|
||||||
|
|
||||||
post(conn, "/api/pleroma/admin/reports/#{report_id}/notes", %{
|
|
||||||
content: "this is disgusting2!"
|
|
||||||
})
|
|
||||||
|
|
||||||
%{
|
|
||||||
admin_id: admin.id,
|
|
||||||
report_id: report_id
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it creates report note", %{admin_id: admin_id, report_id: report_id} do
|
|
||||||
[note, _] = Repo.all(ReportNote)
|
|
||||||
|
|
||||||
assert %{
|
|
||||||
activity_id: ^report_id,
|
|
||||||
content: "this is disgusting!",
|
|
||||||
user_id: ^admin_id
|
|
||||||
} = note
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it returns reports with notes", %{conn: conn, admin: admin} do
|
|
||||||
conn = get(conn, "/api/pleroma/admin/reports")
|
|
||||||
|
|
||||||
response = json_response(conn, 200)
|
|
||||||
notes = hd(response["reports"])["notes"]
|
|
||||||
[note, _] = notes
|
|
||||||
|
|
||||||
assert note["user"]["nickname"] == admin.nickname
|
|
||||||
assert note["content"] == "this is disgusting!"
|
|
||||||
assert note["created_at"]
|
|
||||||
assert response["total"] == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it deletes the note", %{conn: conn, report_id: report_id} do
|
|
||||||
assert ReportNote |> Repo.all() |> length() == 2
|
|
||||||
|
|
||||||
[note, _] = Repo.all(ReportNote)
|
|
||||||
|
|
||||||
delete(conn, "/api/pleroma/admin/reports/#{report_id}/notes/#{note.id}")
|
|
||||||
|
|
||||||
assert ReportNote |> Repo.all() |> length() == 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "GET /api/pleroma/admin/config/descriptions" do
|
describe "GET /api/pleroma/admin/config/descriptions" do
|
||||||
test "structure", %{conn: conn} do
|
test "structure", %{conn: conn} do
|
||||||
admin = insert(:user, is_admin: true)
|
admin = insert(:user, is_admin: true)
|
||||||
|
|
368
test/web/admin_api/controllers/report_controller_test.exs
Normal file
368
test/web/admin_api/controllers/report_controller_test.exs
Normal file
|
@ -0,0 +1,368 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
||||||
|
use Pleroma.Web.ConnCase
|
||||||
|
|
||||||
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Config
|
||||||
|
alias Pleroma.ModerationLog
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.ReportNote
|
||||||
|
alias Pleroma.Web.CommonAPI
|
||||||
|
|
||||||
|
setup do
|
||||||
|
admin = insert(:user, is_admin: true)
|
||||||
|
token = insert(:oauth_admin_token, user: admin)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
build_conn()
|
||||||
|
|> assign(:user, admin)
|
||||||
|
|> assign(:token, token)
|
||||||
|
|
||||||
|
{:ok, %{admin: admin, token: token, conn: conn}}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET /api/pleroma/admin/reports/:id" do
|
||||||
|
test "returns report by its id", %{conn: conn} do
|
||||||
|
[reporter, target_user] = insert_pair(:user)
|
||||||
|
activity = insert(:note_activity, user: target_user)
|
||||||
|
|
||||||
|
{:ok, %{id: report_id}} =
|
||||||
|
CommonAPI.report(reporter, %{
|
||||||
|
account_id: target_user.id,
|
||||||
|
comment: "I feel offended",
|
||||||
|
status_ids: [activity.id]
|
||||||
|
})
|
||||||
|
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> get("/api/pleroma/admin/reports/#{report_id}")
|
||||||
|
|> json_response(:ok)
|
||||||
|
|
||||||
|
assert response["id"] == report_id
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns 404 when report id is invalid", %{conn: conn} do
|
||||||
|
conn = get(conn, "/api/pleroma/admin/reports/test")
|
||||||
|
|
||||||
|
assert json_response(conn, :not_found) == %{"error" => "Not found"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "PATCH /api/pleroma/admin/reports" do
|
||||||
|
setup do
|
||||||
|
[reporter, target_user] = insert_pair(:user)
|
||||||
|
activity = insert(:note_activity, user: target_user)
|
||||||
|
|
||||||
|
{:ok, %{id: report_id}} =
|
||||||
|
CommonAPI.report(reporter, %{
|
||||||
|
account_id: target_user.id,
|
||||||
|
comment: "I feel offended",
|
||||||
|
status_ids: [activity.id]
|
||||||
|
})
|
||||||
|
|
||||||
|
{:ok, %{id: second_report_id}} =
|
||||||
|
CommonAPI.report(reporter, %{
|
||||||
|
account_id: target_user.id,
|
||||||
|
comment: "I feel very offended",
|
||||||
|
status_ids: [activity.id]
|
||||||
|
})
|
||||||
|
|
||||||
|
%{
|
||||||
|
id: report_id,
|
||||||
|
second_report_id: second_report_id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "requires admin:write:reports scope", %{conn: conn, id: id, admin: admin} do
|
||||||
|
read_token = insert(:oauth_token, user: admin, scopes: ["admin:read"])
|
||||||
|
write_token = insert(:oauth_token, user: admin, scopes: ["admin:write:reports"])
|
||||||
|
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> assign(:token, read_token)
|
||||||
|
|> patch("/api/pleroma/admin/reports", %{
|
||||||
|
"reports" => [%{"state" => "resolved", "id" => id}]
|
||||||
|
})
|
||||||
|
|> json_response(403)
|
||||||
|
|
||||||
|
assert response == %{
|
||||||
|
"error" => "Insufficient permissions: admin:write:reports."
|
||||||
|
}
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> assign(:token, write_token)
|
||||||
|
|> patch("/api/pleroma/admin/reports", %{
|
||||||
|
"reports" => [%{"state" => "resolved", "id" => id}]
|
||||||
|
})
|
||||||
|
|> json_response(:no_content)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
|
||||||
|
conn
|
||||||
|
|> patch("/api/pleroma/admin/reports", %{
|
||||||
|
"reports" => [
|
||||||
|
%{"state" => "resolved", "id" => id}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|> json_response(:no_content)
|
||||||
|
|
||||||
|
activity = Activity.get_by_id(id)
|
||||||
|
assert activity.data["state"] == "resolved"
|
||||||
|
|
||||||
|
log_entry = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||||
|
"@#{admin.nickname} updated report ##{id} with 'resolved' state"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "closes report", %{conn: conn, id: id, admin: admin} do
|
||||||
|
conn
|
||||||
|
|> patch("/api/pleroma/admin/reports", %{
|
||||||
|
"reports" => [
|
||||||
|
%{"state" => "closed", "id" => id}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|> json_response(:no_content)
|
||||||
|
|
||||||
|
activity = Activity.get_by_id(id)
|
||||||
|
assert activity.data["state"] == "closed"
|
||||||
|
|
||||||
|
log_entry = Repo.one(ModerationLog)
|
||||||
|
|
||||||
|
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||||
|
"@#{admin.nickname} updated report ##{id} with 'closed' state"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns 400 when state is unknown", %{conn: conn, id: id} do
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> patch("/api/pleroma/admin/reports", %{
|
||||||
|
"reports" => [
|
||||||
|
%{"state" => "test", "id" => id}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
assert hd(json_response(conn, :bad_request))["error"] == "Unsupported state"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns 404 when report is not exist", %{conn: conn} do
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> patch("/api/pleroma/admin/reports", %{
|
||||||
|
"reports" => [
|
||||||
|
%{"state" => "closed", "id" => "test"}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
describe "GET /api/pleroma/admin/reports" do
|
||||||
|
test "returns empty response when no reports created", %{conn: conn} do
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> get("/api/pleroma/admin/reports")
|
||||||
|
|> json_response(:ok)
|
||||||
|
|
||||||
|
assert Enum.empty?(response["reports"])
|
||||||
|
assert response["total"] == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns reports", %{conn: conn} do
|
||||||
|
[reporter, target_user] = insert_pair(:user)
|
||||||
|
activity = insert(:note_activity, user: target_user)
|
||||||
|
|
||||||
|
{:ok, %{id: report_id}} =
|
||||||
|
CommonAPI.report(reporter, %{
|
||||||
|
account_id: target_user.id,
|
||||||
|
comment: "I feel offended",
|
||||||
|
status_ids: [activity.id]
|
||||||
|
})
|
||||||
|
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> get("/api/pleroma/admin/reports")
|
||||||
|
|> json_response(:ok)
|
||||||
|
|
||||||
|
[report] = response["reports"]
|
||||||
|
|
||||||
|
assert length(response["reports"]) == 1
|
||||||
|
assert report["id"] == report_id
|
||||||
|
|
||||||
|
assert response["total"] == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns reports with specified state", %{conn: conn} do
|
||||||
|
[reporter, target_user] = insert_pair(:user)
|
||||||
|
activity = insert(:note_activity, user: target_user)
|
||||||
|
|
||||||
|
{:ok, %{id: first_report_id}} =
|
||||||
|
CommonAPI.report(reporter, %{
|
||||||
|
account_id: target_user.id,
|
||||||
|
comment: "I feel offended",
|
||||||
|
status_ids: [activity.id]
|
||||||
|
})
|
||||||
|
|
||||||
|
{:ok, %{id: second_report_id}} =
|
||||||
|
CommonAPI.report(reporter, %{
|
||||||
|
account_id: target_user.id,
|
||||||
|
comment: "I don't like this user"
|
||||||
|
})
|
||||||
|
|
||||||
|
CommonAPI.update_report_state(second_report_id, "closed")
|
||||||
|
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> get("/api/pleroma/admin/reports", %{
|
||||||
|
"state" => "open"
|
||||||
|
})
|
||||||
|
|> json_response(:ok)
|
||||||
|
|
||||||
|
[open_report] = response["reports"]
|
||||||
|
|
||||||
|
assert length(response["reports"]) == 1
|
||||||
|
assert open_report["id"] == first_report_id
|
||||||
|
|
||||||
|
assert response["total"] == 1
|
||||||
|
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> get("/api/pleroma/admin/reports", %{
|
||||||
|
"state" => "closed"
|
||||||
|
})
|
||||||
|
|> json_response(:ok)
|
||||||
|
|
||||||
|
[closed_report] = response["reports"]
|
||||||
|
|
||||||
|
assert length(response["reports"]) == 1
|
||||||
|
assert closed_report["id"] == second_report_id
|
||||||
|
|
||||||
|
assert response["total"] == 1
|
||||||
|
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> get("/api/pleroma/admin/reports", %{
|
||||||
|
"state" => "resolved"
|
||||||
|
})
|
||||||
|
|> json_response(:ok)
|
||||||
|
|
||||||
|
assert Enum.empty?(response["reports"])
|
||||||
|
assert response["total"] == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns 403 when requested by a non-admin" do
|
||||||
|
user = insert(:user)
|
||||||
|
token = insert(:oauth_token, user: user)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
build_conn()
|
||||||
|
|> assign(:user, user)
|
||||||
|
|> assign(:token, token)
|
||||||
|
|> get("/api/pleroma/admin/reports")
|
||||||
|
|
||||||
|
assert json_response(conn, :forbidden) ==
|
||||||
|
%{"error" => "User is not an admin or OAuth admin scope is not granted."}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns 403 when requested by anonymous" do
|
||||||
|
conn = get(build_conn(), "/api/pleroma/admin/reports")
|
||||||
|
|
||||||
|
assert json_response(conn, :forbidden) == %{"error" => "Invalid credentials."}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "POST /api/pleroma/admin/reports/:id/notes" do
|
||||||
|
setup %{conn: conn, admin: admin} do
|
||||||
|
[reporter, target_user] = insert_pair(:user)
|
||||||
|
activity = insert(:note_activity, user: target_user)
|
||||||
|
|
||||||
|
{:ok, %{id: report_id}} =
|
||||||
|
CommonAPI.report(reporter, %{
|
||||||
|
account_id: target_user.id,
|
||||||
|
comment: "I feel offended",
|
||||||
|
status_ids: [activity.id]
|
||||||
|
})
|
||||||
|
|
||||||
|
post(conn, "/api/pleroma/admin/reports/#{report_id}/notes", %{
|
||||||
|
content: "this is disgusting!"
|
||||||
|
})
|
||||||
|
|
||||||
|
post(conn, "/api/pleroma/admin/reports/#{report_id}/notes", %{
|
||||||
|
content: "this is disgusting2!"
|
||||||
|
})
|
||||||
|
|
||||||
|
%{
|
||||||
|
admin_id: admin.id,
|
||||||
|
report_id: report_id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it creates report note", %{admin_id: admin_id, report_id: report_id} do
|
||||||
|
[note, _] = Repo.all(ReportNote)
|
||||||
|
|
||||||
|
assert %{
|
||||||
|
activity_id: ^report_id,
|
||||||
|
content: "this is disgusting!",
|
||||||
|
user_id: ^admin_id
|
||||||
|
} = note
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it returns reports with notes", %{conn: conn, admin: admin} do
|
||||||
|
conn = get(conn, "/api/pleroma/admin/reports")
|
||||||
|
|
||||||
|
response = json_response(conn, 200)
|
||||||
|
notes = hd(response["reports"])["notes"]
|
||||||
|
[note, _] = notes
|
||||||
|
|
||||||
|
assert note["user"]["nickname"] == admin.nickname
|
||||||
|
assert note["content"] == "this is disgusting!"
|
||||||
|
assert note["created_at"]
|
||||||
|
assert response["total"] == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it deletes the note", %{conn: conn, report_id: report_id} do
|
||||||
|
assert ReportNote |> Repo.all() |> length() == 2
|
||||||
|
|
||||||
|
[note, _] = Repo.all(ReportNote)
|
||||||
|
|
||||||
|
delete(conn, "/api/pleroma/admin/reports/#{report_id}/notes/#{note.id}")
|
||||||
|
|
||||||
|
assert ReportNote |> Repo.all() |> length() == 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue