ensure quote fetching obeys max thread distance (#119)
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/119
This commit is contained in:
parent
2cde2052b8
commit
a3501cab86
5 changed files with 171 additions and 94 deletions
|
@ -156,7 +156,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
|
||||||
|> fix_replies()
|
|> fix_replies()
|
||||||
|> fix_source()
|
|> fix_source()
|
||||||
|> fix_misskey_content()
|
|> fix_misskey_content()
|
||||||
|> Transmogrifier.fix_quote_url()
|
|
||||||
|> Transmogrifier.fix_attachments()
|
|> Transmogrifier.fix_attachments()
|
||||||
|> Transmogrifier.fix_emoji()
|
|> Transmogrifier.fix_emoji()
|
||||||
|> Transmogrifier.fix_content_map()
|
|> Transmogrifier.fix_content_map()
|
||||||
|
|
|
@ -38,6 +38,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
||||||
|> fix_attachments()
|
|> fix_attachments()
|
||||||
|> fix_context()
|
|> fix_context()
|
||||||
|> fix_in_reply_to(options)
|
|> fix_in_reply_to(options)
|
||||||
|
|> fix_quote_url(options)
|
||||||
|> fix_emoji()
|
|> fix_emoji()
|
||||||
|> fix_tag()
|
|> fix_tag()
|
||||||
|> fix_content_map()
|
|> fix_content_map()
|
||||||
|
@ -167,6 +168,50 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
||||||
|
|
||||||
def fix_in_reply_to(object, _options), do: object
|
def fix_in_reply_to(object, _options), do: object
|
||||||
|
|
||||||
|
def fix_quote_url(object, options \\ [])
|
||||||
|
|
||||||
|
def fix_quote_url(%{"quoteUri" => quote_url} = object, options)
|
||||||
|
when not is_nil(quote_url) do
|
||||||
|
depth = (options[:depth] || 0) + 1
|
||||||
|
|
||||||
|
if Federator.allowed_thread_distance?(depth) do
|
||||||
|
with {:ok, quoted_object} <- get_obj_helper(quote_url, options),
|
||||||
|
%Activity{} <- Activity.get_create_by_object_ap_id(quoted_object.data["id"]) do
|
||||||
|
object
|
||||||
|
|> Map.put("quoteUri", quoted_object.data["id"])
|
||||||
|
else
|
||||||
|
e ->
|
||||||
|
Logger.warn("Couldn't fetch #{inspect(quote_url)}, error: #{inspect(e)}")
|
||||||
|
object
|
||||||
|
end
|
||||||
|
else
|
||||||
|
object
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Soapbox
|
||||||
|
def fix_quote_url(%{"quoteUrl" => quote_url} = object, options) do
|
||||||
|
object
|
||||||
|
|> Map.put("quoteUri", quote_url)
|
||||||
|
|> fix_quote_url(options)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Old Fedibird (bug)
|
||||||
|
# https://github.com/fedibird/mastodon/issues/9
|
||||||
|
def fix_quote_url(%{"quoteURL" => quote_url} = object, options) do
|
||||||
|
object
|
||||||
|
|> Map.put("quoteUri", quote_url)
|
||||||
|
|> fix_quote_url(options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fix_quote_url(%{"_misskey_quote" => quote_url} = object, options) do
|
||||||
|
object
|
||||||
|
|> Map.put("quoteUri", quote_url)
|
||||||
|
|> fix_quote_url(options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fix_quote_url(object, _), do: object
|
||||||
|
|
||||||
defp prepare_in_reply_to(in_reply_to) do
|
defp prepare_in_reply_to(in_reply_to) do
|
||||||
cond do
|
cond do
|
||||||
is_bitstring(in_reply_to) ->
|
is_bitstring(in_reply_to) ->
|
||||||
|
@ -424,6 +469,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
||||||
|> strip_internal_fields()
|
|> strip_internal_fields()
|
||||||
|> fix_type(fetch_options)
|
|> fix_type(fetch_options)
|
||||||
|> fix_in_reply_to(fetch_options)
|
|> fix_in_reply_to(fetch_options)
|
||||||
|
|> fix_quote_url(fetch_options)
|
||||||
|
|
||||||
data = Map.put(data, "object", object)
|
data = Map.put(data, "object", object)
|
||||||
options = Keyword.put(options, :local, false)
|
options = Keyword.put(options, :local, false)
|
||||||
|
@ -886,43 +932,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
||||||
|
|
||||||
defp strip_internal_tags(object), do: object
|
defp strip_internal_tags(object), do: object
|
||||||
|
|
||||||
def fix_quote_url(object, options \\ [])
|
|
||||||
|
|
||||||
def fix_quote_url(%{"quoteUri" => quote_url} = object, options)
|
|
||||||
when not is_nil(quote_url) do
|
|
||||||
with {:ok, quoted_object} <- get_obj_helper(quote_url, options),
|
|
||||||
%Activity{} <- Activity.get_create_by_object_ap_id(quoted_object.data["id"]) do
|
|
||||||
Map.put(object, "quoteUri", quoted_object.data["id"])
|
|
||||||
else
|
|
||||||
e ->
|
|
||||||
Logger.warn("Couldn't fetch #{inspect(quote_url)}, error: #{inspect(e)}")
|
|
||||||
object
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Soapbox
|
|
||||||
def fix_quote_url(%{"quoteUrl" => quote_url} = object, options) do
|
|
||||||
object
|
|
||||||
|> Map.put("quoteUri", quote_url)
|
|
||||||
|> fix_quote_url(options)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Old Fedibird (bug)
|
|
||||||
# https://github.com/fedibird/mastodon/issues/9
|
|
||||||
def fix_quote_url(%{"quoteURL" => quote_url} = object, options) do
|
|
||||||
object
|
|
||||||
|> Map.put("quoteUri", quote_url)
|
|
||||||
|> fix_quote_url(options)
|
|
||||||
end
|
|
||||||
|
|
||||||
def fix_quote_url(%{"_misskey_quote" => quote_url} = object, options) do
|
|
||||||
object
|
|
||||||
|> Map.put("quoteUri", quote_url)
|
|
||||||
|> fix_quote_url(options)
|
|
||||||
end
|
|
||||||
|
|
||||||
def fix_quote_url(object, _), do: object
|
|
||||||
|
|
||||||
def perform(:user_upgrade, user) do
|
def perform(:user_upgrade, user) do
|
||||||
# we pass a fake user so that the followers collection is stripped away
|
# we pass a fake user so that the followers collection is stripped away
|
||||||
old_follower_address = User.ap_followers(%User{nickname: user.nickname})
|
old_follower_address = User.ap_followers(%User{nickname: user.nickname})
|
||||||
|
|
48
test/fixtures/misskey/recursive_quote.json
vendored
Normal file
48
test/fixtures/misskey/recursive_quote.json
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://w3id.org/security/v1",
|
||||||
|
{
|
||||||
|
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||||
|
"sensitive": "as:sensitive",
|
||||||
|
"Hashtag": "as:Hashtag",
|
||||||
|
"quoteUrl": "as:quoteUrl",
|
||||||
|
"toot": "http://joinmastodon.org/ns#",
|
||||||
|
"Emoji": "toot:Emoji",
|
||||||
|
"featured": "toot:featured",
|
||||||
|
"discoverable": "toot:discoverable",
|
||||||
|
"schema": "http://schema.org#",
|
||||||
|
"PropertyValue": "schema:PropertyValue",
|
||||||
|
"value": "schema:value",
|
||||||
|
"misskey": "https://misskey-hub.net/ns#",
|
||||||
|
"_misskey_content": "misskey:_misskey_content",
|
||||||
|
"_misskey_quote": "misskey:_misskey_quote",
|
||||||
|
"_misskey_reaction": "misskey:_misskey_reaction",
|
||||||
|
"_misskey_votes": "misskey:_misskey_votes",
|
||||||
|
"_misskey_talk": "misskey:_misskey_talk",
|
||||||
|
"isCat": "misskey:isCat",
|
||||||
|
"vcard": "http://www.w3.org/2006/vcard/ns#"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id": "https://misskey.io/notes/934gok3482",
|
||||||
|
"type": "Note",
|
||||||
|
"attributedTo": "https://misskey.io/users/93492q0ip0",
|
||||||
|
"summary": null,
|
||||||
|
"content": "<p><span>i quompt u</p>",
|
||||||
|
"_misskey_content": "i quompt u",
|
||||||
|
"source": {
|
||||||
|
"content": "i quompt u",
|
||||||
|
"mediaType": "text/x.misskeymarkdown"
|
||||||
|
},
|
||||||
|
"_misskey_quote": "https://misskey.io/notes/934gok3482",
|
||||||
|
"quoteUrl": "https://misskey.io/notes/934gok3482",
|
||||||
|
"published": "2022-07-25T15:21:48.208Z",
|
||||||
|
"to": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
],
|
||||||
|
"cc": [],
|
||||||
|
"inReplyTo": null,
|
||||||
|
"attachment": [],
|
||||||
|
"sensitive": false,
|
||||||
|
"tag": []
|
||||||
|
}
|
|
@ -143,61 +143,5 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
|
||||||
}
|
}
|
||||||
} = ArticleNotePageValidator.cast_and_validate(note)
|
} = ArticleNotePageValidator.cast_and_validate(note)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "a misskey quote should work", _ do
|
|
||||||
Tesla.Mock.mock(fn %{
|
|
||||||
method: :get,
|
|
||||||
url: "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
|
|
||||||
} ->
|
|
||||||
%Tesla.Env{
|
|
||||||
status: 200,
|
|
||||||
body: File.read!("test/fixtures/quoted_status.json"),
|
|
||||||
headers: HttpRequestMock.activitypub_object_headers()
|
|
||||||
}
|
|
||||||
end)
|
|
||||||
|
|
||||||
insert(:user, %{ap_id: "https://misskey.io/users/93492q0ip0"})
|
|
||||||
insert(:user, %{ap_id: "https://example.com/users/user"})
|
|
||||||
|
|
||||||
note =
|
|
||||||
"test/fixtures/misskey/quote.json"
|
|
||||||
|> File.read!()
|
|
||||||
|> Jason.decode!()
|
|
||||||
|
|
||||||
%{
|
|
||||||
valid?: true,
|
|
||||||
changes: %{
|
|
||||||
quoteUri: "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
|
|
||||||
}
|
|
||||||
} = ArticleNotePageValidator.cast_and_validate(note)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "a fedibird quote should work", _ do
|
|
||||||
Tesla.Mock.mock(fn %{
|
|
||||||
method: :get,
|
|
||||||
url: "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
|
|
||||||
} ->
|
|
||||||
%Tesla.Env{
|
|
||||||
status: 200,
|
|
||||||
body: File.read!("test/fixtures/quoted_status.json"),
|
|
||||||
headers: HttpRequestMock.activitypub_object_headers()
|
|
||||||
}
|
|
||||||
end)
|
|
||||||
|
|
||||||
insert(:user, %{ap_id: "https://fedibird.com/users/akkoma_ap_integration_tester"})
|
|
||||||
insert(:user, %{ap_id: "https://example.com/users/user"})
|
|
||||||
|
|
||||||
note =
|
|
||||||
"test/fixtures/fedibird/quote.json"
|
|
||||||
|> File.read!()
|
|
||||||
|> Jason.decode!()
|
|
||||||
|
|
||||||
%{
|
|
||||||
valid?: true,
|
|
||||||
changes: %{
|
|
||||||
quoteUri: "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
|
|
||||||
}
|
|
||||||
} = ArticleNotePageValidator.cast_and_validate(note)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -707,4 +707,81 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "fix_quote_url/1" do
|
||||||
|
test "a misskey quote should work", _ do
|
||||||
|
Tesla.Mock.mock(fn %{
|
||||||
|
method: :get,
|
||||||
|
url: "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
|
||||||
|
} ->
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/quoted_status.json"),
|
||||||
|
headers: HttpRequestMock.activitypub_object_headers()
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
insert(:user, %{ap_id: "https://misskey.io/users/93492q0ip0"})
|
||||||
|
insert(:user, %{ap_id: "https://example.com/users/user"})
|
||||||
|
|
||||||
|
note =
|
||||||
|
"test/fixtures/misskey/quote.json"
|
||||||
|
|> File.read!()
|
||||||
|
|> Jason.decode!()
|
||||||
|
|
||||||
|
%{"quoteUri" => "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"} =
|
||||||
|
Transmogrifier.fix_quote_url(note)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "a fedibird quote should work", _ do
|
||||||
|
Tesla.Mock.mock(fn %{
|
||||||
|
method: :get,
|
||||||
|
url: "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
|
||||||
|
} ->
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/quoted_status.json"),
|
||||||
|
headers: HttpRequestMock.activitypub_object_headers()
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
insert(:user, %{ap_id: "https://fedibird.com/users/akkoma_ap_integration_tester"})
|
||||||
|
insert(:user, %{ap_id: "https://example.com/users/user"})
|
||||||
|
|
||||||
|
note =
|
||||||
|
"test/fixtures/fedibird/quote.json"
|
||||||
|
|> File.read!()
|
||||||
|
|> Jason.decode!()
|
||||||
|
|
||||||
|
%{
|
||||||
|
"quoteUri" => "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
|
||||||
|
} = Transmogrifier.fix_quote_url(note)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "quote fetching should stop after n levels", _ do
|
||||||
|
clear_config([:instance, :federation_incoming_replies_max_depth], 1)
|
||||||
|
|
||||||
|
Tesla.Mock.mock(fn %{
|
||||||
|
method: :get,
|
||||||
|
url: "https://misskey.io/notes/934gok3482"
|
||||||
|
} ->
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/misskey/recursive_quote.json"),
|
||||||
|
headers: HttpRequestMock.activitypub_object_headers()
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
insert(:user, %{ap_id: "https://misskey.io/users/93492q0ip0"})
|
||||||
|
|
||||||
|
note =
|
||||||
|
"test/fixtures/misskey/recursive_quote.json"
|
||||||
|
|> File.read!()
|
||||||
|
|> Jason.decode!()
|
||||||
|
|
||||||
|
%{
|
||||||
|
"quoteUri" => "https://misskey.io/notes/934gok3482"
|
||||||
|
} = Transmogrifier.fix_quote_url(note)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue