activitypub: normalize the actor to ensure we have its URI
authorWilliam Pitcock <nenolod@dereferenced.org>
Sat, 19 May 2018 07:03:53 +0000 (07:03 +0000)
committerWilliam Pitcock <nenolod@dereferenced.org>
Sat, 19 May 2018 08:28:28 +0000 (03:28 -0500)
lib/pleroma/plugs/http_signature.ex
lib/pleroma/web/activity_pub/utils.ex
lib/pleroma/web/federator/federator.ex
lib/pleroma/web/http_signatures/http_signatures.ex

index efde652f52f37893f9bbc49a8d3d40707b6a7f6e..2d0e10cad725d6a3e726bfe8e6bbc05a75e36cb7 100644 (file)
@@ -1,5 +1,6 @@
 defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
   alias Pleroma.Web.HTTPSignatures
+  alias Pleroma.Web.ActivityPub.Utils
   import Plug.Conn
   require Logger
 
@@ -12,7 +13,7 @@ defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
   end
 
   def call(conn, _opts) do
-    user = conn.params["actor"]
+    user = Utils.normalize_actor(conn.params["actor"])
     Logger.debug("Checking sig for #{user}")
     [signature | _] = get_req_header(conn, "signature")
 
index f98545336f3efcc14998077b37803e7fc6ab4af4..d92db0d5f2d53b69ad8a88275d41c84cceb7a00d 100644 (file)
@@ -5,6 +5,22 @@ defmodule Pleroma.Web.ActivityPub.Utils do
   alias Ecto.{Changeset, UUID}
   import Ecto.Query
 
+  # Some implementations send the actor URI as the actor field, others send the entire actor object,
+  # so figure out what the actor's URI is based on what we have.
+  def normalize_actor(actor) do
+    cond do
+      is_binary(actor) ->
+        actor
+
+      is_map(actor) ->
+        actor["id"]
+    end
+  end
+
+  def normalize_params(params) do
+    Map.put(params, "actor", normalize_actor(params["actor"]))
+  end
+
   def make_json_ld_header do
     %{
       "@context" => [
index f84af2f15b95b3f50e37f5fad46450a44079d5fe..8ca530031dbc80708fa8d7c66b426b2eebbbd692 100644 (file)
@@ -5,6 +5,7 @@ defmodule Pleroma.Web.Federator do
   alias Pleroma.Web.{WebFinger, Websub}
   alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.ActivityPub.Transmogrifier
+  alias Pleroma.Web.ActivityPub.Utils
   require Logger
 
   @websub Application.get_env(:pleroma, :websub)
@@ -91,6 +92,8 @@ defmodule Pleroma.Web.Federator do
   def handle(:incoming_ap_doc, params) do
     Logger.info("Handling incoming AP activity")
 
+    params = Utils.normalize_params(params)
+
     with {:ok, _user} <- ap_enabled_actor(params["actor"]),
          nil <- Activity.get_by_ap_id(params["id"]),
          {:ok, _activity} <- Transmogrifier.handle_incoming(params) do
index 9035f5eb63b9f8a88f61b0b355018754a0046fe3..dd3f825db142f5197f87fe7d4cc4ae0553f461f3 100644 (file)
@@ -1,7 +1,7 @@
 # https://tools.ietf.org/html/draft-cavage-http-signatures-08
 defmodule Pleroma.Web.HTTPSignatures do
   alias Pleroma.User
-  alias Pleroma.Web.ActivityPub.ActivityPub
+  alias Pleroma.Web.ActivityPub.Utils
   require Logger
 
   def split_signature(sig) do
@@ -31,14 +31,14 @@ defmodule Pleroma.Web.HTTPSignatures do
   def validate_conn(conn) do
     # TODO: How to get the right key and see if it is actually valid for that request.
     # For now, fetch the key for the actor.
-    with actor_id <- conn.params["actor"],
+    with actor_id <- Utils.normalize_actor(conn.params["actor"]),
          {:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do
       if validate_conn(conn, public_key) do
         true
       else
         Logger.debug("Could not validate, re-fetching user and trying one more time")
         # Fetch user anew and try one more time
-        with actor_id <- conn.params["actor"],
+        with actor_id <- Utils.normalize_actor(conn.params["actor"]),
              {:ok, _user} <- ActivityPub.make_user_from_ap_id(actor_id),
              {:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do
           validate_conn(conn, public_key)