featured_address valition in AddRemoveValidator
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Wed, 3 Mar 2021 12:41:05 +0000 (15:41 +0300)
committerAlexander Strizhakov <alex.strizhakov@gmail.com>
Thu, 25 Mar 2021 10:03:40 +0000 (13:03 +0300)
lib/pleroma/web/activity_pub/object_validator.ex
lib/pleroma/web/activity_pub/object_validators/add_remove_validator.ex
lib/pleroma/web/activity_pub/transmogrifier.ex
lib/pleroma/web/common_api.ex
test/fixtures/users_mock/user.json
test/pleroma/web/activity_pub/activity_pub_controller_test.exs
test/pleroma/web/activity_pub/transmogrifier_test.exs

index 14c3e853180bb910af1c16fd3a3b2885b5ff9da8..3ca9136aae43843575e974470fc426a7bca613bb 100644 (file)
@@ -238,7 +238,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
   def validate(%{"type" => type} = object, meta) when type in ~w(Add Remove) do
     with {:ok, object} <-
            object
-           |> AddRemoveValidator.cast_and_validate()
+           |> AddRemoveValidator.cast_and_validate(meta)
            |> Ecto.Changeset.apply_action(:insert) do
       object = stringify_keys(object)
       {:ok, object, meta}
index 73d1c03f0fc2c78b1599cd3baefaca95ae0f2f25..885282f32817c1907e37f610451e6d3d27fb45a7 100644 (file)
@@ -22,28 +22,28 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AddRemoveValidator do
     field(:cc, ObjectValidators.Recipients, default: [])
   end
 
-  def cast_and_validate(data) do
+  def cast_and_validate(data, meta) do
     data
     |> cast_data()
-    |> validate_data()
+    |> validate_data(meta)
   end
 
   defp cast_data(data) do
     cast(%__MODULE__{}, data, __schema__(:fields))
   end
 
-  defp validate_data(changeset) do
+  defp validate_data(changeset, meta) do
     changeset
     |> validate_required([:id, :target, :object, :actor, :type, :to, :cc])
     |> validate_inclusion(:type, ~w(Add Remove))
     |> validate_actor_presence()
-    |> validate_collection_belongs_to_actor()
+    |> validate_collection_belongs_to_actor(meta)
     |> validate_object_presence()
   end
 
