fix: Fix various bugs with following
This commit is contained in:
parent
90a158c380
commit
54bc877f0a
6 changed files with 35 additions and 9 deletions
|
|
@ -10,6 +10,23 @@ defmodule ActivityPub.Headers do
|
|||
]
|
||||
|
||||
def signing_headers(method, url, body, actor_url, private_key) do
|
||||
url = case url do
|
||||
url when is_struct(url, URI) ->
|
||||
url
|
||||
url when is_binary(url) ->
|
||||
URI.parse(url)
|
||||
end
|
||||
|
||||
private_key = case private_key do
|
||||
"-----BEGIN" <> _ = key_pem ->
|
||||
key_pem
|
||||
|> :public_key.pem_decode()
|
||||
|> hd()
|
||||
|> :public_key.pem_entry_decode()
|
||||
private_key ->
|
||||
private_key
|
||||
end
|
||||
|
||||
method = String.downcase("#{method}")
|
||||
date = DateTime.utc_now() |> Calendar.strftime(@http_date_format)
|
||||
host = url.host
|
||||
|
|
@ -35,9 +52,11 @@ defmodule ActivityPub.Headers do
|
|||
end
|
||||
|
||||
def verify(method, path, headers, actor_fetcher \\ &fetch_actor_key/1) do
|
||||
dbg(headers)
|
||||
|
||||
{_key, signature_header} = Enum.find(headers, fn {key, _} -> key == "signature" end)
|
||||
|
||||
signature_kv = SignatureSplitter.split(signature_header)
|
||||
signature_kv = SignatureSplitter.split(signature_header) |> dbg()
|
||||
key_id = find_value(signature_kv, "keyId")
|
||||
signature = signature_kv |> find_value("signature") |> Base.decode64!()
|
||||
signing_text_headers = signature_kv |> find_value("headers") |> String.split(" ")
|
||||
|
|
@ -65,6 +84,7 @@ defmodule ActivityPub.Headers do
|
|||
value = find_value(header_pairs, header_name)
|
||||
"#{header_name}: #{value}\n"
|
||||
end)
|
||||
|> String.trim()
|
||||
end
|
||||
|
||||
def split_signature_header(signature_header) do
|
||||
|
|
@ -79,6 +99,8 @@ defmodule ActivityPub.Headers do
|
|||
end
|
||||
|
||||
defp find_value(headers, key) do
|
||||
key = String.downcase(key)
|
||||
|
||||
Enum.find_value(headers, fn {key_candidate, value} ->
|
||||
String.downcase(key_candidate) == key && value
|
||||
end)
|
||||
|
|
@ -90,7 +112,7 @@ defmodule ActivityPub.Headers do
|
|||
key_map = body["publicKey"]
|
||||
|
||||
if key_map["id"] == key_id do
|
||||
[public_key | _] =
|
||||
public_key =
|
||||
:public_key.pem_decode(key_map["publicKeyPem"])
|
||||
|> hd()
|
||||
|> :public_key.pem_entry_decode()
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ defmodule Postland.Activities do
|
|||
def cause_effects(%Activity{actor_id: actor_id, type: "Accept", data: %{"object" => %{"type" => "Follow"}}} = activity) do
|
||||
case Follows.get(Postland.my_actor_id(), actor_id) do
|
||||
nil ->
|
||||
# TODO: Need to handle the scenario where the we're following has an alias (/@foobar becomes /users/foobar by the time
|
||||
# they Accept)
|
||||
Logger.warning("Got accept for a follow we don't have in the db: #{actor_id}")
|
||||
|
||||
{:ok, activity}
|
||||
|
|
@ -50,5 +52,5 @@ defmodule Postland.Activities do
|
|||
end
|
||||
end
|
||||
|
||||
def cause_effects(activity), do: activity
|
||||
def cause_effects(activity), do: {:ok, activity}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ defmodule Postland.Follows do
|
|||
encoded_followee = Base.url_encode64(to_actor_id)
|
||||
encoded_follower = Base.url_encode64(Postland.my_actor_id())
|
||||
|
||||
actor = ActivityPub.fetch_actor(to_actor_id)
|
||||
{:ok, actor} = ActivityPub.fetch_actor(to_actor_id)
|
||||
inbox = Map.get(actor, "inbox")
|
||||
follow_request = %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ defmodule PostlandWeb.ActorController do
|
|||
use PostlandWeb, :controller
|
||||
|
||||
def get(conn, _params) do
|
||||
render(conn, :actor, %{})
|
||||
conn
|
||||
|> Plug.Conn.put_resp_header("content-type", "application/activity+json")
|
||||
|> render(:actor, %{})
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ defmodule PostlandWeb.InboxController do
|
|||
if Headers.verify(conn.method, conn.request_path, conn.req_headers) do
|
||||
case Activities.process_activity(params) do
|
||||
{:ok, _activity} ->
|
||||
render(conn, :ok)
|
||||
Plug.Conn.send_resp(conn, 200, Jason.encode!(params))
|
||||
error ->
|
||||
Logger.error(error)
|
||||
render(conn, :unprocessable_entity)
|
||||
Plug.Conn.send_resp(conn, 422, "unprocessable entity")
|
||||
end
|
||||
else
|
||||
render(conn, :forbidden)
|
||||
Plug.Conn.send_resp(conn, 403, "forbidden")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ defmodule PostlandWeb.Router do
|
|||
get "/.well-known/webfinger", WebfingerController, :get
|
||||
|
||||
get "/actor", ActorController, :get
|
||||
get "/inbox", InboxController, :post
|
||||
post "/inbox", InboxController, :post
|
||||
get "/outbox", OutboxController, :get
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue