Merge remote-tracking branch 'upstream/bookwyrm-entities' into develop
authorFloatingGhost <hannah@coffee-and-dreams.uk>
Fri, 7 Jan 2022 17:21:44 +0000 (17:21 +0000)
committerFloatingGhost <hannah@coffee-and-dreams.uk>
Fri, 7 Jan 2022 17:21:44 +0000 (17:21 +0000)
lib/pleroma/web/activity_pub/object_validators/article_note_page_validator.ex
lib/pleroma/web/activity_pub/object_validators/tag_validator.ex
mix.exs
mix.lock
test/fixtures/bookwyrm-article.json [new file with mode: 0644]
test/fixtures/bookwyrm-replies-collection.json [new file with mode: 0644]
test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs
test/pleroma/web/activity_pub/object_validators/tag_validator_test.exs [new file with mode: 0644]
test/pleroma/web/streamer_test.exs

index 0aa249c4c1ea089847202ae709e06530aaf9e330..6beeca225d9de189d90c72ffaa05eeec1c0f52b8 100644 (file)
@@ -9,9 +9,12 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
   alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
   alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
   alias Pleroma.Web.ActivityPub.Transmogrifier
+  alias Pleroma.Object.Fetcher
 
   import Ecto.Changeset
 
+  require Logger
+
   @primary_key false
   @derive Jason.Encoder
 
@@ -63,6 +66,18 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
   defp fix_replies(%{"replies" => replies} = data) when is_bitstring(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(data) do
index 7510215851346810f3a86f1e33ae6ff1f7d39620..00d0194afcf27849ff1e0410b9113c249f79283d 100644 (file)
@@ -68,6 +68,36 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.TagValidator do
     |> validate_required([:type, :name, :icon])
   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["title"])
+
+    struct
+    |> cast(data, [:type, :name])
+    |> validate_required([:type, :name])
+  end
+
+  def changeset(struct, %{"type" => "Work"} = data) do
+    data = Map.put(data, "name", data["title"])
+
+    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
     struct
     |> cast(data, [:type, :url])
diff --git a/mix.exs b/mix.exs
index 390430f419175fef4459e968ca452e9e10fed698..848c51c66d5dc8f38ac6b8e8a76496da3ee248c7 100644 (file)
--- a/mix.exs
+++ b/mix.exs
@@ -149,8 +149,7 @@ defmodule Pleroma.Mixfile do
        git: "https://github.com/msantos/crypt.git",
        ref: "f75cd55325e33cbea198fb41fe41871392f8fb76"},
       {:cors_plug, "~> 2.0"},
-      {:web_push_encryption,
-       git: "https://github.com/lanodan/elixir-web-push-encryption.git", branch: "bugfix/otp-24"},
+      {:web_push_encryption, "~> 0.3.1"},
       {:swoosh, "~> 1.0"},
       {:phoenix_swoosh, "~> 0.3"},
       {:gen_smtp, "~> 0.13"},
@@ -183,9 +182,7 @@ defmodule Pleroma.Mixfile do
       {:ex_const, "~> 0.2"},
       {:plug_static_index_html, "~> 1.0.0"},
       {:flake_id, "~> 0.1.0"},
-      {:concurrent_limiter,
-       git: "https://git.pleroma.social/pleroma/elixir-libraries/concurrent_limiter.git",
-       ref: "d81be41024569330f296fc472e24198d7499ba78"},
+      {:concurrent_limiter, "~> 0.1.1"},
       {:remote_ip,
        git: "https://git.pleroma.social/pleroma/remote_ip.git",
        ref: "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8"},
