MRF.InlineQuotePolicy: Add link to post URL, not ID #733

Merged
floatingghost merged 1 commit from erincandescent/akkoma:quote-url into develop 2024-04-12 17:02:53 +00:00
2 changed files with 35 additions and 7 deletions

View file

@ -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
"<span class=\"quote-inline\"><br/><br/>#{prefix}: <a href=\"#{url}\">#{url}</a></span>"
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

the issue is the fetch: true you've added

we've got a test to check for handling self-referential quotes (as naturally it'd be a DoS vector) - having this fetch: true here makes that fail

the issue is the `fetch: true` you've added we've got a test to check for handling self-referential quotes (as naturally it'd be a DoS vector) - having this `fetch: true` here makes that fail

for reference, why this happens:

we try to fetch a quote

pipeline

It goes through the inbound AP pipeline

which puts it through this (as it is enabled by default)

quote URL is detected, let's fetch it (because fetch is true here)

GOTO pipeline

for reference, why this happens: we try to fetch a quote pipeline It goes through the inbound AP pipeline which puts it through this (as it is enabled by default) quote URL is detected, let's fetch it (because fetch is true here) GOTO pipeline

I wonder if we could just run this for outbound messages? I will have to take a look at precisely how MRFs are run to see if thats a feasible option

I wonder if we could just run this for outbound messages? I will have to take a look at precisely how MRFs are run to see if thats a feasible option

You know what, I'm tempted to just change it to fetch: false. Its gotta be astoundingly rare for someone to be quoting a post the server doesn't know about

You know what, I'm tempted to just change it to `fetch: false`. Its gotta be astoundingly rare for someone to be quoting a post the server doesn't know about
# 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 =~ "<span class=\"quote-inline\">" -> 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 =
erincandescent marked this conversation as resolved Outdated

ig this should also switch to preferred_url instead of quote_url?

ig this should also switch to `preferred_url` instead of `quote_url`?

Good catch!

Good catch!
if String.ends_with?(content, "</p>") do
String.trim_trailing(content, "</p>") <> build_inline_quote(prefix, quote_url) <> "</p>"
String.trim_trailing(content, "</p>") <>
build_inline_quote(prefix, preferred_url) <> "</p>"
else
content <> build_inline_quote(prefix, quote_url)
content <> build_inline_quote(prefix, preferred_url)
end
Map.put(object, "content", content)

View file

@ -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 ==
"<p>Nice post<span class=\"quote-inline\"><br/><br/>RE: <a href=\"https://example.com/objects/1234\">https://example.com/objects/1234</a></span></p>"
"<p>Nice post<span class=\"quote-inline\"><br/><br/>RE: <a href=\"https://mastodon.social/@emelie/101849165031453009\">https://mastodon.social/@emelie/101849165031453009</a></span></p>"
end
test "ignores Misskey quote posts" do