-  defp validate_collection_belongs_to_actor(changeset) do
+  defp validate_collection_belongs_to_actor(changeset, meta) do
     validate_change(changeset, :target, fn :target, target ->
-      if String.starts_with?(target, changeset.changes[:actor]) do
+      if target == meta[:featured_address] do
         []
       else
         [target: "collection doesn't belong to actor"]
index b662f53796f56efd58b1dfa0e670887fae5a4427..fa62e0db245b93617c0fdc8d801643c240b9644f 100644 (file)
@@ -557,7 +557,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
   end
 
   def handle_incoming(%{"type" => type} = data, _options) when type in ~w(Add Remove) do
-    with {:ok, user} <- ObjectValidator.fetch_actor(data),
+    with {:ok, %User{} = user} <- ObjectValidator.fetch_actor(data),
          %Object{} <- Object.normalize(data["object"], fetch: true) do
       # Mastodon sends pin/unpin objects without id, to, cc fields
       data =
@@ -566,7 +566,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
         |> Map.put_new("to", [Pleroma.Constants.as_public()])
         |> Map.put_new("cc", [user.follower_address])
 
-      case Pipeline.common_pipeline(data, local: false) do
+      case Pipeline.common_pipeline(data,
+             local: false,
+             featured_address: user.featured_address
+           ) do
         {:ok, activity, _meta} -> {:ok, activity}
         error -> error
       end
index d35a0f219836651b60e9d9e5b9ad006876e592ff..175d690cca93f66616f9c1919436efc216253193 100644 (file)
@@ -412,14 +412,18 @@ defmodule Pleroma.Web.CommonAPI do
   end
 
   @spec pin(String.t(), User.t()) :: {:ok, Activity.t()} | {:error, term()}
-  def pin(id, %User{ap_id: actor} = user) do
+  def pin(id, %User{} = user) do
     with %Activity{} = activity <- create_activity_by_id(id),
-         true <- activity_belongs_to_actor(activity, actor),
+         true <- activity_belongs_to_actor(activity, user.ap_id),
          true <- object_type_is_allowed_for_pin(activity.object),
          true <- activity_is_public(activity),
          {:ok, pin_data, _} <- Builder.pin(user, activity.object),
          {:ok, _pin, _} <-
-           Pipeline.common_pipeline(pin_data, local: true, activity_id: id) do
+           Pipeline.common_pipeline(pin_data,
+             local: true,
+             activity_id: id,
+             featured_address: user.featured_address
+           ) do
       {:ok, activity}
     else
       {:error, {:execute_side_effects, error}} -> error
@@ -456,7 +460,8 @@ defmodule Pleroma.Web.CommonAPI do
            Pipeline.common_pipeline(unpin_data,
              local: true,
              activity_id: activity.id,
-             expires_at: activity.data["expires_at"]
+             expires_at: activity.data["expires_at"],
+             featured_address: user.featured_address
            ) do
       {:ok, activity}
     end
index da2483d028480a87c04be795b193926524d5ae99..c722a1145006873e6897f26d577dcaa34832d555 100644 (file)
@@ -34,6 +34,7 @@
     "owner": "https://example.com/users/{{nickname}}",
     "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5DLtwGXNZElJyxFGfcVc\nXANhaMadj/iYYQwZjOJTV9QsbtiNBeIK54PJrYuU0/0YIdrvS1iqheX5IwXRhcwa\nhm3ZyLz7XeN9st7FBni4BmZMBtMpxAuYuu5p/jbWy13qAiYOhPreCx0wrWgm/lBD\n9mkgaxIxPooBE0S4ZWEJIDIV1Vft3AWcRUyWW1vIBK0uZzs6GYshbQZB952S0yo4\nFzI1hABGHncH8UvuFauh4EZ8tY7/X5I0pGRnDOcRN1dAht5w5yTA+6r5kebiFQjP\nIzN/eCO/a9Flrj9YGW7HDNtjSOH0A31PLRGlJtJO3yK57dnf5ppyCZGfL4emShQo\ncQIDAQAB\n-----END PUBLIC KEY-----\n\n"
   },
+  "featured": "https://example.com/users/{{nickname}}/collections/featured",
   "summary": "your friendly neighborhood pleroma developer<br>I like cute things and distributed systems, and really hate delete and redrafts",
   "tag": [],
   "type": "Person",
index d9fa25d9439faa3145d3838a4d44e6c72fc83506..cea4b3a975250d9115e6ab72fac1938aac0620ba 100644 (file)
@@ -673,6 +673,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
             body: user,
             headers: [{"content-type", "application/activity+json"}]
           }
+
+        %{method: :get, url: "https://example.com/users/lain/collections/featured"} ->
+          %Tesla.Env{
+            status: 200,
+            body:
+              "test/fixtures/users_mock/masto_featured.json"
+              |> File.read!()
+              |> String.replace("{{domain}}", "example.com")
+              |> String.replace("{{nickname}}", "lain"),
+            headers: [{"content-type", "application/activity+json"}]
+          }
       end)
 
       data = %{
@@ -753,6 +764,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
             body: user,
             headers: [{"content-type", "application/activity+json"}]
           }
+
+        %{method: :get, url: "https://example.com/users/lain/collections/featured"} ->
+          %Tesla.Env{
+            status: 200,
+            body:
+              "test/fixtures/users_mock/masto_featured.json"
+              |> File.read!()
+              |> String.replace("{{domain}}", "example.com")
+              |> String.replace("{{nickname}}", "lain"),
+            headers: [{"content-type", "application/activity+json"}]
+          }
       end)
 
       data = %{
index 9bc27f89e6a8b5b218cb652b21394e0e18a889b7..fb8284aaf250d8e7bdae8d96b9666e7add871ed8 100644 (file)
@@ -147,6 +147,17 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
             body: object,
             headers: [{"content-type", "application/activity+json"}]
           }
+
+        %{method: :get, url: "https://example.com/users/lain/collections/featured"} ->
+          %Tesla.Env{
+            status: 200,
+            body:
+              "test/fixtures/users_mock/masto_featured.json"
+              |> File.read!()
+              |> String.replace("{{domain}}", "example.com")
+              |> String.replace("{{nickname}}", "lain"),
+            headers: [{"content-type", "application/activity+json"}]
+          }
       end)
 
       message = %{