From 2bfae25a1ff735499e15cb431314503f34097a6b Mon Sep 17 00:00:00 2001
From: Ivan Tashkinov <ivantashkinov@gmail.com>
Date: Thu, 17 Jan 2019 18:03:49 +0300
Subject: [PATCH 1/2] [#491] Made user bio preserve full nicknames (nick@host).

---
 lib/pleroma/formatter.ex                      | 7 +++----
 test/formatter_test.exs                       | 4 ++--
 test/web/twitter_api/views/user_view_test.exs | 2 +-
 3 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex
index 4149265a2..024c6e117 100644
--- a/lib/pleroma/formatter.ex
+++ b/lib/pleroma/formatter.ex
@@ -142,12 +142,11 @@ defmodule Pleroma.Formatter do
               ap_id
             end
 
-          short_match = String.split(match, "@") |> tl() |> hd()
+          full_match = String.trim_leading(match, "@")
 
           {uuid,
-           "<span class='h-card'><a data-user='#{id}' class='u-url mention' href='#{ap_id}'>@<span>#{
-             short_match
-           }</span></a></span>"}
+           "<span class='h-card'><a data-user='#{id}' class='u-url mention' href='#{ap_id}'>" <>
+             "@<span>#{full_match}</span></a></span>"}
         end)
 
     {subs, uuid_text}
diff --git a/test/formatter_test.exs b/test/formatter_test.exs
index bd8844458..7040f1c27 100644
--- a/test/formatter_test.exs
+++ b/test/formatter_test.exs
@@ -150,7 +150,7 @@ defmodule Pleroma.FormatterTest do
           archaeme.id
         }' class='u-url mention' href='#{"https://archeme/@archa_eme_"}'>@<span>archa_eme_</span></a></span>, that is @daggsy. Also hello <span class='h-card'><a data-user='#{
           archaeme_remote.id
-        }' class='u-url mention' href='#{archaeme_remote.ap_id}'>@<span>archaeme</span></a></span>"
+        }' class='u-url mention' href='#{archaeme_remote.ap_id}'>@<span>archaeme@archae.me</span></a></span>"
 
       assert expected_text == Formatter.finalize({subs, text})
     end
@@ -168,7 +168,7 @@ defmodule Pleroma.FormatterTest do
       Enum.each(subs, fn {uuid, _} -> assert String.contains?(text, uuid) end)
 
       expected_text =
-        "<span class='h-card'><a data-user='#{mike.id}' class='u-url mention' href='#{mike.ap_id}'>@<span>mike</span></a></span> test"
+        "<span class='h-card'><a data-user='#{mike.id}' class='u-url mention' href='#{mike.ap_id}'>@<span>mike@osada.macgirvin.com</span></a></span> test"
 
       assert expected_text == Formatter.finalize({subs, text})
     end
diff --git a/test/web/twitter_api/views/user_view_test.exs b/test/web/twitter_api/views/user_view_test.exs
index 5f7481eb6..b8f1afa76 100644
--- a/test/web/twitter_api/views/user_view_test.exs
+++ b/test/web/twitter_api/views/user_view_test.exs
@@ -12,7 +12,7 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
   import Pleroma.Factory
 
   setup do
-    user = insert(:user, bio: "<span>Here's some html</span>")
+    user = insert(:user, bio: "<span>Here's some html,</span> @mention@domain.com")
     [user: user]
   end
 

