AP ingest: fill missing attributedTo from activity
This commit is contained in:
parent
9912a9f603
commit
3b3e369f83
5 changed files with 108 additions and 9 deletions
|
|
@ -15,12 +15,28 @@ defmodule Pleroma.Object.Containment do
|
||||||
actor
|
actor
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_actor(%{"actor" => nil, "attributedTo" => actor}) when not is_nil(actor) do
|
||||||
|
get_actor(%{"actor" => actor})
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_actor(%{"actor" => nil}), do: nil
|
||||||
|
|
||||||
|
def get_actor(%{"actor" => []}), do: nil
|
||||||
|
|
||||||
def get_actor(%{"actor" => actor}) when is_list(actor) do
|
def get_actor(%{"actor" => actor}) when is_list(actor) do
|
||||||
if is_binary(Enum.at(actor, 0)) do
|
case actor do
|
||||||
Enum.at(actor, 0)
|
[first | _] when is_binary(first) ->
|
||||||
else
|
first
|
||||||
Enum.find(actor, fn %{"type" => type} -> type in ["Person", "Service", "Application"] end)
|
|
||||||
|> Map.get("id")
|
_ ->
|
||||||
|
Enum.find_value(actor, fn
|
||||||
|
%{"type" => type, "id" => id}
|
||||||
|
when type in ["Person", "Service", "Application"] and is_binary(id) ->
|
||||||
|
id
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
nil
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -28,10 +44,6 @@ defmodule Pleroma.Object.Containment do
|
||||||
id
|
id
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_actor(%{"actor" => nil, "attributedTo" => actor}) when not is_nil(actor) do
|
|
||||||
get_actor(%{"actor" => actor})
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_object(%{"object" => id}) when is_binary(id) do
|
def get_object(%{"object" => id}) when is_binary(id) do
|
||||||
id
|
id
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
||||||
when objtype in ~w[Question Answer Audio Video Image Event Article Note Page] do
|
when objtype in ~w[Question Answer Audio Video Image Event Article Note Page] do
|
||||||
with {:ok, object_data} <-
|
with {:ok, object_data} <-
|
||||||
object
|
object
|
||||||
|
|> CommonFixes.maybe_set_attributed_to_from_activity(create_activity)
|
||||||
|> CommonFixes.maybe_add_language_from_activity(create_activity)
|
|> CommonFixes.maybe_add_language_from_activity(create_activity)
|
||||||
|> cast_and_apply_and_stringify_with_history(),
|
|> cast_and_apply_and_stringify_with_history(),
|
||||||
meta = Keyword.put(meta, :object_data, object_data),
|
meta = Keyword.put(meta, :object_data, object_data),
|
||||||
|
|
@ -172,6 +173,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
||||||
{_, {:ok, object_data, _}} <-
|
{_, {:ok, object_data, _}} <-
|
||||||
{:object_validation,
|
{:object_validation,
|
||||||
object
|
object
|
||||||
|
|> CommonFixes.maybe_set_attributed_to_from_activity(update_activity)
|
||||||
|> CommonFixes.maybe_add_language_from_activity(update_activity)
|
|> CommonFixes.maybe_add_language_from_activity(update_activity)
|
||||||
|> validate(meta)},
|
|> validate(meta)},
|
||||||
meta = Keyword.put(meta, :object_data, object_data),
|
meta = Keyword.put(meta, :object_data, object_data),
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,17 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes do
|
||||||
|> Map.put("attributedTo", actor)
|
|> Map.put("attributedTo", actor)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def maybe_set_attributed_to_from_activity(object, activity) when is_map(object) do
|
||||||
|
if is_nil(object["attributedTo"]) and is_nil(object["actor"]) do
|
||||||
|
case Containment.get_actor(activity) do
|
||||||
|
actor when is_binary(actor) -> Map.put(object, "attributedTo", actor)
|
||||||
|
_ -> object
|
||||||
|
end
|
||||||
|
else
|
||||||
|
object
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def fix_activity_context(data, %Object{data: %{"context" => object_context}}) do
|
def fix_activity_context(data, %Object{data: %{"context" => object_context}}) do
|
||||||
data
|
data
|
||||||
|> Map.put("context", object_context)
|
|> Map.put("context", object_context)
|
||||||
|
|
|
||||||
25
test/fixtures/fedidev.fun/missing_attributed_to.json
vendored
Normal file
25
test/fixtures/fedidev.fun/missing_attributed_to.json
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://www.w3.org/ns/activitystreams"
|
||||||
|
],
|
||||||
|
"type": "Create",
|
||||||
|
"id": "https://fedidev.fun/activity/missing-attributedto",
|
||||||
|
"actor": "https://fedidev.fun/users/alice",
|
||||||
|
"to": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
],
|
||||||
|
"cc": [],
|
||||||
|
"published": "2025-11-21T14:42:00Z",
|
||||||
|
"object": {
|
||||||
|
"type": "Note",
|
||||||
|
"id": "https://fedidev.fun/objects/note-missing-attributedto",
|
||||||
|
"attributedTo": null,
|
||||||
|
"to": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
],
|
||||||
|
"cc": [],
|
||||||
|
"published": "2025-11-21T14:42:00Z",
|
||||||
|
"content": "object without attributedTo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.ActivityPub.Transmogrifier.FedidevFunMissingAttributedToTest do
|
||||||
|
use Oban.Testing, repo: Pleroma.Repo
|
||||||
|
use Pleroma.DataCase
|
||||||
|
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
|
||||||
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
setup_all do
|
||||||
|
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
defp ensure_remote_actor!(ap_id) when is_binary(ap_id) do
|
||||||
|
case User.get_cached_by_ap_id(ap_id) do
|
||||||
|
%User{} ->
|
||||||
|
:ok
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
insert(:user,
|
||||||
|
local: false,
|
||||||
|
ap_id: ap_id,
|
||||||
|
follower_address: ap_id <> "/followers",
|
||||||
|
following_address: ap_id <> "/following",
|
||||||
|
featured_address: ap_id <> "/collections/featured",
|
||||||
|
inbox: ap_id <> "/inbox"
|
||||||
|
)
|
||||||
|
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "inherits attributedTo from surrounding activity" do
|
||||||
|
data = File.read!("test/fixtures/fedidev.fun/missing_attributed_to.json") |> Jason.decode!()
|
||||||
|
ensure_remote_actor!(data["actor"])
|
||||||
|
|
||||||
|
assert {:ok, activity} = Transmogrifier.handle_incoming(data)
|
||||||
|
object = Object.normalize(activity.data["object"], fetch: false)
|
||||||
|
|
||||||
|
assert object.data["attributedTo"] == data["actor"]
|
||||||
|
assert object.data["actor"] == data["actor"]
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Add table
Add a link
Reference in a new issue