Pleroma.User: Add rel=me to URLs where it linkbacks to the profile
authorHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Mon, 11 Feb 2019 21:27:02 +0000 (22:27 +0100)
committerHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Sat, 2 Mar 2019 04:36:48 +0000 (05:36 +0100)
lib/pleroma/user.ex
lib/pleroma/web/rel_me.ex [new file with mode: 0644]

index d58274508afa1e601edb0e7da170a79725f169af..b5461327493e1d6d735143a79a6124cb06a3acb3 100644 (file)
@@ -22,6 +22,7 @@ defmodule Pleroma.User do
   alias Pleroma.Web.OAuth
   alias Pleroma.Web.ActivityPub.Utils
   alias Pleroma.Web.ActivityPub.ActivityPub
+  alias Pleroma.Web.RelMe
 
   require Logger
 
@@ -1202,8 +1203,14 @@ defmodule Pleroma.User do
         {String.trim(name, ":"), url}
       end)
 
+    # TODO: get profile URLs other than user.ap_id
+    profile_urls = user[:ap_id]
+
     bio
-    |> CommonUtils.format_input("text/plain", mentions_format: :full)
+    |> CommonUtils.format_input("text/plain", %{
+      mentions_format: :full,
+      rel: &RelMe.maybe_put_rel_me(&1, profile_urls)
+    })
     |> elem(0)
     |> Formatter.emojify(emoji)
   end
diff --git a/lib/pleroma/web/rel_me.ex b/lib/pleroma/web/rel_me.ex
new file mode 100644 (file)
index 0000000..b23c499
--- /dev/null
@@ -0,0 +1,46 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.RelMe do
+  @hackney_options [
+    pool: :media,
+    timeout: 2_000,
+    recv_timeout: 2_000,
+    max_body: 2_000_000
+  ]
+
+  def parse(nil), do: {:error, "No URL provided"}
+
+  if Mix.env() == :test do
+    def parse(url), do: parse_url(url)
+  else
+    def parse(url) do
+      Cachex.fetch!(:rel_me_cache, url, fn _ ->
+        {:commit, parse_url(url)}
+      end)
+    rescue
+      e -> {:error, "Cachex error: #{inspect(e)}"}
+    end
+  end
+
+  defp parse_url(url) do
+    {:ok, %Tesla.Env{body: html}} = Pleroma.HTTP.get(url, [], adapter: @hackney_options)
+
+    Floki.attribute(html, "link[rel=me]", "href") ++ Floki.attribute(html, "a[rel=me]", "href")
+  rescue
+    e -> {:error, "Parsing error: #{inspect(e)}"}
+  end
+
+  def maybe_put_rel_me("http" <> _ = target_page, urls) when not is_nil(urls) do
+    if Enum.any?(parse(target_page), fn x -> x in urls end) do
+      "rel=\"me\" "
+    else
+      ""
+    end
+  end
+
+  def maybe_put_rel_me(_, _) do
+    ""
+  end
+end