Add compatibility with bookwyrm's weird entities

This commit is contained in:
FloatingGhost 2022-01-07 16:51:04 +00:00
parent a3094b64df
commit 680c5d8d89
5 changed files with 142 additions and 0 deletions

View file

@ -9,9 +9,12 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Object.Fetcher
import Ecto.Changeset import Ecto.Changeset
require Logger
@primary_key false @primary_key false
@derive Jason.Encoder @derive Jason.Encoder
@ -63,6 +66,18 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
defp fix_replies(%{"replies" => replies} = data) when is_bitstring(replies), defp fix_replies(%{"replies" => replies} = data) when is_bitstring(replies),
do: Map.drop(data, ["replies"]) do: Map.drop(data, ["replies"])
defp fix_replies(%{"replies" => %{"first" => first}} = data) do
with {:ok, %{"orderedItems" => replies}} <-
Fetcher.fetch_and_contain_remote_object_from_id(first) do
Map.put(data, "replies", replies)
else
{:error, e} ->
Logger.error("Could not fetch replies for #{first}")
IO.inspect(e)
Map.put(data, "replies", [])
end
end
defp fix_replies(data), do: data defp fix_replies(data), do: data
defp fix(data) do defp fix(data) do

View file

@ -68,6 +68,36 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
|> validate_required([:type, :name, :icon]) |> validate_required([:type, :name, :icon])
end end
def changeset(struct, %{"type" => "Book"} = data) do
data = Map.put(data, "name", data["title"])
struct
|> cast(data, [:type, :name])
|> validate_required([:type, :name])
end
def changeset(struct, %{"type" => "Edition"} = data) do
data = Map.put(data, "name", data["work"])
struct
|> cast(data, [:type, :name])
|> validate_required([:type, :name])
end
def changeset(struct, %{"type" => "Work"} = data) do
data = Map.put(data, "name", data["lccn"])
struct
|> cast(data, [:type, :name])
|> validate_required([:type, :name])
end
def changeset(struct, %{"type" => "Author"} = data) do
struct
|> cast(data, [:type, :name])
|> validate_required([:type, :name])
end
def icon_changeset(struct, data) do def icon_changeset(struct, data) do
struct struct
|> cast(data, [:type, :url]) |> cast(data, [:type, :url])

35
test/fixtures/bookwyrm-article.json vendored Normal file
View file

@ -0,0 +1,35 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"attachment": [
{
"id": null,
"name": "Death's End (The Three-Body Problem) (2018, Head of Zeus)",
"type": "Document",
"url": "https://bookwyrm.com/images/covers/e7a6a777-b3fa-44be-a819-33f3aa5187dd.jpeg"
}
],
"attributedTo": "https://bookwyrm.com/user/TestUser",
"cc": [
"https://bookwyrm.com/user/TestUser/followers"
],
"content": "<p>review</p>",
"id": "https://bookwyrm.com/user/TestUser/review/17",
"inReplyToBook": "https://bookwyrm.com/book/2",
"name": "Review of \"Death's End (The Three-Body Problem)\": ab",
"published": "2022-01-07T16:07:43.665392+00:00",
"replies": {
"@context": "https://www.w3.org/ns/activitystreams",
"first": "https://bookwyrm.com/user/TestUser/review/17/replies?page=1",
"id": "https://bookwyrm.com/user/TestUser/review/17/replies",
"last": "https://bookwyrm.com/user/TestUser/review/17/replies?page=1",
"totalItems": 0,
"type": "OrderedCollection"
},
"sensitive": false,
"tag": [],
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"type": "Article",
"updated": "2022-01-07T16:14:08.267337+00:00"
}

View file

@ -0,0 +1,41 @@
{
"id": "https://bookwyrm.com/user/TestUser/review/17/replies?page=1",
"type": "OrderedCollectionPage",
"partOf": "https://bookwyrm.com/user/TestUser/review/17/replies",
"orderedItems": [
{
"id": "https://bookwyrm.com/user/TestUser/status/18",
"type": "Note",
"published": "2022-01-07T16:07:51.111523+00:00",
"attributedTo": "https://bookwyrm.com/user/TestUser",
"content": "<p>reply</p>",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://bookwyrm.com/user/TestUser/followers",
"https://bookwyrm.com/user/TestUser"
],
"replies": {
"id": "https://bookwyrm.com/user/TestUser/status/18/replies",
"type": "OrderedCollection",
"totalItems": 0,
"first": "https://bookwyrm.com/user/TestUser/status/18/replies?page=1",
"last": "https://bookwyrm.com/user/TestUser/status/18/replies?page=1",
"@context": "https://www.w3.org/ns/activitystreams"
},
"inReplyTo": "https://bookwyrm.com/user/TestUser/review/17",
"tag": [
{
"href": "https://bookwyrm.com/user/TestUser",
"name": "TestUser@bookwyrm.com",
"type": "Mention"
}
],
"attachment": [],
"sensitive": false,
"@context": "https://www.w3.org/ns/activitystreams"
}
],
"@context": "https://www.w3.org/ns/activitystreams"
}

View file

@ -31,5 +31,26 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
test "a basic note validates", %{note: note} do test "a basic note validates", %{note: note} do
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note) %{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
end end
test "a note with a remote replies collection should validate", _ do
insert(:user, %{ap_id: "https://bookwyrm.com/user/TestUser"})
collection = File.read!("test/fixtures/bookwyrm-replies-collection.json")
Tesla.Mock.mock(fn %{
method: :get,
url: "https://bookwyrm.com/user/TestUser/review/17/replies?page=1"
} ->
%Tesla.Env{
status: 200,
body: collection,
headers: HttpRequestMock.activitypub_object_headers()
}
end)
note = Jason.decode!(File.read!("test/fixtures/bookwyrm-article.json"))
%{valid?: true, changes: %{replies: ["https://bookwyrm.com/user/TestUser/status/18"]}} =
ArticleNotePageValidator.cast_and_validate(note)
end
end end
end end