Strip status data from Flag (when federating or closing/resolving report)

This commit is contained in:
Maxim Filippov 2019-10-27 16:05:32 +03:00
parent b08b1d5d91
commit 8eff05d4c6
5 changed files with 119 additions and 35 deletions

View file

@ -30,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- MRF (Simple Policy): Also use `:accept`/`:reject` on the actors rather than only their activities - MRF (Simple Policy): Also use `:accept`/`:reject` on the actors rather than only their activities
- OStatus: Extract RSS functionality - OStatus: Extract RSS functionality
- Mastodon API: Add `pleroma.direct_conversation_id` to the status endpoint (`GET /api/v1/statuses/:id`) - Mastodon API: Add `pleroma.direct_conversation_id` to the status endpoint (`GET /api/v1/statuses/:id`)
- Store status data inside Flag activity
### Fixed ### Fixed
- Mastodon API: Fix private and direct statuses not being filtered out from the public timeline for an authenticated user (`GET /api/v1/timelines/public`) - Mastodon API: Fix private and direct statuses not being filtered out from the public timeline for an authenticated user (`GET /api/v1/timelines/public`)

View file

@ -491,7 +491,8 @@ def flag(
with flag_data <- make_flag_data(params, additional), with flag_data <- make_flag_data(params, additional),
{:ok, activity} <- insert(flag_data, local), {:ok, activity} <- insert(flag_data, local),
:ok <- maybe_federate(activity) do {:ok, stripped_activity} <- strip_report_status_data(activity),
:ok <- maybe_federate(stripped_activity) do
Enum.each(User.all_superusers(), fn superuser -> Enum.each(User.all_superusers(), fn superuser ->
superuser superuser
|> Pleroma.Emails.AdminEmail.report(actor, account, statuses, content) |> Pleroma.Emails.AdminEmail.report(actor, account, statuses, content)

View file

@ -22,6 +22,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
require Pleroma.Constants require Pleroma.Constants
@supported_object_types ["Article", "Note", "Video", "Page", "Question", "Answer", "Audio"] @supported_object_types ["Article", "Note", "Video", "Page", "Question", "Answer", "Audio"]
@strip_status_report_states ~w(closed resolved)
@supported_report_states ~w(open closed resolved) @supported_report_states ~w(open closed resolved)
@valid_visibilities ~w(public unlisted private direct) @valid_visibilities ~w(public unlisted private direct)
@ -673,6 +674,20 @@ def fetch_ordered_collection(from, pages_left, acc \\ []) do
#### Report-related helpers #### Report-related helpers
def update_report_state(%Activity{} = activity, state)
when state in @strip_status_report_states do
{:ok, stripped_activity} = strip_report_status_data(activity)
new_data =
activity.data
|> Map.put("state", state)
|> Map.put("object", stripped_activity.data["object"])
activity
|> Changeset.change(data: new_data)
|> Repo.update()
end
def update_report_state(%Activity{} = activity, state) when state in @supported_report_states do def update_report_state(%Activity{} = activity, state) when state in @supported_report_states do
new_data = Map.put(activity.data, "state", state) new_data = Map.put(activity.data, "state", state)
@ -683,6 +698,14 @@ def update_report_state(%Activity{} = activity, state) when state in @supported_
def update_report_state(_, _), do: {:error, "Unsupported state"} def update_report_state(_, _), do: {:error, "Unsupported state"}
def strip_report_status_data(activity) do
[actor | reported_activities] = activity.data["object"]
stripped_activities = Enum.map(reported_activities, & &1["id"])
new_data = put_in(activity.data, ["object"], [actor | stripped_activities])
{:ok, %{activity | data: new_data}}
end
def update_activity_visibility(activity, visibility) when visibility in @valid_visibilities do def update_activity_visibility(activity, visibility) when visibility in @valid_visibilities do
[to, cc, recipients] = [to, cc, recipients] =
activity activity

View file

@ -1255,45 +1255,99 @@ test "returned pinned statuses" do
assert 3 = length(activities) assert 3 = length(activities)
end end
test "it can create a Flag activity" do describe "flag/1" do
reporter = insert(:user) setup do
target_account = insert(:user) reporter = insert(:user)
{:ok, activity} = CommonAPI.post(target_account, %{"status" => "foobar"}) target_account = insert(:user)
context = Utils.generate_context_id() content = "foobar"
content = "foobar" {:ok, activity} = CommonAPI.post(target_account, %{"status" => content})
context = Utils.generate_context_id()
reporter_ap_id = reporter.ap_id reporter_ap_id = reporter.ap_id
target_ap_id = target_account.ap_id target_ap_id = target_account.ap_id
activity_ap_id = activity.data["id"] activity_ap_id = activity.data["id"]
activity_with_object = Activity.get_by_ap_id_with_object(activity_ap_id) activity_with_object = Activity.get_by_ap_id_with_object(activity_ap_id)
assert {:ok, activity} = {:ok,
ActivityPub.flag(%{ %{
actor: reporter, reporter: reporter,
context: context, context: context,
account: target_account, target_account: target_account,
statuses: [activity], reported_activity: activity,
content: content content: content,
}) activity_ap_id: activity_ap_id,
activity_with_object: activity_with_object,
reporter_ap_id: reporter_ap_id,
target_ap_id: target_ap_id
}}
end
note_obj = %{ test "it can create a Flag activity",
"type" => "Note", %{
"id" => activity_ap_id, reporter: reporter,
"content" => content, context: context,
"published" => activity_with_object.object.data["published"], target_account: target_account,
"actor" => AccountView.render("show.json", %{user: target_account}) reported_activity: reported_activity,
} content: content,
activity_ap_id: activity_ap_id,
activity_with_object: activity_with_object,
reporter_ap_id: reporter_ap_id,
target_ap_id: target_ap_id
} do
assert {:ok, activity} =
ActivityPub.flag(%{
actor: reporter,
context: context,
account: target_account,
statuses: [reported_activity],
content: content
})
assert %Activity{ note_obj = %{
actor: ^reporter_ap_id, "type" => "Note",
data: %{ "id" => activity_ap_id,
"type" => "Flag", "content" => content,
"content" => ^content, "published" => activity_with_object.object.data["published"],
"context" => ^context, "actor" => AccountView.render("show.json", %{user: target_account})
"object" => [^target_ap_id, ^note_obj] }
}
} = activity assert %Activity{
actor: ^reporter_ap_id,
data: %{
"type" => "Flag",
"content" => ^content,
"context" => ^context,
"object" => [^target_ap_id, ^note_obj]
}
} = activity
end
test_with_mock "strips status data from Flag, before federating it",
%{
reporter: reporter,
context: context,
target_account: target_account,
reported_activity: reported_activity,
content: content
},
Utils,
[:passthrough],
[] do
{:ok, activity} =
ActivityPub.flag(%{
actor: reporter,
context: context,
account: target_account,
statuses: [reported_activity],
content: content
})
new_data =
put_in(activity.data, ["object"], [target_account.ap_id, reported_activity.data["id"]])
assert_called(Utils.maybe_federate(%{activity | data: new_data}))
end
end end
test "fetch_activities/2 returns activities addressed to a list " do test "fetch_activities/2 returns activities addressed to a list " do

View file

@ -421,6 +421,11 @@ test "updates report state" do
{:ok, report} = CommonAPI.update_report_state(report_id, "resolved") {:ok, report} = CommonAPI.update_report_state(report_id, "resolved")
assert report.data["state"] == "resolved" assert report.data["state"] == "resolved"
[reported_user, activity_id] = report.data["object"]
assert reported_user == target_user.ap_id
assert activity_id == activity.data["id"]
end end
test "does not update report state when state is unsupported" do test "does not update report state when state is unsupported" do