mirror of
https://git.pleroma.social/pleroma/pleroma.git
synced 2024-12-23 00:26:30 +00:00
Merge branch 'features/reports-enhancements' into 'develop'
Enhance reports in Pleroma API: index, show See merge request pleroma/pleroma!3280
This commit is contained in:
commit
4a9d3a1f28
6 changed files with 286 additions and 2 deletions
|
@ -136,11 +136,11 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp report_state do
|
def report_state do
|
||||||
%Schema{type: :string, enum: ["open", "closed", "resolved"]}
|
%Schema{type: :string, enum: ["open", "closed", "resolved"]}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp id_param do
|
def id_param do
|
||||||
Operation.parameter(:id, :path, FlakeID, "Report ID",
|
Operation.parameter(:id, :path, FlakeID, "Report ID",
|
||||||
example: "9umDrYheeY451cQnEe",
|
example: "9umDrYheeY451cQnEe",
|
||||||
required: true
|
required: true
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.ApiSpec.PleromaReportOperation do
|
||||||
|
alias OpenApiSpex.Operation
|
||||||
|
alias OpenApiSpex.Schema
|
||||||
|
alias Pleroma.Web.ApiSpec.Admin.ReportOperation
|
||||||
|
alias Pleroma.Web.ApiSpec.Schemas.Account
|
||||||
|
alias Pleroma.Web.ApiSpec.Schemas.ApiError
|
||||||
|
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
|
||||||
|
alias Pleroma.Web.ApiSpec.Schemas.Status
|
||||||
|
|
||||||
|
def open_api_operation(action) do
|
||||||
|
operation = String.to_existing_atom("#{action}_operation")
|
||||||
|
apply(__MODULE__, operation, [])
|
||||||
|
end
|
||||||
|
|
||||||
|
def index_operation do
|
||||||
|
%Operation{
|
||||||
|
tags: ["Reports"],
|
||||||
|
summary: "Get a list of your own reports",
|
||||||
|
operationId: "PleromaAPI.ReportController.index",
|
||||||
|
security: [%{"oAuth" => ["read:reports"]}],
|
||||||
|
parameters: [
|
||||||
|
Operation.parameter(
|
||||||
|
:state,
|
||||||
|
:query,
|
||||||
|
ReportOperation.report_state(),
|
||||||
|
"Filter by report state"
|
||||||
|
),
|
||||||
|
Operation.parameter(
|
||||||
|
:limit,
|
||||||
|
:query,
|
||||||
|
%Schema{type: :integer},
|
||||||
|
"The number of records to retrieve"
|
||||||
|
),
|
||||||
|
Operation.parameter(
|
||||||
|
:page,
|
||||||
|
:query,
|
||||||
|
%Schema{type: :integer, default: 1},
|
||||||
|
"Page number"
|
||||||
|
),
|
||||||
|
Operation.parameter(
|
||||||
|
:page_size,
|
||||||
|
:query,
|
||||||
|
%Schema{type: :integer, default: 50},
|
||||||
|
"Number number of log entries per page"
|
||||||
|
)
|
||||||
|
],
|
||||||
|
responses: %{
|
||||||
|
200 =>
|
||||||
|
Operation.response("Response", "application/json", %Schema{
|
||||||
|
type: :object,
|
||||||
|
properties: %{
|
||||||
|
total: %Schema{type: :integer},
|
||||||
|
reports: %Schema{
|
||||||
|
type: :array,
|
||||||
|
items: report()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_operation do
|
||||||
|
%Operation{
|
||||||
|
tags: ["Reports"],
|
||||||
|
summary: "Get an individual report",
|
||||||
|
operationId: "PleromaAPI.ReportController.show",
|
||||||
|
parameters: [ReportOperation.id_param()],
|
||||||
|
security: [%{"oAuth" => ["read:reports"]}],
|
||||||
|
responses: %{
|
||||||
|
200 => Operation.response("Report", "application/json", report()),
|
||||||
|
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Copied from ReportOperation.report with removing notes
|
||||||
|
defp report do
|
||||||
|
%Schema{
|
||||||
|
type: :object,
|
||||||
|
properties: %{
|
||||||
|
id: FlakeID,
|
||||||
|
state: ReportOperation.report_state(),
|
||||||
|
account: Account,
|
||||||
|
actor: Account,
|
||||||
|
content: %Schema{type: :string},
|
||||||
|
created_at: %Schema{type: :string, format: :"date-time"},
|
||||||
|
statuses: %Schema{type: :array, items: Status}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
46
lib/pleroma/web/pleroma_api/controllers/report_controller.ex
Normal file
46
lib/pleroma/web/pleroma_api/controllers/report_controller.ex
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.PleromaAPI.ReportController do
|
||||||
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
|
alias Pleroma.Web.AdminAPI.Report
|
||||||
|
|
||||||
|
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
|
||||||
|
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||||
|
plug(Pleroma.Web.Plugs.OAuthScopesPlug, %{scopes: ["read:reports"]})
|
||||||
|
|
||||||
|
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaReportOperation
|
||||||
|
|
||||||
|
@doc "GET /api/v0/pleroma/reports"
|
||||||
|
def index(%{assigns: %{user: user}, body_params: params} = conn, _) do
|
||||||
|
params =
|
||||||
|
params
|
||||||
|
|> Map.put(:actor_id, user.ap_id)
|
||||||
|
|
||||||
|
reports = Utils.get_reports(params, Map.get(params, :page, 1), Map.get(params, :size, 20))
|
||||||
|
|
||||||
|
render(conn, "index.json", %{reports: reports, for: user})
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc "GET /api/v0/pleroma/reports/:id"
|
||||||
|
def show(%{assigns: %{user: user}} = conn, %{id: id}) do
|
||||||
|
with %Activity{} = report <- Activity.get_report(id),
|
||||||
|
true <- report.actor == user.ap_id,
|
||||||
|
%{} = report_info <- Report.extract_report_info(report) do
|
||||||
|
render(conn, "show.json", Map.put(report_info, :for, user))
|
||||||
|
else
|
||||||
|
false ->
|
||||||
|
{:error, :not_found}
|
||||||
|
|
||||||
|
nil ->
|
||||||
|
{:error, :not_found}
|
||||||
|
|
||||||
|
e ->
|
||||||
|
{:error, inspect(e)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
55
lib/pleroma/web/pleroma_api/views/report_view.ex
Normal file
55
lib/pleroma/web/pleroma_api/views/report_view.ex
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.PleromaAPI.ReportView do
|
||||||
|
use Pleroma.Web, :view
|
||||||
|
|
||||||
|
alias Pleroma.HTML
|
||||||
|
alias Pleroma.Web.AdminAPI.Report
|
||||||
|
alias Pleroma.Web.CommonAPI.Utils
|
||||||
|
alias Pleroma.Web.MastodonAPI.AccountView
|
||||||
|
alias Pleroma.Web.MastodonAPI.StatusView
|
||||||
|
|
||||||
|
def render("index.json", %{reports: reports, for: for_user}) do
|
||||||
|
%{
|
||||||
|
reports:
|
||||||
|
reports[:items]
|
||||||
|
|> Enum.map(&Report.extract_report_info/1)
|
||||||
|
|> Enum.map(&render(__MODULE__, "show.json", Map.put(&1, :for, for_user))),
|
||||||
|
total: reports[:total]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def render("show.json", %{
|
||||||
|
report: report,
|
||||||
|
user: actor,
|
||||||
|
account: account,
|
||||||
|
statuses: statuses,
|
||||||
|
for: for_user
|
||||||
|
}) do
|
||||||
|
created_at = Utils.to_masto_date(report.data["published"])
|
||||||
|
|
||||||
|
content =
|
||||||
|
unless is_nil(report.data["content"]) do
|
||||||
|
HTML.filter_tags(report.data["content"])
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
%{
|
||||||
|
id: report.id,
|
||||||
|
account: AccountView.render("show.json", %{user: account, for: for_user}),
|
||||||
|
actor: AccountView.render("show.json", %{user: actor, for: for_user}),
|
||||||
|
content: content,
|
||||||
|
created_at: created_at,
|
||||||
|
statuses:
|
||||||
|
StatusView.render("index.json", %{
|
||||||
|
activities: statuses,
|
||||||
|
as: :activity,
|
||||||
|
for: for_user
|
||||||
|
}),
|
||||||
|
state: report.data["state"]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
|
@ -368,6 +368,12 @@ defmodule Pleroma.Web.Router do
|
||||||
get("/statuses/:id/reactions", EmojiReactionController, :index)
|
get("/statuses/:id/reactions", EmojiReactionController, :index)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scope "/api/v0/pleroma", Pleroma.Web.PleromaAPI do
|
||||||
|
pipe_through(:authenticated_api)
|
||||||
|
get("/reports", ReportController, :index)
|
||||||
|
get("/reports/:id", ReportController, :show)
|
||||||
|
end
|
||||||
|
|
||||||
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
|
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
|
||||||
scope [] do
|
scope [] do
|
||||||
pipe_through(:authenticated_api)
|
pipe_through(:authenticated_api)
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.PleromaAPI.ReportControllerTest do
|
||||||
|
use Pleroma.Web.ConnCase, async: true
|
||||||
|
|
||||||
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
alias Pleroma.Web.CommonAPI
|
||||||
|
|
||||||
|
describe "GET /api/v0/pleroma/reports" do
|
||||||
|
test "returns list of own reports" do
|
||||||
|
%{conn: reporter_conn, user: reporter} = oauth_access(["read:reports"])
|
||||||
|
%{conn: reported_conn, user: reported} = oauth_access(["read:reports"])
|
||||||
|
activity = insert(:note_activity, user: reported)
|
||||||
|
|
||||||
|
{:ok, %{id: report_id}} =
|
||||||
|
CommonAPI.report(reporter, %{
|
||||||
|
account_id: reported.id,
|
||||||
|
comment: "You stole my sandwich!",
|
||||||
|
status_ids: [activity.id]
|
||||||
|
})
|
||||||
|
|
||||||
|
assert reported_response =
|
||||||
|
reported_conn
|
||||||
|
|> get("/api/v0/pleroma/reports")
|
||||||
|
|> json_response_and_validate_schema(:ok)
|
||||||
|
|
||||||
|
assert reported_response == %{"reports" => [], "total" => 0}
|
||||||
|
|
||||||
|
assert reporter_response =
|
||||||
|
reporter_conn
|
||||||
|
|> get("/api/v0/pleroma/reports")
|
||||||
|
|> json_response_and_validate_schema(:ok)
|
||||||
|
|
||||||
|
assert %{"reports" => [report], "total" => 1} = reporter_response
|
||||||
|
assert report["id"] == report_id
|
||||||
|
refute report["notes"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET /api/v0/pleroma/reports/:id" do
|
||||||
|
test "returns report by its id" do
|
||||||
|
%{conn: reporter_conn, user: reporter} = oauth_access(["read:reports"])
|
||||||
|
%{conn: reported_conn, user: reported} = oauth_access(["read:reports"])
|
||||||
|
activity = insert(:note_activity, user: reported)
|
||||||
|
|
||||||
|
{:ok, %{id: report_id}} =
|
||||||
|
CommonAPI.report(reporter, %{
|
||||||
|
account_id: reported.id,
|
||||||
|
comment: "You stole my sandwich!",
|
||||||
|
status_ids: [activity.id]
|
||||||
|
})
|
||||||
|
|
||||||
|
assert reported_conn
|
||||||
|
|> get("/api/v0/pleroma/reports/#{report_id}")
|
||||||
|
|> json_response_and_validate_schema(:not_found)
|
||||||
|
|
||||||
|
assert response =
|
||||||
|
reporter_conn
|
||||||
|
|> get("/api/v0/pleroma/reports/#{report_id}")
|
||||||
|
|> json_response_and_validate_schema(:ok)
|
||||||
|
|
||||||
|
assert response["id"] == report_id
|
||||||
|
refute response["notes"]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns 404 when report id is invalid" do
|
||||||
|
%{conn: conn, user: _user} = oauth_access(["read:reports"])
|
||||||
|
|
||||||
|
assert response =
|
||||||
|
conn
|
||||||
|
|> get("/api/v0/pleroma/reports/0")
|
||||||
|
|> json_response_and_validate_schema(:not_found)
|
||||||
|
|
||||||
|
assert response == %{"error" => "Record not found"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue