Compare commits

...

3 commits

Author SHA1 Message Date
ab0355a210 Merge remote-tracking branch 'oneric/pleroma_unlisted' into akko.wtf
Available as pending PR AkkomaGang/akkoma#885
2025-03-23 15:10:11 -04:00
Oneric
0abe01be2e federation/in: always copy object addressing into its Create activity
Since we later only consider the Create activity for
access permission checks, but the semantically more
sensible set of fields are the object’s.

Changing the check itself to use the object may have unintended
consequences on already existing legacy posts as the old code
which processed it when it arrived may have never considered
effects on the objects addressing fields.
2025-03-17 23:08:27 +01:00
Oneric
cdf576b951 federation/in: fix activity addressing of Pleroma unlisted
While the object itself has the expected adressing for an
"unlisted" post, we always use the Create activity’s
adressing fields for permission checks.

To avoid unintended effects on legacy objects
we will continue to use the activity for access perm checks,
but fix its addressing fields based on its object data.

Ref: https://git.pleroma.social/pleroma/pleroma/-/issues/3323
2025-03-17 23:06:16 +01:00
2 changed files with 43 additions and 1 deletions

View file

@ -118,7 +118,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
Map.put(map, field, new_fval)
else
map
Map.put(map, field, [])
end
normalise_addressing_public_list(map, fields)
@ -208,6 +208,19 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def fix_in_reply_to(object, _options), do: object
# Pleroma sends unlisted posts without addressing public scope in the enclosing activity
# but we only use the ativity for access perm cheks, see:
# https://git.pleroma.social/pleroma/pleroma/-/issues/3323
defp fix_create_visibility(%{"type" => "Create", "object" => %{} = object} = activity) do
activity
|> Map.put("to", object["to"])
|> Map.put("cc", object["cc"])
|> Map.put("bto", object["bto"])
|> Map.put("bcc", object["bcc"])
end
defp fix_create_visibility(activity), do: activity
def fix_quote_url(object, options \\ [])
def fix_quote_url(%{"quoteUri" => quote_url} = object, options)
@ -513,6 +526,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
)
when objtype in ~w{Question Answer Audio Video Event Article Note Page} do
fetch_options = Keyword.put(options, :depth, (options[:depth] || 0) + 1)
data = fix_create_visibility(data)
object =
data["object"]

View file

@ -17,6 +17,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
import Mock
import Pleroma.Factory
require Pleroma.Constants
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
@ -276,6 +278,32 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
refute is_nil(data["cc"])
end
test "it fixes Pleroma unlisted" do
# https://git.pleroma.social/pleroma/pleroma/-/issues/3323
user1 = insert(:user)
user2 = insert(:user)
data =
File.read!("test/fixtures/mastodon-post-activity.json")
|> Jason.decode!()
|> Map.put("actor", user1.ap_id)
|> Map.put("cc", [])
|> Map.put("to", [user2.ap_id, user1.follower_address])
object =
data["object"]
|> Map.put("attributedTo", user1.ap_id)
|> Map.put("cc", [Pleroma.Constants.as_public()])
|> Map.put("to", [user2.ap_id, user1.follower_address])
|> Map.put("id", user1.ap_id <> "/activities/12345678")
data = Map.put(data, "object", object)
{:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(data)
assert "unlisted" == Pleroma.Web.ActivityPub.Visibility.get_visibility(activity)
end
test "it strips internal likes" do
data =
File.read!("test/fixtures/mastodon-post-activity.json")