From 75d9e2b37514345cc00160d9335781c163da43d4 Mon Sep 17 00:00:00 2001
From: Erin Shepherd
Date: Tue, 2 Apr 2024 23:57:27 +0200
Subject: [PATCH] MRF.InlineQuotePolicy: Add link to post URL, not ID
"id" is used for the canonical link to the AS2 representation of an object.
"url" is typically used for the canonical link to the HTTP representation.
It is what we use, for example, when following the "external source" link
in the frontend. However, it's not the link we include in the post contents
for quote posts.
Using URL instead means we include a more user-friendly URL for Mastodon,
and a working (in the browser) URL for Threads
---
.../activity_pub/mrf/inline_quote_policy.ex | 29 +++++++++++++++----
.../mrf/inline_quote_policy_test.exs | 13 +++++++--
2 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
index 20432410b..35682f994 100644
--- a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
@@ -6,14 +6,29 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
@moduledoc "Force a quote line into the message content."
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
+ alias Pleroma.Object
+
defp build_inline_quote(prefix, url) do
"
#{prefix}: #{url}"
end
- defp has_inline_quote?(content, quote_url) do
+ defp resolve_urls(quote_url) do
+ # Fetching here can cause infinite recursion as we run this logic on inbound objects too
+ # This is probably not a problem - its an exceptional corner case for a local user to quote
+ # a post which doesn't exist
+ with %Object{} = obj <- Object.normalize(quote_url, fetch: false) do
+ id = obj.data["id"]
+ url = Map.get(obj.data, "url", id)
+ {id, url, [id, url, quote_url]}
+ else
+ _ -> {quote_url, quote_url, [quote_url]}
+ end
+ end
+
+ defp has_inline_quote?(content, urls) do
cond do
# Does the quote URL exist in the content?
- content =~ quote_url -> true
+ Enum.any?(urls, fn url -> content =~ url end) -> true
# Does the content already have a .quote-inline span?
content =~ "" -> true
# No inline quote found
@@ -22,18 +37,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
end
defp filter_object(%{"quoteUri" => quote_url} = object) do
+ {id, preferred_url, all_urls} = resolve_urls(quote_url)
+ object = Map.put(object, "quoteUri", id)
+
content = object["content"] || ""
- if has_inline_quote?(content, quote_url) do
+ if has_inline_quote?(content, all_urls) do
object
else
prefix = Pleroma.Config.get([:mrf_inline_quote, :prefix])
content =
if String.ends_with?(content, "
") do
- String.trim_trailing(content, "") <> build_inline_quote(prefix, quote_url) <> ""
+ String.trim_trailing(content, "") <>
+ build_inline_quote(prefix, preferred_url) <> ""
else
- content <> build_inline_quote(prefix, quote_url)
+ content <> build_inline_quote(prefix, preferred_url)
end
Map.put(object, "content", content)
diff --git a/test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs b/test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs
index 4e0910d3e..7671ad5a1 100644
--- a/test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs
+++ b/test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs
@@ -4,10 +4,16 @@
defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicyTest do
alias Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy
+ alias Pleroma.Object
use Pleroma.DataCase
+ setup_all do
+ Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
+ :ok
+ end
+
test "adds quote URL to post content" do
- quote_url = "https://example.com/objects/1234"
+ quote_url = "https://mastodon.social/users/emelie/statuses/101849165031453009"
activity = %{
"type" => "Create",
@@ -19,10 +25,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicyTest do
}
}
+ # Prefetch the quoted post
+ %Object{} = Object.normalize(quote_url, fetch: true)
+
{:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity)
assert filtered ==
- "Nice post
RE: https://example.com/objects/1234
"
+ "Nice post
RE: https://mastodon.social/@emelie/101849165031453009
"
end
test "ignores Misskey quote posts" do