Page MenuHomePhorge

No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None
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 7de4935f2..c78675caf 100644
--- a/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
+++ b/lib/pleroma/web/activity_pub/mrf/inline_quote_policy.ex
@@ -1,60 +1,71 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
@moduledoc "Force a quote line into the message content."
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
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
+ cond do
+ # Does the quote URL exist in the content?
+ content =~ quote_url -> true
+ # Does the content already have a .quote-inline span?
+ content =~ "<span class=\"quote-inline\">" -> true
+ # No inline quote found
+ true -> false
+ end
+ end
+
defp filter_object(%{"quoteUrl" => quote_url} = object) do
content = object["content"] || ""
- if content =~ quote_url do
+ if has_inline_quote?(content, quote_url) do
object
else
prefix = Pleroma.Config.get([:mrf_inline_quote, :prefix])
content =
if String.ends_with?(content, "</p>"),
do:
String.trim_trailing(content, "</p>") <>
build_inline_quote(prefix, quote_url) <> "</p>",
else: content <> build_inline_quote(prefix, quote_url)
Map.put(object, "content", content)
end
end
@impl true
def filter(%{"object" => %{"quoteUrl" => _} = object} = activity) do
{:ok, Map.put(activity, "object", filter_object(object))}
end
@impl true
def filter(object), do: {:ok, object}
@impl true
def describe, do: {:ok, %{}}
@impl true
def config_description do
%{
key: :mrf_inline_quote,
related_policy: "Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy",
label: "MRF Inline Quote",
description: "Force quote post URLs inline",
children: [
%{
key: :prefix,
type: :string,
description: "Prefix before the link",
suggestions: ["RT", "QT", "RE", "RN"]
}
]
}
end
end
diff --git a/test/fixtures/quote_post/fedibird_quote_mismatched.json b/test/fixtures/quote_post/fedibird_quote_mismatched.json
new file mode 100644
index 000000000..8dee5daff
--- /dev/null
+++ b/test/fixtures/quote_post/fedibird_quote_mismatched.json
@@ -0,0 +1,54 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ {
+ "ostatus": "http://ostatus.org#",
+ "atomUri": "ostatus:atomUri",
+ "inReplyToAtomUri": "ostatus:inReplyToAtomUri",
+ "conversation": "ostatus:conversation",
+ "sensitive": "as:sensitive",
+ "toot": "http://joinmastodon.org/ns#",
+ "votersCount": "toot:votersCount",
+ "fedibird": "http://fedibird.com/ns#",
+ "quoteUri": "fedibird:quoteUri",
+ "expiry": "fedibird:expiry"
+ }
+ ],
+ "id": "https://fedibird.com/users/noellabo/statuses/107712183700212249",
+ "type": "Note",
+ "summary": null,
+ "inReplyTo": null,
+ "published": "2022-01-30T15:44:50Z",
+ "url": "https://fedibird.com/@noellabo/107712183700212249",
+ "attributedTo": "https://fedibird.com/users/noellabo",
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "cc": [
+ "https://fedibird.com/users/noellabo/followers"
+ ],
+ "sensitive": false,
+ "atomUri": "https://fedibird.com/users/noellabo/statuses/107712183700212249",
+ "inReplyToAtomUri": null,
+ "conversation": "tag:fedibird.com,2022-01-30:objectId=107712183700170473:objectType=Conversation",
+ "context": "https://fedibird.com/contexts/107712183700170473",
+ "quoteUri": "https://unnerv.jp/users/UN_NERV/statuses/107712176849067434",
+ "_misskey_quote": "https://unnerv.jp/users/UN_NERV/statuses/107712176849067434",
+ "_misskey_content": "揺れていたようだ",
+ "content": "<p>揺れていたようだ<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"UN_NERV@unnerv.jp\" data-status-id=\"107712177062934465\" href=\"https://unnerv.jp/@UN_NERV/107712176849067434\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">unnerv.jp/@UN_NERV/10771217684</span><span class=\"invisible\">9067434</span></a></span></p>",
+ "contentMap": {
+ "ja": "<p>揺れていたようだ<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"UN_NERV@unnerv.jp\" data-status-id=\"107712177062934465\" href=\"https://unnerv.jp/@UN_NERV/107712176849067434\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">unnerv.jp/@UN_NERV/10771217684</span><span class=\"invisible\">9067434</span></a></span></p>"
+ },
+ "attachment": [],
+ "tag": [],
+ "replies": {
+ "id": "https://fedibird.com/users/noellabo/statuses/107712183700212249/replies",
+ "type": "Collection",
+ "first": {
+ "type": "CollectionPage",
+ "next": "https://fedibird.com/users/noellabo/statuses/107712183700212249/replies?only_other_accounts=true&page=true",
+ "partOf": "https://fedibird.com/users/noellabo/statuses/107712183700212249/replies",
+ "items": []
+ }
+ }
+}
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 2291c1dac..44ee91d4b 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
@@ -1,75 +1,92 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicyTest do
alias Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy
use Pleroma.DataCase
test "adds quote URL to post content" do
quote_url = "https://gleasonator.com/objects/1234"
activity = %{
"type" => "Create",
"actor" => "https://gleasonator.com/users/alex",
"object" => %{
"type" => "Note",
"content" => "Nice post",
"quoteUrl" => quote_url
}
}
{:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity)
assert filtered ==
"Nice post<span class=\"quote-inline\"><br/><br/>RT: <a href=\"https://gleasonator.com/objects/1234\">https://gleasonator.com/objects/1234</a></span>"
end
test "doesn't add line breaks to markdown posts" do
quote_url = "https://gleasonator.com/objects/1234"
activity = %{
"type" => "Create",
"actor" => "https://gleasonator.com/users/alex",
"object" => %{
"type" => "Note",
"content" => "<p>Nice post</p>",
"quoteUrl" => quote_url
}
}
{:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity)
assert filtered ==
"<p>Nice post<span class=\"quote-inline\"><br/><br/>RT: <a href=\"https://gleasonator.com/objects/1234\">https://gleasonator.com/objects/1234</a></span></p>"
end
test "ignores Misskey quote posts" do
object = File.read!("test/fixtures/quote_post/misskey_quote_post.json") |> Jason.decode!()
activity = %{
"type" => "Create",
"actor" => "https://misskey.io/users/7rkrarq81i",
"object" => object
}
{:ok, filtered} = InlineQuotePolicy.filter(activity)
assert filtered == activity
end
test "ignores Fedibird quote posts" do
object = File.read!("test/fixtures/quote_post/fedibird_quote_post.json") |> Jason.decode!()
# Normally the ObjectValidator will fix this before it reaches MRF
object = Map.put(object, "quoteUrl", object["quoteURL"])
activity = %{
"type" => "Create",
"actor" => "https://fedibird.com/users/noellabo",
"object" => object
}
{:ok, filtered} = InlineQuotePolicy.filter(activity)
assert filtered == activity
end
+
+ test "skips objects which already have an .inline-quote span" do
+ object =
+ File.read!("test/fixtures/quote_post/fedibird_quote_mismatched.json") |> Jason.decode!()
+
+ # Normally the ObjectValidator will fix this before it reaches MRF
+ object = Map.put(object, "quoteUrl", object["quoteUri"])
+
+ activity = %{
+ "type" => "Create",
+ "actor" => "https://fedibird.com/users/noellabo",
+ "object" => object
+ }
+
+ {:ok, filtered} = InlineQuotePolicy.filter(activity)
+ assert filtered == activity
+ end
end

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jul 19, 5:42 PM (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1695323
Default Alt Text
(8 KB)

Event Timeline