Make EnsureRePrepended history-aware
This commit is contained in:
parent
593df1413c
commit
088951b65a
5 changed files with 102 additions and 7 deletions
|
@ -198,7 +198,7 @@ def make_new_object_data_from_update_object(original_data, new_data) do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp for_each_history_item(%{"orderedItems" => items} = history, _object, fun) do
|
def for_each_history_item(%{"orderedItems" => items} = history, _object, fun) do
|
||||||
new_items =
|
new_items =
|
||||||
Enum.map(items, fun)
|
Enum.map(items, fun)
|
||||||
|> Enum.reduce_while(
|
|> Enum.reduce_while(
|
||||||
|
@ -215,7 +215,7 @@ defp for_each_history_item(%{"orderedItems" => items} = history, _object, fun) d
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp for_each_history_item(history, _, _) do
|
def for_each_history_item(history, _, _) do
|
||||||
{:ok, history}
|
{:ok, history}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -63,10 +63,53 @@ defmodule Pleroma.Web.ActivityPub.MRF do
|
||||||
|
|
||||||
@required_description_keys [:key, :related_policy]
|
@required_description_keys [:key, :related_policy]
|
||||||
|
|
||||||
|
def filter_one(policy, message) do
|
||||||
|
should_plug_history? =
|
||||||
|
if function_exported?(policy, :history_awareness, 0) do
|
||||||
|
policy.history_awareness()
|
||||||
|
else
|
||||||
|
:manual
|
||||||
|
end
|
||||||
|
|> Kernel.==(:auto)
|
||||||
|
|
||||||
|
if not should_plug_history? do
|
||||||
|
policy.filter(message)
|
||||||
|
else
|
||||||
|
main_result = policy.filter(message)
|
||||||
|
|
||||||
|
with {_, {:ok, main_message}} <- {:main, main_result},
|
||||||
|
{_,
|
||||||
|
%{
|
||||||
|
"formerRepresentations" => %{
|
||||||
|
"orderedItems" => [_ | _]
|
||||||
|
}
|
||||||
|
}} = {_, object} <- {:object, message["object"]},
|
||||||
|
{_, {:ok, new_history}} <-
|
||||||
|
{:history,
|
||||||
|
Pleroma.Object.Updater.for_each_history_item(
|
||||||
|
object["formerRepresentations"],
|
||||||
|
object,
|
||||||
|
fn item ->
|
||||||
|
with {:ok, filtered} <- policy.filter(Map.put(message, "object", item)) do
|
||||||
|
{:ok, filtered["object"]}
|
||||||
|
else
|
||||||
|
e -> e
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)} do
|
||||||
|
{:ok, put_in(main_message, ["object", "formerRepresentations"], new_history)}
|
||||||
|
else
|
||||||
|
{:main, _} -> main_result
|
||||||
|
{:object, _} -> main_result
|
||||||
|
{:history, e} -> e
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def filter(policies, %{} = message) do
|
def filter(policies, %{} = message) do
|
||||||
policies
|
policies
|
||||||
|> Enum.reduce({:ok, message}, fn
|
|> Enum.reduce({:ok, message}, fn
|
||||||
policy, {:ok, message} -> policy.filter(message)
|
policy, {:ok, message} -> filter_one(policy, message)
|
||||||
_, error -> error
|
_, error -> error
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrepended do
|
||||||
|
|
||||||
@reply_prefix Regex.compile!("^re:[[:space:]]*", [:caseless])
|
@reply_prefix Regex.compile!("^re:[[:space:]]*", [:caseless])
|
||||||
|
|
||||||
|
def history_awareness, do: :auto
|
||||||
|
|
||||||
def filter_by_summary(
|
def filter_by_summary(
|
||||||
%{data: %{"summary" => parent_summary}} = _in_reply_to,
|
%{data: %{"summary" => parent_summary}} = _in_reply_to,
|
||||||
%{"summary" => child_summary} = child
|
%{"summary" => child_summary} = child
|
||||||
|
@ -27,8 +29,8 @@ def filter_by_summary(
|
||||||
|
|
||||||
def filter_by_summary(_in_reply_to, child), do: child
|
def filter_by_summary(_in_reply_to, child), do: child
|
||||||
|
|
||||||
def filter(%{"type" => "Create", "object" => child_object} = object)
|
def filter(%{"type" => type, "object" => child_object} = object)
|
||||||
when is_map(child_object) do
|
when type in ["Create", "Update"] and is_map(child_object) do
|
||||||
child =
|
child =
|
||||||
child_object["inReplyTo"]
|
child_object["inReplyTo"]
|
||||||
|> Object.normalize(fetch: false)
|
|> Object.normalize(fetch: false)
|
||||||
|
|
|
@ -12,5 +12,6 @@ defmodule Pleroma.Web.ActivityPub.MRF.Policy do
|
||||||
label: String.t(),
|
label: String.t(),
|
||||||
description: String.t()
|
description: String.t()
|
||||||
}
|
}
|
||||||
@optional_callbacks config_description: 0
|
@callback history_awareness() :: :auto | :manual
|
||||||
|
@optional_callbacks config_description: 0, history_awareness: 0
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do
|
||||||
|
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Web.ActivityPub.MRF
|
||||||
alias Pleroma.Web.ActivityPub.MRF.EnsureRePrepended
|
alias Pleroma.Web.ActivityPub.MRF.EnsureRePrepended
|
||||||
|
|
||||||
describe "rewrites summary" do
|
describe "rewrites summary" do
|
||||||
|
@ -35,10 +36,58 @@ test "it adds `re:` to summary object when child summary containts re-subject of
|
||||||
assert {:ok, res} = EnsureRePrepended.filter(message)
|
assert {:ok, res} = EnsureRePrepended.filter(message)
|
||||||
assert res["object"]["summary"] == "re: object-summary"
|
assert res["object"]["summary"] == "re: object-summary"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it adds `re:` to history" do
|
||||||
|
message = %{
|
||||||
|
"type" => "Create",
|
||||||
|
"object" => %{
|
||||||
|
"summary" => "object-summary",
|
||||||
|
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}},
|
||||||
|
"formerRepresentations" => %{
|
||||||
|
"orderedItems" => [
|
||||||
|
%{
|
||||||
|
"summary" => "object-summary",
|
||||||
|
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {:ok, res} = MRF.filter_one(EnsureRePrepended, message)
|
||||||
|
assert res["object"]["summary"] == "re: object-summary"
|
||||||
|
|
||||||
|
assert Enum.at(res["object"]["formerRepresentations"]["orderedItems"], 0)["summary"] ==
|
||||||
|
"re: object-summary"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it accepts Updates" do
|
||||||
|
message = %{
|
||||||
|
"type" => "Update",
|
||||||
|
"object" => %{
|
||||||
|
"summary" => "object-summary",
|
||||||
|
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}},
|
||||||
|
"formerRepresentations" => %{
|
||||||
|
"orderedItems" => [
|
||||||
|
%{
|
||||||
|
"summary" => "object-summary",
|
||||||
|
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {:ok, res} = MRF.filter_one(EnsureRePrepended, message)
|
||||||
|
assert res["object"]["summary"] == "re: object-summary"
|
||||||
|
|
||||||
|
assert Enum.at(res["object"]["formerRepresentations"]["orderedItems"], 0)["summary"] ==
|
||||||
|
"re: object-summary"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "skip filter" do
|
describe "skip filter" do
|
||||||
test "it skip if type isn't 'Create'" do
|
test "it skip if type isn't 'Create' or 'Update'" do
|
||||||
message = %{
|
message = %{
|
||||||
"type" => "Annotation",
|
"type" => "Annotation",
|
||||||
"object" => %{"summary" => "object-summary"}
|
"object" => %{"summary" => "object-summary"}
|
||||||
|
|
Loading…
Reference in a new issue