From 65bb9b2fba7560df7331645db9839305c47dad11 Mon Sep 17 00:00:00 2001
From: Ivan Tashkinov <ivantashkinov@gmail.com>
Date: Fri, 18 Jan 2019 09:30:16 +0300
Subject: [PATCH 2/2] [#491] Made full nicknames be preserved in user links
 text only in Bio.

---
 lib/pleroma/formatter.ex                      | 11 ++++++++---
 lib/pleroma/user.ex                           | 15 ++++++++++++---
 lib/pleroma/web/common_api/utils.ex           | 14 ++++++++------
 test/formatter_test.exs                       |  6 +++---
 test/user_test.exs                            | 15 +++++++++++++++
 test/web/twitter_api/views/user_view_test.exs |  2 +-
 6 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex
index 024c6e117..37737853a 100644
--- a/lib/pleroma/formatter.ex
+++ b/lib/pleroma/formatter.ex
@@ -120,7 +120,7 @@ defmodule Pleroma.Formatter do
   end
 
   @doc "Adds the links to mentioned users"
-  def add_user_links({subs, text}, mentions) do
+  def add_user_links({subs, text}, mentions, options \\ []) do
     mentions =
       mentions
       |> Enum.sort_by(fn {name, _} -> -String.length(name) end)
@@ -142,11 +142,16 @@ defmodule Pleroma.Formatter do
               ap_id
             end
 
-          full_match = String.trim_leading(match, "@")
+          nickname =
+            if options[:format] == :full do
+              User.full_nickname(match)
+            else
+              User.local_nickname(match)
+            end
 
           {uuid,
            "<span class='h-card'><a data-user='#{id}' class='u-url mention' href='#{ap_id}'>" <>
-             "@<span>#{full_match}</span></a></span>"}
+             "@<span>#{nickname}</span></a></span>"}
         end)
 
     {subs, uuid_text}
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index a52e536d3..2dc3c8d56 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -447,8 +447,7 @@ defmodule Pleroma.User do
   def get_by_nickname(nickname) do
     Repo.get_by(User, nickname: nickname) ||
       if Regex.match?(~r(@#{Pleroma.Web.Endpoint.host()})i, nickname) do
-        [local_nickname, _] = String.split(nickname, "@")
-        Repo.get_by(User, nickname: local_nickname)
+        Repo.get_by(User, nickname: local_nickname(nickname))
       end
   end
 
@@ -990,7 +989,7 @@ defmodule Pleroma.User do
       end)
 
     bio
-    |> CommonUtils.format_input(mentions, tags, "text/plain")
+    |> CommonUtils.format_input(mentions, tags, "text/plain", user_links: [format: :full])
     |> Formatter.emojify(emoji)
   end
 
@@ -1041,6 +1040,16 @@ defmodule Pleroma.User do
     end
   end
 
+  def local_nickname(nickname_or_mention) do
+    nickname_or_mention
+    |> full_nickname()
+    |> String.split("@")
+    |> hd()
+  end
+
+  def full_nickname(nickname_or_mention),
+    do: String.trim_leading(nickname_or_mention, "@")
+
   def error_user(ap_id) do
     %User{
       name: ap_id,
diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex
index 7e30d224c..a36ab5c15 100644
--- a/lib/pleroma/web/common_api/utils.ex
+++ b/lib/pleroma/web/common_api/utils.ex
@@ -116,16 +116,18 @@ defmodule Pleroma.Web.CommonAPI.Utils do
     Enum.join([text | attachment_text], "<br>")
   end
 
+  def format_input(text, mentions, tags, format, options \\ [])
+
   @doc """
   Formatting text to plain text.
   """
-  def format_input(text, mentions, tags, "text/plain") do
+  def format_input(text, mentions, tags, "text/plain", options) do
     text
     |> Formatter.html_escape("text/plain")
     |> String.replace(~r/\r?\n/, "<br>")
     |> (&{[], &1}).()
     |> Formatter.add_links()
-    |> Formatter.add_user_links(mentions)
+    |> Formatter.add_user_links(mentions, options[:user_links] || [])
     |> Formatter.add_hashtag_links(tags)
     |> Formatter.finalize()
   end
@@ -133,24 +135,24 @@ defmodule Pleroma.Web.CommonAPI.Utils do
   @doc """
   Formatting text to html.
   """
-  def format_input(text, mentions, _tags, "text/html") do
+  def format_input(text, mentions, _tags, "text/html", options) do
     text
     |> Formatter.html_escape("text/html")
     |> (&{[], &1}).()
-    |> Formatter.add_user_links(mentions)
+    |> Formatter.add_user_links(mentions, options[:user_links] || [])
     |> Formatter.finalize()
   end
 
   @doc """
   Formatting text to markdown.
   """
-  def format_input(text, mentions, tags, "text/markdown") do
+  def format_input(text, mentions, tags, "text/markdown", options) do
     text
     |> Formatter.mentions_escape(mentions)
     |> Earmark.as_html!()
     |> Formatter.html_escape("text/html")
     |> (&{[], &1}).()
-    |> Formatter.add_user_links(mentions)
+    |> Formatter.add_user_links(mentions, options[:user_links] || [])
     |> Formatter.add_hashtag_links(tags)
     |> Formatter.finalize()
   end
diff --git a/test/formatter_test.exs b/test/formatter_test.exs
index 7040f1c27..2e717194b 100644
--- a/test/formatter_test.exs
+++ b/test/formatter_test.exs
@@ -124,7 +124,7 @@ defmodule Pleroma.FormatterTest do
   end
 
   describe "add_user_links" do
-    test "gives a replacement for user links" do
+    test "gives a replacement for user links, using local nicknames in user links text" do
       text = "@gsimg According to @archa_eme_, that is @daggsy. Also hello @archaeme@archae.me"
       gsimg = insert(:user, %{nickname: "gsimg"})
 
@@ -150,7 +150,7 @@ defmodule Pleroma.FormatterTest do
           archaeme.id
         }' class='u-url mention' href='#{"https://archeme/@archa_eme_"}'>@<span>archa_eme_</span></a></span>, that is @daggsy. Also hello <span class='h-card'><a data-user='#{
           archaeme_remote.id
-        }' class='u-url mention' href='#{archaeme_remote.ap_id}'>@<span>archaeme@archae.me</span></a></span>"
+        }' class='u-url mention' href='#{archaeme_remote.ap_id}'>@<span>archaeme</span></a></span>"
 
       assert expected_text == Formatter.finalize({subs, text})
     end
