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.
This commit is contained in:
parent
1e3aff6ef1
commit
f84fb340b7
2 changed files with 20 additions and 9 deletions
|
@ -8,10 +8,16 @@ defmodule Pleroma.Signature do
|
||||||
alias Pleroma.Keys
|
alias Pleroma.Keys
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
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
|
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} <- User.get_public_key_for_ap_id(actor_id) do
|
||||||
{:ok, public_key}
|
{:ok, public_key}
|
||||||
else
|
else
|
||||||
|
@ -21,7 +27,8 @@ defmodule Pleroma.Signature do
|
||||||
end
|
end
|
||||||
|
|
||||||
def refetch_public_key(conn) do
|
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, _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} <- User.get_public_key_for_ap_id(actor_id) do
|
||||||
{:ok, public_key}
|
{:ok, public_key}
|
||||||
|
|
|
@ -31,25 +31,29 @@ defmodule Pleroma.SignatureTest do
|
||||||
65_537
|
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
|
describe "fetch_public_key/1" do
|
||||||
test "it returns key" do
|
test "it returns key" do
|
||||||
expected_result = {:ok, @rsa_public_key}
|
expected_result = {:ok, @rsa_public_key}
|
||||||
|
|
||||||
user = insert(:user, %{info: %{source_data: %{"publicKey" => @public_key}}})
|
user = insert(:user, %{info: %{source_data: %{"publicKey" => @public_key}}})
|
||||||
|
|
||||||
assert Signature.fetch_public_key(%Plug.Conn{params: %{"actor" => user.ap_id}}) ==
|
assert Signature.fetch_public_key(make_fake_conn(user.ap_id)) == expected_result
|
||||||
expected_result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns error when not found user" do
|
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}
|
{:error, :error}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns error if public key is empty" do
|
test "it returns error if public key is empty" do
|
||||||
user = insert(:user, %{info: %{source_data: %{"publicKey" => %{}}}})
|
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}
|
{:error, :error}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -58,12 +62,12 @@ defmodule Pleroma.SignatureTest do
|
||||||
test "it returns key" do
|
test "it returns key" do
|
||||||
ap_id = "https://mastodon.social/users/lambadalambda"
|
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}
|
{:ok, @rsa_public_key}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns error when not found user" do
|
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}}
|
{:error, {:error, :ok}}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue