User: Move inbox & shared_inbox to own fields
authorHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Wed, 1 Apr 2020 05:47:07 +0000 (07:47 +0200)
committerHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Fri, 10 Apr 2020 04:20:02 +0000 (06:20 +0200)
lib/pleroma/user.ex
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/activity_pub/publisher.ex
priv/repo/migrations/20200401072456_users_add_inboxes.exs [new file with mode: 0644]
test/web/activity_pub/publisher_test.exs
test/web/federator_test.exs

index 027386a225cd1e27d405472b375cb66de829987c..7d8f3a76bf5bfdb953b57cb681f1e2257d42faf4 100644 (file)
@@ -134,6 +134,8 @@ defmodule Pleroma.User do
     field(:skip_thread_containment, :boolean, default: false)
     field(:actor_type, :string, default: "Person")
     field(:also_known_as, {:array, :string}, default: [])
+    field(:inbox, :string)
+    field(:shared_inbox, :string)
 
     embeds_one(
       :notification_settings,
@@ -367,6 +369,8 @@ defmodule Pleroma.User do
         :bio,
         :name,
         :ap_id,
+        :inbox,
+        :shared_inbox,
         :nickname,
         :public_key,
         :avatar,
@@ -411,6 +415,8 @@ defmodule Pleroma.User do
         :name,
         :avatar,
         :public_key,
+        :inbox,
+        :shared_inbox,
         :locked,
         :no_rich_text,
         :default_scope,
@@ -508,6 +514,8 @@ defmodule Pleroma.User do
         :follower_address,
         :following_address,
         :public_key,
+        :inbox,
+        :shared_inbox,
         :avatar,
         :last_refreshed_at,
         :ap_enabled,
index 0e4a9d842ba12aa1a74e2df452f97569a97bd921..f0bbecc9b6f6d4bdb1f272f8598a5da3fd6b4755 100644 (file)
@@ -1432,7 +1432,20 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     discoverable = data["discoverable"] || false
     invisible = data["invisible"] || false
     actor_type = data["type"] || "Person"
-    public_key = data["publicKey"]["publicKeyPem"]
+
+    public_key =
+      if is_map(data["publicKey"]) && is_binary(data["publicKey"]["publicKeyPem"]) do
+        data["publicKey"]["publicKeyPem"]
+      else
+        nil
+      end
+
+    shared_inbox =
+      if is_map(data["endpoints"]) && is_binary(data["endpoints"]["sharedInbox"]) do
+        data["endpoints"]["sharedInbox"]
+      else
+        nil
+      end
 
     user_data = %{
       ap_id: data["id"],
@@ -1451,7 +1464,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
       bio: data["summary"],
       actor_type: actor_type,
       also_known_as: Map.get(data, "alsoKnownAs", []),
-      public_key: public_key
+      public_key: public_key,
+      inbox: data["inbox"],
+      shared_inbox: shared_inbox
     }
 
     # nickname can be nil because of virtual actors
index 6c558e7f0ef907e3fde4022ff26e56c3da1d5b56..b70cbd04343b4d40ca899a6e63c331d861f3d3d4 100644 (file)
@@ -141,8 +141,8 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
     |> Enum.map(& &1.ap_id)
   end
 
-  defp maybe_use_sharedinbox(%User{source_data: data}),
-    do: (is_map(data["endpoints"]) && Map.get(data["endpoints"], "sharedInbox")) || data["inbox"]
+  defp maybe_use_sharedinbox(%User{shared_inbox: nil, inbox: inbox}), do: inbox
+  defp maybe_use_sharedinbox(%User{shared_inbox: shared_inbox}), do: shared_inbox
 
   @doc """
   Determine a user inbox to use based on heuristics.  These heuristics
@@ -157,7 +157,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
   """
   def determine_inbox(
         %Activity{data: activity_data},
-        %User{source_data: data} = user
+        %User{inbox: inbox} = user
       ) do
     to = activity_data["to"] || []
     cc = activity_data["cc"] || []
@@ -174,7 +174,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
         maybe_use_sharedinbox(user)
 
       true ->
-        data["inbox"]
+        inbox
     end
   end
 
@@ -192,14 +192,13 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
     inboxes =
       recipients
       |> Enum.filter(&User.ap_enabled?/1)
-      |> Enum.map(fn %{source_data: data} -> data["inbox"] end)
+      |> Enum.map(fn actor -> actor.inbox end)
       |> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
       |> Instances.filter_reachable()
 
     Repo.checkout(fn ->
       Enum.each(inboxes, fn {inbox, unreachable_since} ->
-        %User{ap_id: ap_id} =
-          Enum.find(recipients, fn %{source_data: data} -> data["inbox"] == inbox end)
+        %User{ap_id: ap_id} = Enum.find(recipients, fn actor -> actor.inbox == inbox end)
 
         # Get all the recipients on the same host and add them to cc. Otherwise, a remote
         # instance would only accept a first message for the first recipient and ignore the rest.
diff --git a/priv/repo/migrations/20200401072456_users_add_inboxes.exs b/priv/repo/migrations/20200401072456_users_add_inboxes.exs
new file mode 100644 (file)
index 0000000..0947f0a
--- /dev/null
@@ -0,0 +1,20 @@
+defmodule Pleroma.Repo.Migrations.UsersAddInboxes do
+  use Ecto.Migration
+
+  def up do
+    alter table(:users) do
+      add_if_not_exists(:inbox, :text)
+      add_if_not_exists(:shared_inbox, :text)
+    end
+
+    execute("UPDATE users SET inbox = source_data->>'inbox'")
+    execute("UPDATE users SET shared_inbox = source_data->'endpoints'->>'sharedInbox'")
+  end
+
+  def down do
+    alter table(:users) do
+      remove_if_exists(:inbox, :text)
+      remove_if_exists(:shared_inbox, :text)
+    end
+  end
+end
index 801da03c1318c8f0fe539f0e9cad104b7f6cad13..c2bc38d52508fdf896d2781484dfe742080d4919 100644 (file)
@@ -48,10 +48,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
 
   describe "determine_inbox/2" do
     test "it returns sharedInbox for messages involving as:Public in to" do
-      user =
-        insert(:user, %{
-          source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}}
-        })
+      user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
 
       activity = %Activity{
         data: %{"to" => [@as_public], "cc" => [user.follower_address]}
@@ -61,10 +58,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
     end
 
     test "it returns sharedInbox for messages involving as:Public in cc" do
-      user =
-        insert(:user, %{
-          source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}}
-        })
+      user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
 
       activity = %Activity{
         data: %{"cc" => [@as_public], "to" => [user.follower_address]}
@@ -74,11 +68,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
     end
 
     test "it returns sharedInbox for messages involving multiple recipients in to" do
-      user =
-        insert(:user, %{
-          source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}}
-        })
-
+      user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
       user_two = insert(:user)
       user_three = insert(:user)
 
@@ -90,11 +80,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
     end
 
     test "it returns sharedInbox for messages involving multiple recipients in cc" do
-      user =
-        insert(:user, %{
-          source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}}
-        })
-
+      user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
       user_two = insert(:user)
       user_three = insert(:user)
 
@@ -107,12 +93,10 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
 
     test "it returns sharedInbox for messages involving multiple recipients in total" do
       user =
-        insert(:user,
-          source_data: %{
-            "inbox" => "http://example.com/personal-inbox",
-            "endpoints" => %{"sharedInbox" => "http://example.com/inbox"}
-          }
-        )
+        insert(:user, %{
+          shared_inbox: "http://example.com/inbox",
+          inbox: "http://example.com/personal-inbox"
+        })
 
       user_two = insert(:user)
 
@@ -125,12 +109,10 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
 
     test "it returns inbox for messages involving single recipients in total" do
       user =
-        insert(:user,
-          source_data: %{
-            "inbox" => "http://example.com/personal-inbox",
-            "endpoints" => %{"sharedInbox" => "http://example.com/inbox"}
-          }
-        )
+        insert(:user, %{
+          shared_inbox: "http://example.com/inbox",
+          inbox: "http://example.com/personal-inbox"
+        })
 
       activity = %Activity{
         data: %{"to" => [user.ap_id], "cc" => []}
@@ -258,11 +240,11 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
                    [:passthrough],
                    [] do
       follower =
-        insert(:user,
+        insert(:user, %{
           local: false,
-          source_data: %{"inbox" => "https://domain.com/users/nick1/inbox"},
+          inbox: "https://domain.com/users/nick1/inbox",
           ap_enabled: true
-        )
+        })
 
       actor = insert(:user, follower_address: follower.ap_id)
       user = insert(:user)
@@ -295,14 +277,14 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
       fetcher =
         insert(:user,
           local: false,
-          source_data: %{"inbox" => "https://domain.com/users/nick1/inbox"},
+          inbox: "https://domain.com/users/nick1/inbox",
           ap_enabled: true
         )
 
       another_fetcher =
         insert(:user,
           local: false,
-          source_data: %{"inbox" => "https://domain2.com/users/nick1/inbox"},
+          inbox: "https://domain2.com/users/nick1/inbox",
           ap_enabled: true
         )
 
index da844c24c2a7a8598a884685dbd039636c667b5b..59e53bb039f576d626fca9970275a0f7680f4261 100644 (file)
@@ -78,7 +78,7 @@ defmodule Pleroma.Web.FederatorTest do
         local: false,
         nickname: "nick1@domain.com",
         ap_id: "https://domain.com/users/nick1",
-        source_data: %{"inbox" => inbox1},
+        inbox: inbox1,
         ap_enabled: true
       })
 
@@ -86,7 +86,7 @@ defmodule Pleroma.Web.FederatorTest do
         local: false,
         nickname: "nick2@domain2.com",
         ap_id: "https://domain2.com/users/nick2",
-        source_data: %{"inbox" => inbox2},
+        inbox: inbox2,
         ap_enabled: true
       })