CommonAPI: Fail when user sends report with posts not visible to them
This commit is contained in:
parent
a4e480a636
commit
2b76243ec8
6 changed files with 124 additions and 3 deletions
|
|
@ -24,7 +24,17 @@ defmodule Pleroma.Web.ApiSpec.ReportOperation do
|
||||||
requestBody: Helpers.request_body("Parameters", create_request(), required: true),
|
requestBody: Helpers.request_body("Parameters", create_request(), required: true),
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => Operation.response("Report", "application/json", create_response()),
|
200 => Operation.response("Report", "application/json", create_response()),
|
||||||
400 => Operation.response("Report", "application/json", ApiError)
|
400 => Operation.response("Report", "application/json", ApiError),
|
||||||
|
404 =>
|
||||||
|
Operation.response(
|
||||||
|
"Report",
|
||||||
|
"application/json",
|
||||||
|
%Schema{
|
||||||
|
allOf: [ApiError],
|
||||||
|
title: "Report",
|
||||||
|
example: %{"error" => "Record not found"}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -620,6 +620,7 @@ defmodule Pleroma.Web.CommonAPI do
|
||||||
with {:ok, account} <- get_reported_account(data.account_id),
|
with {:ok, account} <- get_reported_account(data.account_id),
|
||||||
{:ok, {content_html, _, _}} <- make_report_content_html(data[:comment]),
|
{:ok, {content_html, _, _}} <- make_report_content_html(data[:comment]),
|
||||||
{:ok, statuses} <- get_report_statuses(account, data),
|
{:ok, statuses} <- get_report_statuses(account, data),
|
||||||
|
true <- check_statuses_visibility(user, statuses),
|
||||||
rules <- get_report_rules(Map.get(data, :rule_ids, nil)) do
|
rules <- get_report_rules(Map.get(data, :rule_ids, nil)) do
|
||||||
ActivityPub.flag(%{
|
ActivityPub.flag(%{
|
||||||
context: Utils.generate_context_id(),
|
context: Utils.generate_context_id(),
|
||||||
|
|
@ -630,9 +631,27 @@ defmodule Pleroma.Web.CommonAPI do
|
||||||
forward: Map.get(data, :forward, false),
|
forward: Map.get(data, :forward, false),
|
||||||
rules: rules
|
rules: rules
|
||||||
})
|
})
|
||||||
|
else
|
||||||
|
false ->
|
||||||
|
{:error, :visibility}
|
||||||
|
|
||||||
|
error ->
|
||||||
|
error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp check_statuses_visibility(user, statuses) when is_list(statuses) do
|
||||||
|
visibility = for status <- statuses, do: Visibility.visible_for_user?(status, user)
|
||||||
|
|
||||||
|
case Enum.all?(visibility) do
|
||||||
|
true -> true
|
||||||
|
_ -> false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# There are no statuses associated with the report, pass!
|
||||||
|
defp check_statuses_visibility(_, status) when status == nil, do: true
|
||||||
|
|
||||||
defp get_reported_account(account_id) do
|
defp get_reported_account(account_id) do
|
||||||
case User.get_cached_by_id(account_id) do
|
case User.get_cached_by_id(account_id) do
|
||||||
%User{} = account -> {:ok, account}
|
%User{} = account -> {:ok, account}
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
|
||||||
# TODO: Fix this quirk in FE and remove here and other affected places
|
# TODO: Fix this quirk in FE and remove here and other affected places
|
||||||
with %Activity{} = activity <- Activity.get_by_id(id),
|
with %Activity{} = activity <- Activity.get_by_id(id),
|
||||||
true <- Visibility.visible_for_user?(activity, draft.user),
|
true <- Visibility.visible_for_user?(activity, draft.user),
|
||||||
{:type, type} when type in ["Create", "Announce"] <- {:type, activity.data["type"]} do
|
{_, type} when type in ["Create", "Announce"] <- {:type, activity.data["type"]} do
|
||||||
%__MODULE__{draft | in_reply_to: activity}
|
%__MODULE__{draft | in_reply_to: activity}
|
||||||
else
|
else
|
||||||
nil ->
|
nil ->
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,12 @@ defmodule Pleroma.Web.MastodonAPI.ReportController do
|
||||||
def create(%{assigns: %{user: user}, body_params: params} = conn, _) do
|
def create(%{assigns: %{user: user}, body_params: params} = conn, _) do
|
||||||
with {:ok, activity} <- Pleroma.Web.CommonAPI.report(user, params) do
|
with {:ok, activity} <- Pleroma.Web.CommonAPI.report(user, params) do
|
||||||
render(conn, "show.json", activity: activity)
|
render(conn, "show.json", activity: activity)
|
||||||
|
else
|
||||||
|
{:error, :visibility} ->
|
||||||
|
{:error, :not_found, "Record not found"}
|
||||||
|
|
||||||
|
error ->
|
||||||
|
error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1286,6 +1286,47 @@ defmodule Pleroma.Web.CommonAPITest do
|
||||||
} = flag_activity
|
} = flag_activity
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "doesn't create a report when post is not visible to user" do
|
||||||
|
reporter = insert(:user)
|
||||||
|
target_user = insert(:user)
|
||||||
|
{:ok, post} = CommonAPI.post(target_user, %{status: "Eric", visibility: "private"})
|
||||||
|
|
||||||
|
assert Pleroma.Web.ActivityPub.Visibility.private?(post)
|
||||||
|
refute Pleroma.Web.ActivityPub.Visibility.visible_for_user?(post, reporter)
|
||||||
|
|
||||||
|
# Fails when all status are invisible
|
||||||
|
report_data = %{
|
||||||
|
account_id: target_user.id,
|
||||||
|
comment: "foobar",
|
||||||
|
status_ids: [post.id]
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {:error, :visibility} = CommonAPI.report(reporter, report_data)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "doesn't create a report when some posts are not visible to user" do
|
||||||
|
reporter = insert(:user)
|
||||||
|
target_user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, visible_activity} = CommonAPI.post(target_user, %{status: "cofe"})
|
||||||
|
|
||||||
|
{:ok, invisibile_activity} =
|
||||||
|
CommonAPI.post(target_user, %{status: "cawfee", visibility: "private"})
|
||||||
|
|
||||||
|
assert Pleroma.Web.ActivityPub.Visibility.private?(invisibile_activity)
|
||||||
|
assert Pleroma.Web.ActivityPub.Visibility.public?(visible_activity)
|
||||||
|
refute Pleroma.Web.ActivityPub.Visibility.visible_for_user?(invisibile_activity, reporter)
|
||||||
|
|
||||||
|
# Fails when some statuses are invisible
|
||||||
|
report_data_partial = %{
|
||||||
|
account_id: target_user.id,
|
||||||
|
comment: "foobar",
|
||||||
|
status_ids: [visible_activity.id, invisibile_activity.id]
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {:error, :visibility} = CommonAPI.report(reporter, report_data_partial)
|
||||||
|
end
|
||||||
|
|
||||||
test "updates report state" do
|
test "updates report state" do
|
||||||
[reporter, target_user] = insert_pair(:user)
|
[reporter, target_user] = insert_pair(:user)
|
||||||
activity = insert(:note_activity, user: target_user)
|
activity = insert(:note_activity, user: target_user)
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
|
||||||
|> json_response_and_validate_schema(400)
|
|> json_response_and_validate_schema(400)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns error when account is not exist", %{
|
test "returns error when account does not exist", %{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
activity: activity
|
activity: activity
|
||||||
} do
|
} do
|
||||||
|
|
@ -159,6 +159,51 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
|
||||||
assert json_response_and_validate_schema(conn, 400) == %{"error" => "Account not found"}
|
assert json_response_and_validate_schema(conn, 400) == %{"error" => "Account not found"}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "returns not found when post isn't visible to reporter", %{user: target_user} do
|
||||||
|
%{conn: conn, user: reporter} = oauth_access(["write:reports"])
|
||||||
|
|
||||||
|
{:ok, invisible_activity} =
|
||||||
|
CommonAPI.post(target_user, %{status: "Invisible!", visibility: "private"})
|
||||||
|
|
||||||
|
assert Pleroma.Web.ActivityPub.Visibility.private?(invisible_activity)
|
||||||
|
refute Pleroma.Web.ActivityPub.Visibility.visible_for_user?(invisible_activity, reporter)
|
||||||
|
|
||||||
|
assert %{"error" => "Record not found"} =
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> post(
|
||||||
|
"/api/v1/reports",
|
||||||
|
%{"account_id" => target_user.id, "status_ids" => [invisible_activity.id]}
|
||||||
|
)
|
||||||
|
|> json_response_and_validate_schema(404)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns not found when some post aren't visible to reporter", %{
|
||||||
|
activity: activity,
|
||||||
|
user: target_user
|
||||||
|
} do
|
||||||
|
%{conn: conn, user: reporter} = oauth_access(["write:reports"])
|
||||||
|
|
||||||
|
{:ok, invisible_activity} =
|
||||||
|
CommonAPI.post(target_user, %{status: "Invisible!", visibility: "private"})
|
||||||
|
|
||||||
|
assert Pleroma.Web.ActivityPub.Visibility.private?(invisible_activity)
|
||||||
|
assert Pleroma.Web.ActivityPub.Visibility.visible_for_user?(activity, reporter)
|
||||||
|
refute Pleroma.Web.ActivityPub.Visibility.visible_for_user?(invisible_activity, reporter)
|
||||||
|
|
||||||
|
assert %{"error" => "Record not found"} =
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> post(
|
||||||
|
"/api/v1/reports",
|
||||||
|
%{
|
||||||
|
"account_id" => target_user.id,
|
||||||
|
"status_ids" => [activity.id, invisible_activity.id]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|> json_response_and_validate_schema(404)
|
||||||
|
end
|
||||||
|
|
||||||
test "doesn't fail if an admin has no email", %{conn: conn, target_user: target_user} do
|
test "doesn't fail if an admin has no email", %{conn: conn, target_user: target_user} do
|
||||||
insert(:user, %{is_admin: true, email: nil})
|
insert(:user, %{is_admin: true, email: nil})
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue