Merge branch 'fix/mrf-delete' into 'develop'
ActivityPub: Fix deletes being exempt from MRF Closes #1461 See merge request pleroma/pleroma!2037
This commit is contained in:
commit
a280be34e3
|
@ -80,6 +80,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
### Fixed
|
### Fixed
|
||||||
- Report emails now include functional links to profiles of remote user accounts
|
- Report emails now include functional links to profiles of remote user accounts
|
||||||
- Not being able to log in to some third-party apps when logged in to MastoFE
|
- Not being able to log in to some third-party apps when logged in to MastoFE
|
||||||
|
- MRF: `Delete` activities being exempt from MRF policies
|
||||||
<details>
|
<details>
|
||||||
<summary>API Changes</summary>
|
<summary>API Changes</summary>
|
||||||
|
|
||||||
|
|
|
@ -241,9 +241,10 @@ def normalize(obj) when is_map(obj), do: get_by_ap_id_with_object(obj["id"])
|
||||||
def normalize(ap_id) when is_binary(ap_id), do: get_by_ap_id_with_object(ap_id)
|
def normalize(ap_id) when is_binary(ap_id), do: get_by_ap_id_with_object(ap_id)
|
||||||
def normalize(_), do: nil
|
def normalize(_), do: nil
|
||||||
|
|
||||||
def delete_by_ap_id(id) when is_binary(id) do
|
def delete_all_by_object_ap_id(id) when is_binary(id) do
|
||||||
id
|
id
|
||||||
|> Queries.by_object_id()
|
|> Queries.by_object_id()
|
||||||
|
|> Queries.exclude_type("Delete")
|
||||||
|> select([u], u)
|
|> select([u], u)
|
||||||
|> Repo.delete_all()
|
|> Repo.delete_all()
|
||||||
|> elem(1)
|
|> elem(1)
|
||||||
|
@ -255,7 +256,7 @@ def delete_by_ap_id(id) when is_binary(id) do
|
||||||
|> purge_web_resp_cache()
|
|> purge_web_resp_cache()
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_by_ap_id(_), do: nil
|
def delete_all_by_object_ap_id(_), do: nil
|
||||||
|
|
||||||
defp purge_web_resp_cache(%Activity{} = activity) do
|
defp purge_web_resp_cache(%Activity{} = activity) do
|
||||||
%{path: path} = URI.parse(activity.data["id"])
|
%{path: path} = URI.parse(activity.data["id"])
|
||||||
|
|
|
@ -64,4 +64,12 @@ def by_type(query \\ Activity, activity_type) do
|
||||||
where: fragment("(?)->>'type' = ?", activity.data, ^activity_type)
|
where: fragment("(?)->>'type' = ?", activity.data, ^activity_type)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec exclude_type(query, String.t()) :: query
|
||||||
|
def exclude_type(query \\ Activity, activity_type) do
|
||||||
|
from(
|
||||||
|
activity in query,
|
||||||
|
where: fragment("(?)->>'type' != ?", activity.data, ^activity_type)
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -147,7 +147,7 @@ def swap_object_with_tombstone(object) do
|
||||||
|
|
||||||
def delete(%Object{data: %{"id" => id}} = object) do
|
def delete(%Object{data: %{"id" => id}} = object) do
|
||||||
with {:ok, _obj} = swap_object_with_tombstone(object),
|
with {:ok, _obj} = swap_object_with_tombstone(object),
|
||||||
deleted_activity = Activity.delete_by_ap_id(id),
|
deleted_activity = Activity.delete_all_by_object_ap_id(id),
|
||||||
{:ok, true} <- Cachex.del(:object_cache, "object:#{id}"),
|
{:ok, true} <- Cachex.del(:object_cache, "object:#{id}"),
|
||||||
{:ok, _} <- Cachex.del(:web_resp_cache, URI.parse(id).path) do
|
{:ok, _} <- Cachex.del(:web_resp_cache, URI.parse(id).path) do
|
||||||
{:ok, object, deleted_activity}
|
{:ok, object, deleted_activity}
|
||||||
|
|
|
@ -456,17 +456,18 @@ def delete(%Object{data: %{"id" => id, "actor" => actor}} = object, options \\ [
|
||||||
user = User.get_cached_by_ap_id(actor)
|
user = User.get_cached_by_ap_id(actor)
|
||||||
to = (object.data["to"] || []) ++ (object.data["cc"] || [])
|
to = (object.data["to"] || []) ++ (object.data["cc"] || [])
|
||||||
|
|
||||||
with {:ok, object, activity} <- Object.delete(object),
|
with create_activity <- Activity.get_create_by_object_ap_id(id),
|
||||||
data <-
|
data <-
|
||||||
%{
|
%{
|
||||||
"type" => "Delete",
|
"type" => "Delete",
|
||||||
"actor" => actor,
|
"actor" => actor,
|
||||||
"object" => id,
|
"object" => id,
|
||||||
"to" => to,
|
"to" => to,
|
||||||
"deleted_activity_id" => activity && activity.id
|
"deleted_activity_id" => create_activity && create_activity.id
|
||||||
}
|
}
|
||||||
|> maybe_put("id", activity_id),
|
|> maybe_put("id", activity_id),
|
||||||
{:ok, activity} <- insert(data, local, false),
|
{:ok, activity} <- insert(data, local, false),
|
||||||
|
{:ok, object, _create_activity} <- Object.delete(object),
|
||||||
stream_out_participations(object, user),
|
stream_out_participations(object, user),
|
||||||
_ <- decrease_replies_count_if_reply(object),
|
_ <- decrease_replies_count_if_reply(object),
|
||||||
{:ok, _actor} <- decrease_note_count_if_public(user, object),
|
{:ok, _actor} <- decrease_note_count_if_public(user, object),
|
||||||
|
|
|
@ -298,7 +298,7 @@ test "cached purged after activity deletion", %{conn: conn} do
|
||||||
assert json_response(conn1, :ok)
|
assert json_response(conn1, :ok)
|
||||||
assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
|
assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
|
||||||
|
|
||||||
Activity.delete_by_ap_id(activity.object.data["id"])
|
Activity.delete_all_by_object_ap_id(activity.object.data["id"])
|
||||||
|
|
||||||
conn2 =
|
conn2 =
|
||||||
conn
|
conn
|
||||||
|
|
|
@ -1259,6 +1259,21 @@ test "decreases reply count" do
|
||||||
assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
|
assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
|
||||||
assert object.data["repliesCount"] == 0
|
assert object.data["repliesCount"] == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it passes delete activity through MRF before deleting the object" do
|
||||||
|
rewrite_policy = Pleroma.Config.get([:instance, :rewrite_policy])
|
||||||
|
Pleroma.Config.put([:instance, :rewrite_policy], Pleroma.Web.ActivityPub.MRF.DropPolicy)
|
||||||
|
|
||||||
|
on_exit(fn -> Pleroma.Config.put([:instance, :rewrite_policy], rewrite_policy) end)
|
||||||
|
|
||||||
|
note = insert(:note_activity)
|
||||||
|
object = Object.normalize(note)
|
||||||
|
|
||||||
|
{:error, {:reject, _}} = ActivityPub.delete(object)
|
||||||
|
|
||||||
|
assert Activity.get_by_id(note.id)
|
||||||
|
assert Repo.get(Object, object.id).data["type"] == object.data["type"]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "timeline post-processing" do
|
describe "timeline post-processing" do
|
||||||
|
|
Loading…
Reference in New Issue