From 39fd4d7639a0ab47bc5ae3839b10701fc301a1be Mon Sep 17 00:00:00 2001
From: lain <lain@soykaf.club>
Date: Mon, 19 Oct 2020 15:40:50 +0200
Subject: [PATCH 1/2] Transmogrifier: Downcase incoming Hashtags

Also, set sensitive to true if we have an nsfw hashtag present.
---
 .../web/activity_pub/transmogrifier.ex        |  9 ++-
 .../fixtures/mastodon-post-activity-nsfw.json | 68 +++++++++++++++++++
 .../web/activity_pub/transmogrifier_test.exs  | 10 +++
 3 files changed, 85 insertions(+), 2 deletions(-)
 create mode 100644 test/fixtures/mastodon-post-activity-nsfw.json

diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index d7dd9fe6b..2f51f9e39 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -40,6 +40,7 @@ def fix_object(object, options \\ []) do
     |> fix_in_reply_to(options)
     |> fix_emoji
     |> fix_tag
+    |> set_sensitive
     |> fix_content_map
     |> fix_addressing
     |> fix_summary
@@ -313,7 +314,11 @@ def fix_tag(%{"tag" => tag} = object) when is_list(tag) do
     tags =
       tag
       |> Enum.filter(fn data -> data["type"] == "Hashtag" and data["name"] end)
-      |> Enum.map(fn data -> String.slice(data["name"], 1..-1) end)
+      |> Enum.map(fn %{"name" => name} ->
+        name
+        |> String.slice(1..-1)
+        |> String.downcase()
+      end)
 
     Map.put(object, "tag", tag ++ tags)
   end
@@ -927,7 +932,7 @@ def set_conversation(object) do
     Map.put(object, "conversation", object["context"])
   end
 
-  def set_sensitive(%{"sensitive" => true} = object) do
+  def set_sensitive(%{"sensitive" => _} = object) do
     object
   end
 
diff --git a/test/fixtures/mastodon-post-activity-nsfw.json b/test/fixtures/mastodon-post-activity-nsfw.json
new file mode 100644
index 000000000..70729a1bd
--- /dev/null
+++ b/test/fixtures/mastodon-post-activity-nsfw.json
@@ -0,0 +1,68 @@
+{
+    "@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#",
+            "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",
+        "summary": "cw",
+        "tag": [
+            {
+                "href": "http://localtesting.pleroma.lol/users/lain",
+                "name": "@lain@localtesting.pleroma.lol",
+                "type": "Mention"
+            },
+            {
+                "href": "http://mastodon.example.org/tags/nsfw",
+                "name": "#NSFW",
+                "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/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs
index 561674f01..8d8f63cc1 100644
--- a/test/pleroma/web/activity_pub/transmogrifier_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs
@@ -206,6 +206,16 @@ test "it works for incoming notices" do
       assert user.note_count == 1
     end
 
+    test "it works for incoming notices without the sensitive property but an nsfw hashtag" do
+      data = File.read!("test/fixtures/mastodon-post-activity-nsfw.json") |> Poison.decode!()
+
+      {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
+
+      object_data = Object.normalize(data["object"], false).data
+
+      assert object_data["sensitive"] == true
+    end
+
     test "it works for incoming notices with hashtags" do
       data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Poison.decode!()
 

From e97b254c6bb798d200f381e5adbde2177bcbc0df Mon Sep 17 00:00:00 2001
From: lain <lain@soykaf.club>
Date: Mon, 19 Oct 2020 15:46:24 +0200
Subject: [PATCH 2/2] Transmogrifier: Refactor and unify incoming tag handling

---
 lib/pleroma/web/activity_pub/transmogrifier.ex | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 2f51f9e39..39c8f7e39 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -323,14 +323,12 @@ def fix_tag(%{"tag" => tag} = object) when is_list(tag) do
     Map.put(object, "tag", tag ++ tags)
   end
 
-  def fix_tag(%{"tag" => %{"type" => "Hashtag", "name" => hashtag} = tag} = object) do
-    combined = [tag, String.slice(hashtag, 1..-1)]
-
-    Map.put(object, "tag", combined)
+  def fix_tag(%{"tag" => %{} = tag} = object) do
+    object
+    |> Map.put("tag", [tag])
+    |> fix_tag
   end
 
-  def fix_tag(%{"tag" => %{} = tag} = object), do: Map.put(object, "tag", [tag])
-
   def fix_tag(object), do: object
 
   # content map usually only has one language so this will do for now.