@@ -168,7 +168,7 @@ defmodule Pleroma.FormatterTest do
       Enum.each(subs, fn {uuid, _} -> assert String.contains?(text, uuid) end)
 
       expected_text =
-        "<span class='h-card'><a data-user='#{mike.id}' class='u-url mention' href='#{mike.ap_id}'>@<span>mike@osada.macgirvin.com</span></a></span> test"
+        "<span class='h-card'><a data-user='#{mike.id}' class='u-url mention' href='#{mike.ap_id}'>@<span>mike</span></a></span> test"
 
       assert expected_text == Formatter.finalize({subs, text})
     end
diff --git a/test/user_test.exs b/test/user_test.exs
index cfccce8d1..21a62483f 100644
--- a/test/user_test.exs
+++ b/test/user_test.exs
@@ -874,4 +874,19 @@ defmodule Pleroma.UserTest do
       Pleroma.Config.put([:instance, :account_activation_required], false)
     end
   end
+
+  describe "parse_bio/2" do
+    test "preserves hosts in user links text" do
+      remote_user = insert(:user, local: false, nickname: "nick@domain.com")
+      user = insert(:user)
+      bio = "A.k.a. @nick@domain.com"
+
+      expected_text =
+        "A.k.a. <span class='h-card'><a data-user='#{remote_user.id}' class='u-url mention' href='#{
+          remote_user.ap_id
+        }'>" <> "@<span>nick@domain.com</span></a></span>"
+
+      assert expected_text == User.parse_bio(bio, user)
+    end
+  end
 end
diff --git a/test/web/twitter_api/views/user_view_test.exs b/test/web/twitter_api/views/user_view_test.exs
index b8f1afa76..5f7481eb6 100644
--- a/test/web/twitter_api/views/user_view_test.exs
+++ b/test/web/twitter_api/views/user_view_test.exs
@@ -12,7 +12,7 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
   import Pleroma.Factory
 
   setup do
-    user = insert(:user, bio: "<span>Here's some html,</span> @mention@domain.com")
+    user = insert(:user, bio: "<span>Here's some html</span>")
     [user: user]
   end