Merge remote-tracking branch 'upstream/develop' into earmark
[akkoma] / lib / pleroma / web / web_finger.ex
index 15002b29fab6bb038747b4ff4909d585a12386e5..21b10e654a6692bc4046de0efb6c027a9dfc45f4 100644 (file)
@@ -94,52 +94,56 @@ defmodule Pleroma.Web.WebFinger do
     |> XmlBuilder.to_doc()
   end
 
-  defp webfinger_from_xml(doc) do
-    subject = XML.string_from_xpath("//Subject", doc)
-
-    subscribe_address =
-      ~s{//Link[@rel="http://ostatus.org/schema/1.0/subscribe"]/@template}
-      |> XML.string_from_xpath(doc)
-
-    ap_id =
-      ~s{//Link[@rel="self" and @type="application/activity+json"]/@href}
-      |> XML.string_from_xpath(doc)
-
-    data = %{
-      "subject" => subject,
-      "subscribe_address" => subscribe_address,
-      "ap_id" => ap_id
-    }
+  defp webfinger_from_xml(body) do
+    with {:ok, doc} <- XML.parse_document(body) do
+      subject = XML.string_from_xpath("//Subject", doc)
+
+      subscribe_address =
+        ~s{//Link[@rel="http://ostatus.org/schema/1.0/subscribe"]/@template}
+        |> XML.string_from_xpath(doc)
+
+      ap_id =
+        ~s{//Link[@rel="self" and @type="application/activity+json"]/@href}
+        |> XML.string_from_xpath(doc)
+
+      data = %{
+        "subject" => subject,
+        "subscribe_address" => subscribe_address,
+        "ap_id" => ap_id
+      }
 
-    {:ok, data}
+      {:ok, data}
+    end
   end
 
-  defp webfinger_from_json(doc) do
-    data =
-      Enum.reduce(doc["links"], %{"subject" => doc["subject"]}, fn link, data ->
-        case {link["type"], link["rel"]} do
-          {"application/activity+json", "self"} ->
-            Map.put(data, "ap_id", link["href"])
+  defp webfinger_from_json(body) do
+    with {:ok, doc} <- Jason.decode(body) do
+      data =
+        Enum.reduce(doc["links"], %{"subject" => doc["subject"]}, fn link, data ->
+          case {link["type"], link["rel"]} do
+            {"application/activity+json", "self"} ->
+              Map.put(data, "ap_id", link["href"])
 
-          {"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"", "self"} ->
-            Map.put(data, "ap_id", link["href"])
+            {"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"", "self"} ->
+              Map.put(data, "ap_id", link["href"])
 
-          {nil, "http://ostatus.org/schema/1.0/subscribe"} ->
-            Map.put(data, "subscribe_address", link["template"])
+            {nil, "http://ostatus.org/schema/1.0/subscribe"} ->
+              Map.put(data, "subscribe_address", link["template"])
 
-          _ ->
-            Logger.debug("Unhandled type: #{inspect(link["type"])}")
-            data
-        end
-      end)
+            _ ->
+              Logger.debug("Unhandled type: #{inspect(link["type"])}")
+              data
+          end
+        end)
 
-    {:ok, data}
+      {:ok, data}
+    end
   end
 
   def get_template_from_xml(body) do
     xpath = "//Link[@rel='lrdd']/@template"
 
-    with doc when doc != :error <- XML.parse_document(body),
+    with {:ok, doc} <- XML.parse_document(body),
          template when template != nil <- XML.string_from_xpath(xpath, doc) do
       {:ok, template}
     end
@@ -192,15 +196,23 @@ defmodule Pleroma.Web.WebFinger do
              address,
              [{"accept", "application/xrd+xml,application/jrd+json"}]
            ),
-         {:ok, %{status: status, body: body}} when status in 200..299 <- response do
-      doc = XML.parse_document(body)
-
-      if doc != :error do
-        webfinger_from_xml(doc)
-      else
-        with {:ok, doc} <- Jason.decode(body) do
-          webfinger_from_json(doc)
-        end
+         {:ok, %{status: status, body: body, headers: headers}} when status in 200..299 <-
+           response do
+      case List.keyfind(headers, "content-type", 0) do
+        {_, content_type} ->
+          case Plug.Conn.Utils.media_type(content_type) do
+            {:ok, "application", subtype, _} when subtype in ~w(xrd+xml xml) ->
+              webfinger_from_xml(body)
+
+            {:ok, "application", subtype, _} when subtype in ~w(jrd+json json) ->
+              webfinger_from_json(body)
+
+            _ ->
+              {:error, {:content_type, content_type}}
+          end
+
+        _ ->
+          {:error, {:content_type, nil}}
       end
     else
       e ->