Browse Source

http signatures: derive actor ID from key ID.

Almost all AP servers return their key ID as the actor URI with #main-key
added.  Hubzilla, which doesn't, uses a URL which refers to the actor
anyway, so worst case, Hubzilla users get refetched.
tags/v1.1.4
Ariadne Conill 5 years ago
parent
commit
f84fb340b7
2 changed files with 20 additions and 9 deletions
  1. +10
    -3
      lib/pleroma/signature.ex
  2. +10
    -6
      test/signature_test.exs

+ 10
- 3
lib/pleroma/signature.ex View File

@@ -8,10 +8,16 @@ defmodule Pleroma.Signature do
alias Pleroma.Keys
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils

defp key_id_to_actor_id(key_id) do
URI.parse(key_id)
|> Map.put(:fragment, nil)
|> URI.to_string()
end

def fetch_public_key(conn) do
with actor_id <- Utils.get_ap_id(conn.params["actor"]),
with %{"keyId" => kid} <- HTTPSignatures.signature_for_conn(conn),
actor_id <- key_id_to_actor_id(kid),
{:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do
{:ok, public_key}
else
@@ -21,7 +27,8 @@ defmodule Pleroma.Signature do
end

def refetch_public_key(conn) do
with actor_id <- Utils.get_ap_id(conn.params["actor"]),
with %{"keyId" => kid} <- HTTPSignatures.signature_for_conn(conn),
actor_id <- key_id_to_actor_id(kid),
{:ok, _user} <- ActivityPub.make_user_from_ap_id(actor_id),
{:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do
{:ok, public_key}


+ 10
- 6
test/signature_test.exs View File

@@ -31,25 +31,29 @@ defmodule Pleroma.SignatureTest do
65_537
}

defp make_fake_signature(key_id), do: "keyId=\"#{key_id}\""

defp make_fake_conn(key_id),
do: %Plug.Conn{req_headers: %{"signature" => make_fake_signature(key_id <> "#main-key")}}

describe "fetch_public_key/1" do
test "it returns key" do
expected_result = {:ok, @rsa_public_key}

user = insert(:user, %{info: %{source_data: %{"publicKey" => @public_key}}})

assert Signature.fetch_public_key(%Plug.Conn{params: %{"actor" => user.ap_id}}) ==
expected_result
assert Signature.fetch_public_key(make_fake_conn(user.ap_id)) == expected_result
end

test "it returns error when not found user" do
assert Signature.fetch_public_key(%Plug.Conn{params: %{"actor" => "test-ap_id"}}) ==
assert Signature.fetch_public_key(make_fake_conn("test-ap_id")) ==
{:error, :error}
end

test "it returns error if public key is empty" do
user = insert(:user, %{info: %{source_data: %{"publicKey" => %{}}}})

assert Signature.fetch_public_key(%Plug.Conn{params: %{"actor" => user.ap_id}}) ==
assert Signature.fetch_public_key(make_fake_conn(user.ap_id)) ==
{:error, :error}
end
end
@@ -58,12 +62,12 @@ defmodule Pleroma.SignatureTest do
test "it returns key" do
ap_id = "https://mastodon.social/users/lambadalambda"

assert Signature.refetch_public_key(%Plug.Conn{params: %{"actor" => ap_id}}) ==
assert Signature.refetch_public_key(make_fake_conn(ap_id)) ==
{:ok, @rsa_public_key}
end

test "it returns error when not found user" do
assert Signature.refetch_public_key(%Plug.Conn{params: %{"actor" => "test-ap_id"}}) ==
assert Signature.refetch_public_key(make_fake_conn("test-ap_id")) ==
{:error, {:error, :ok}}
end
end


Loading…
Cancel
Save