index 020b84a74e9dcfb9331f478727577d512c2fc5f0..43143e0cab91c75fe09b34a2adced4151607157a 100644 (file)
--- a/mix.lock
+++ b/mix.lock
@@ -14,7 +14,7 @@
   "certifi": {:hex, :certifi, "2.8.0", "d4fb0a6bb20b7c9c3643e22507e42f356ac090a1dcea9ab99e27e0376d695eba", [:rebar3], [], "hexpm", "6ac7efc1c6f8600b08d625292d4bbf584e14847ce1b6b5c44d983d273e1097ea"},
   "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
   "comeonin": {:hex, :comeonin, "5.3.2", "5c2f893d05c56ae3f5e24c1b983c2d5dfb88c6d979c9287a76a7feb1e1d8d646", [:mix], [], "hexpm", "d0993402844c49539aeadb3fe46a3c9bd190f1ecf86b6f9ebd71957534c95f04"},
-  "concurrent_limiter": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/concurrent_limiter.git", "d81be41024569330f296fc472e24198d7499ba78", [ref: "d81be41024569330f296fc472e24198d7499ba78"]},
+  "concurrent_limiter": {:hex, :concurrent_limiter, "0.1.1", "43ae1dc23edda1ab03dd66febc739c4ff710d047bb4d735754909f9a474ae01c", [:mix], [{:telemetry, "~> 0.3", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "53968ff238c0fbb4d7ed76ddb1af0be6f3b2f77909f6796e249e737c505a16eb"},
   "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
   "cors_plug": {:hex, :cors_plug, "2.0.3", "316f806d10316e6d10f09473f19052d20ba0a0ce2a1d910ddf57d663dac402ae", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ee4ae1418e6ce117fc42c2ba3e6cbdca4e95ecd2fe59a05ec6884ca16d469aea"},
   "cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
   "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
   "unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"},
   "vex": {:hex, :vex, "0.9.0", "613ea5eb3055662e7178b83e25b2df0975f68c3d8bb67c1645f0573e1a78d606", [:mix], [], "hexpm", "c69fff44d5c8aa3f1faee71bba1dcab05dd36364c5a629df8bb11751240c857f"},
-  "web_push_encryption": {:git, "https://github.com/lanodan/elixir-web-push-encryption.git", "026a043037a89db4da8f07560bc8f9c68bcf0cc0", [branch: "bugfix/otp-24"]},
+  "web_push_encryption": {:hex, :web_push_encryption, "0.3.1", "76d0e7375142dfee67391e7690e89f92578889cbcf2879377900b5620ee4708d", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.11.1", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "4f82b2e57622fb9337559058e8797cb0df7e7c9790793bdc4e40bc895f70e2a2"},
   "websocket_client": {:git, "https://github.com/jeremyong/websocket_client.git", "9a6f65d05ebf2725d62fb19262b21f1805a59fbf", []},
 }
diff --git a/test/fixtures/bookwyrm-article.json b/test/fixtures/bookwyrm-article.json
new file mode 100644 (file)
index 0000000..66b34b6
--- /dev/null
@@ -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"
+}
diff --git a/test/fixtures/bookwyrm-replies-collection.json b/test/fixtures/bookwyrm-replies-collection.json
new file mode 100644 (file)
index 0000000..3f6d722
--- /dev/null
@@ -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"
+}
index 720c17d8da7e731da5c134dfce4699c274ecf48e..2bd1e46c131376f719a5c3ede92940c4e99779cf 100644 (file)
@@ -31,5 +31,26 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
     test "a basic note validates", %{note: note} do
       %{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
     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
diff --git a/test/pleroma/web/activity_pub/object_validators/tag_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/tag_validator_test.exs
new file mode 100644 (file)
index 0000000..bca7a32
--- /dev/null
@@ -0,0 +1,112 @@
+# 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.ObjectValidators.TagValidatorTest do
+  use Pleroma.DataCase, async: true
+
+  alias Pleroma.Web.ActivityPub.ObjectValidators.TagValidator
+
+  test "it validates an Edition" do
+    edition = %{
+      "@context" => "https://www.w3.org/ns/activitystreams",
+      "asin" => "",
+      "authors" => ["https://bookwyrm.com/author/3"],
+      "cover" => %{
+        "@context" => "https://www.w3.org/ns/activitystreams",
+        "name" => "Piranesi (2020, Bloomsbury Publishing)",
+        "type" => "Document",
+        "url" => "https://bookwyrm.com/images/covers/9fd28af7-ebb8-4df3-80c8-28488fc5349f.jpeg"
+      },
+      "description" => "",
+      "editionRank" => 7,
+      "firstPublishedDate" => "",
+      "goodreadsKey" => "",
+      "id" => "https://bookwyrm.com/book/10",
+      "isbn10" => "163557563X",
+      "isbn13" => "9781635575637",
+      "languages" => ["English"],
+      "librarythingKey" => "",
+      "oclcNumber" => "",
+      "openlibraryKey" => "OL28300471M",
+      "pages" => 272,
+      "physicalFormat" => "",
+      "physicalFormatDetail" => "hardcover",
+      "publishedDate" => "2020-09-15T00:00:00+00:00",
+      "publishers" => ["Bloomsbury Publishing"],
+      "series" => "",
+      "seriesNumber" => "",
+      "sortTitle" => "",
+      "subjectPlaces" => [],
+      "subjects" => [],
+      "subtitle" => "",
+      "title" => "Piranesi",
+      "type" => "Edition",
+      "work" => "https://bookwyrm.com/book/9"
+    }
+
+    assert %{valid?: true, changes: %{name: "Piranesi"}} = TagValidator.cast_and_validate(edition)
+  end
+
+  test "it should validate an author" do
+    author = %{
+      "@context" => "https://www.w3.org/ns/activitystreams",
+      "aliases" => [],
+      "bio" => "snipped",
+      "bnfId" => "14603397h",
+      "born" => "1959-11-01T00:00:00+00:00",
+      "goodreadsKey" => "",
+      "id" => "https://bookwyrm.com/author/3",
+      "isni" => "0000 0001 0877 1086",
+      "librarythingKey" => "",
+      "name" => "Susanna Clarke",
+      "openlibraryKey" => "OL1387961A",
+      "type" => "Author",
+      "viafId" => "19931023",
+      "wikipediaLink" => ""
+    }
+
+    assert %{valid?: true, changes: %{name: "Susanna Clarke"}} =
+             TagValidator.cast_and_validate(author)
+  end
+
+  test "it should validate a work" do
+    work = %{
+      "@context" => "https://www.w3.org/ns/activitystreams",
+      "authors" => ["https://bookwyrm.com/author/3"],
+      "cover" => %{
+        "@context" => "https://www.w3.org/ns/activitystreams",
+        "name" => "Piranesi",
+        "type" => "Document",
+        "url" => "https://bookwyrm.com/images/covers/e950ac10-feaf-4c3e-b2d3-de20d3a28329.jpeg"
+      },
+      "description" => "snipped",
+      "editions" => [
+        "https://bookwyrm.com/book/12",
+        "https://bookwyrm.com/book/10",
+        "https://bookwyrm.com/book/14",
+        "https://bookwyrm.com/book/13",
+        "https://bookwyrm.com/book/11",
+        "https://bookwyrm.com/book/15"
+      ],
+      "firstPublishedDate" => "",
+      "goodreadsKey" => "",
+      "id" => "https://bookwyrm.com/book/9",
+      "languages" => [],
+      "lccn" => "",
+      "librarythingKey" => "",
+      "openlibraryKey" => "OL20893680W",
+      "publishedDate" => "",
+      "series" => "",
+      "seriesNumber" => "",
+      "sortTitle" => "",
+      "subjectPlaces" => [],
+      "subjects" => ["English literature"],
+      "subtitle" => "",
+      "title" => "Piranesi",
+      "type" => "Work"
+    }
+
+    assert %{valid?: true, changes: %{name: "Piranesi"}} = TagValidator.cast_and_validate(work)
+  end
+end
index b788a913861b56cceac3d10604b4f8cf9ed557f3..b2941a62c1a36a887307b73a1379b9e7d9e7d7d0 100644 (file)
@@ -772,6 +772,7 @@ defmodule Pleroma.Web.StreamerTest do
       refute_receive _
     end
 
+    @tag :erratic
     test "it sends conversation update to the 'direct' stream when a message is deleted", %{
       user: user,
       token: oauth_token