From 2aea3bc632ffe73c86f4ac9fff79286c179f425f Mon Sep 17 00:00:00 2001
From: William Pitcock <nenolod@dereferenced.org>
Date: Sat, 24 Mar 2018 21:39:37 +0000
Subject: [PATCH] activitypub transmogrifier: rewrite incoming hashtags

---
 .../web/activity_pub/transmogrifier.ex        | 12 ++++
 .../mastodon-post-activity-hashtag.json       | 70 +++++++++++++++++++
 test/web/activity_pub/transmogrifier_test.exs |  7 ++
 3 files changed, 89 insertions(+)
 create mode 100644 test/fixtures/mastodon-post-activity-hashtag.json

diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 61631e1ea..6561b8d76 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -22,6 +22,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
     |> fix_context
     |> fix_in_reply_to
     |> fix_emoji
+    |> fix_tag
   end
 
   def fix_in_reply_to(%{"inReplyTo" => in_reply_to_id} = object) when not is_nil(in_reply_to_id) do
@@ -76,6 +77,17 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
     |> Map.put("emoji", emoji)
   end
 
+  def fix_tag(object) do
+    tags = (object["tag"] || [])
+    |> Enum.filter(fn (data) -> data["type"] == "Hashtag" and data["name"] end)
+    |> Enum.map(fn (data) -> String.slice(data["name"], 1..-1) end)
+
+    combined = (object["tag"] || []) ++ tags
+
+    object
+    |> Map.put("tag", combined)
+  end
+
   # TODO: validate those with a Ecto scheme
   # - tags
   # - emoji
diff --git a/test/fixtures/mastodon-post-activity-hashtag.json b/test/fixtures/mastodon-post-activity-hashtag.json
new file mode 100644
index 000000000..ed0925d85
--- /dev/null
+++ b/test/fixtures/mastodon-post-activity-hashtag.json
@@ -0,0 +1,70 @@
+{
+    "@context": [
+        "https://www.w3.org/ns/activitystreams",
+        "https://w3id.org/security/v1",
+        {
+            "Emoji": "toot:Emoji",
+            "Hashtag": "as:Hashtag",
+            "atomUri": "ostatus:atomUri",
+            "conversation": "ostatus:conversation",
+            "inReplyToAtomUri": "ostatus:inReplyToAtomUri",
+            "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
+            "movedTo": "as:movedTo",
+            "ostatus": "http://ostatus.org#",
+            "sensitive": "as:sensitive",
+            "toot": "http://joinmastodon.org/ns#"
+        }
+    ],
+    "actor": "http://mastodon.example.org/users/admin",
+    "cc": [
+        "http://mastodon.example.org/users/admin/followers",
+        "http://localtesting.pleroma.lol/users/lain"
+    ],
+    "id": "http://mastodon.example.org/users/admin/statuses/99512778738411822/activity",
+    "nickname": "lain",
+    "object": {
+        "atomUri": "http://mastodon.example.org/users/admin/statuses/99512778738411822",
+        "attachment": [],
+        "attributedTo": "http://mastodon.example.org/users/admin",
+        "cc": [
+            "http://mastodon.example.org/users/admin/followers",
+            "http://localtesting.pleroma.lol/users/lain"
+        ],
+        "content": "<p><span class=\"h-card\"><a href=\"http://localtesting.pleroma.lol/users/lain\" class=\"u-url mention\">@<span>lain</span></a></span> #moo</p>",
+        "conversation": "tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation",
+        "id": "http://mastodon.example.org/users/admin/statuses/99512778738411822",
+        "inReplyTo": null,
+        "inReplyToAtomUri": null,
+        "published": "2018-02-12T14:08:20Z",
+        "sensitive": true,
+        "summary": "cw",
+        "tag": [
+            {
+                "href": "http://localtesting.pleroma.lol/users/lain",
+                "name": "@lain@localtesting.pleroma.lol",
+                "type": "Mention"
+            },
+            {
+                "href": "http://mastodon.example.org/tags/moo",
+                "name": "#moo",
+                "type": "Hashtag"
+            }
+        ],
+        "to": [
+            "https://www.w3.org/ns/activitystreams#Public"
+        ],
+        "type": "Note",
+        "url": "http://mastodon.example.org/@admin/99512778738411822"
+    },
+    "published": "2018-02-12T14:08:20Z",
+    "signature": {
+        "created": "2018-02-12T14:08:20Z",
+        "creator": "http://mastodon.example.org/users/admin#main-key",
+        "signatureValue": "rnNfcopkc6+Ju73P806popcfwrK9wGYHaJVG1/ZvrlEbWVDzaHjkXqj9Q3/xju5l8CSn9tvSgCCtPFqZsFQwn/pFIFUcw7ZWB2xi4bDm3NZ3S4XQ8JRaaX7og5hFxAhWkGhJhAkfxVnOg2hG+w2d/7d7vRVSC1vo5ip4erUaA/PkWusZvPIpxnRWoXaxJsFmVx0gJgjpJkYDyjaXUlp+jmaoseeZ4EPQUWqHLKJ59PRG0mg8j2xAjYH9nQaN14qMRmTGPxY8gfv/CUFcatA+8VJU9KEsJkDAwLVvglydNTLGrxpAJU78a2eaht0foV43XUIZGe3DKiJPgE+UOKGCJw==",
+        "type": "RsaSignature2017"
+    },
+    "to": [
+        "https://www.w3.org/ns/activitystreams#Public"
+    ],
+    "type": "Create"
+}
diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs
index caad9737a..375e74ad9 100644
--- a/test/web/activity_pub/transmogrifier_test.exs
+++ b/test/web/activity_pub/transmogrifier_test.exs
@@ -69,6 +69,13 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       assert object["sensitive"] == true
     end
 
+    test "it works for incoming notices with hashtags" do
+      data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Poison.decode!
+
+      {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
+      assert Enum.at(data["object"]["tag"], 2) == "moo"
+    end
+
     test "it works for incoming follow requests" do
       user = insert(:user)
       data = File.read!("test/fixtures/mastodon-follow-activity.json") |> Poison.decode!