Merge commit '07fed0fda2473fc4e1e3b01e863217391fd2902f'; commit 'e3173a279dad89dfce6e...
[akkoma] / lib / pleroma / web / activity_pub / transmogrifier.ex
index 36ef6a454e54a0cc8ca38c0844532f3a68836a43..4d9a5617eb9b5b3fcdebfb44b0e3cf0ee9c8aed3 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.Transmogrifier do
@@ -312,15 +312,16 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
   def fix_emoji(object), do: object
 
   def fix_tag(%{"tag" => tag} = object) when is_list(tag) do
-    hashtags =
+    tags =
       tag
       |> Enum.filter(fn data -> data["type"] == "Hashtag" and data["name"] end)
-      |> Enum.map(fn
-        %{"name" => "#" <> hashtag} -> String.downcase(hashtag)
-        %{"name" => hashtag} -> String.downcase(hashtag)
+      |> Enum.map(fn %{"name" => name} ->
+        name
+        |> String.slice(1..-1)
+        |> String.downcase()
       end)
 
-    Map.put(object, "hashtags", hashtags)
+    Map.put(object, "tag", tag ++ tags)
   end
 
   def fix_tag(%{"tag" => %{} = tag} = object) do
@@ -652,7 +653,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
 
   @spec get_obj_helper(String.t(), Keyword.t()) :: {:ok, Object.t()} | nil
   def get_obj_helper(id, options \\ []) do
-    case Object.normalize(id, true, options) do
+    options = Keyword.put(options, :fetch, true)
+
+    case Object.normalize(id, options) do
       %Object{} = object -> {:ok, object}
       _ -> nil
     end
@@ -671,7 +674,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
              "actor" => attributed_to,
              "object" => data
            }) do
-      {:ok, Object.normalize(activity)}
+      {:ok, Object.normalize(activity, fetch: false)}
     else
       _ -> get_obj_helper(object_id)
     end
@@ -762,7 +765,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
       when activity_type in ["Create", "Listen"] do
     object =
       object_id
-      |> Object.normalize()
+      |> Object.normalize(fetch: false)
       |> Map.get(:data)
       |> prepare_object
 
@@ -778,7 +781,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
   def prepare_outgoing(%{"type" => "Announce", "actor" => ap_id, "object" => object_id} = data) do
     object =
       object_id
-      |> Object.normalize()
+      |> Object.normalize(fetch: false)
 
     data =
       if Visibility.is_private?(object) && object.data["actor"] == ap_id do
@@ -863,18 +866,23 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
   def maybe_fix_object_url(data), do: data
 
   def add_hashtags(object) do
-    hashtags =
-      object
-      |> Object.hashtags()
-      |> Enum.map(fn tag ->
-        %{
-          "href" => Pleroma.Web.Endpoint.url() <> "/tags/#{tag}",
-          "name" => "##{tag}",
-          "type" => "Hashtag"
-        }
+    tags =
+      (object["tag"] || [])
+      |> Enum.map(fn
+        # Expand internal representation tags into AS2 tags.
+        tag when is_binary(tag) ->
+          %{
+            "href" => Pleroma.Web.Endpoint.url() <> "/tags/#{tag}",
+            "name" => "##{tag}",
+            "type" => "Hashtag"
+          }
+
+        # Do not process tags which are already AS2 tag objects.
+        tag when is_map(tag) ->
+          tag
       end)
 
-    Map.put(object, "tag", hashtags ++ (object["tag"] || []))
+    Map.put(object, "tag", tags)
   end
 
   # TODO These should be added on our side on insertion, it doesn't make much
@@ -913,7 +921,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
 
   defp build_emoji_tag({name, url}) do
     %{
-      "icon" => %{"url" => url, "type" => "Image"},
+      "icon" => %{"url" => "#{URI.encode(url)}", "type" => "Image"},
       "name" => ":" <> name <> ":",
       "type" => "Emoji",
       "updated" => "1970-01-01T00:00:00Z",
@@ -930,7 +938,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
   end
 
   def set_sensitive(object) do
-    tags = object["hashtags"] || object["tag"] || []
+    tags = object["tag"] || []
     Map.put(object, "sensitive", "nsfw" in tags)
   end