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
|
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}")
|
method = String.downcase("#{method}")
|
||||||
date = DateTime.utc_now() |> Calendar.strftime(@http_date_format)
|
date = DateTime.utc_now() |> Calendar.strftime(@http_date_format)
|
||||||
host = url.host
|
host = url.host
|
||||||
|
|
@ -35,9 +52,11 @@ defmodule ActivityPub.Headers do
|
||||||
end
|
end
|
||||||
|
|
||||||
def verify(method, path, headers, actor_fetcher \\ &fetch_actor_key/1) do
|
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)
|
{_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")
|
key_id = find_value(signature_kv, "keyId")
|
||||||
signature = signature_kv |> find_value("signature") |> Base.decode64!()
|
signature = signature_kv |> find_value("signature") |> Base.decode64!()
|
||||||
signing_text_headers = signature_kv |> find_value("headers") |> String.split(" ")
|
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)
|
value = find_value(header_pairs, header_name)
|
||||||
"#{header_name}: #{value}\n"
|
"#{header_name}: #{value}\n"
|
||||||
end)
|
end)
|
||||||
|
|> String.trim()
|
||||||
end
|
end
|
||||||
|
|
||||||
def split_signature_header(signature_header) do
|
def split_signature_header(signature_header) do
|
||||||
|
|
@ -79,6 +99,8 @@ defmodule ActivityPub.Headers do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp find_value(headers, key) do
|
defp find_value(headers, key) do
|
||||||
|
key = String.downcase(key)
|
||||||
|
|
||||||
Enum.find_value(headers, fn {key_candidate, value} ->
|
Enum.find_value(headers, fn {key_candidate, value} ->
|
||||||
String.downcase(key_candidate) == key && value
|
String.downcase(key_candidate) == key && value
|
||||||
end)
|
end)
|
||||||
|
|
@ -90,7 +112,7 @@ defmodule ActivityPub.Headers do
|
||||||
key_map = body["publicKey"]
|
key_map = body["publicKey"]
|
||||||
|
|
||||||
if key_map["id"] == key_id do
|
if key_map["id"] == key_id do
|
||||||
[public_key | _] =
|
public_key =
|
||||||
:public_key.pem_decode(key_map["publicKeyPem"])
|
:public_key.pem_decode(key_map["publicKeyPem"])
|
||||||
|> hd()
|
|> hd()
|
||||||
|> :public_key.pem_entry_decode()
|
|> :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
|
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
|
case Follows.get(Postland.my_actor_id(), actor_id) do
|
||||||
nil ->
|
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}")
|
Logger.warning("Got accept for a follow we don't have in the db: #{actor_id}")
|
||||||
|
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
|
|
@ -50,5 +52,5 @@ defmodule Postland.Activities do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def cause_effects(activity), do: activity
|
def cause_effects(activity), do: {:ok, activity}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ defmodule Postland.Follows do
|
||||||
encoded_followee = Base.url_encode64(to_actor_id)
|
encoded_followee = Base.url_encode64(to_actor_id)
|
||||||
encoded_follower = Base.url_encode64(Postland.my_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")
|
inbox = Map.get(actor, "inbox")
|
||||||
follow_request = %{
|
follow_request = %{
|
||||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ defmodule PostlandWeb.ActorController do
|
||||||
use PostlandWeb, :controller
|
use PostlandWeb, :controller
|
||||||
|
|
||||||
def get(conn, _params) do
|
def get(conn, _params) do
|
||||||
render(conn, :actor, %{})
|
conn
|
||||||
|
|> Plug.Conn.put_resp_header("content-type", "application/activity+json")
|
||||||
|
|> render(:actor, %{})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@ defmodule PostlandWeb.InboxController do
|
||||||
if Headers.verify(conn.method, conn.request_path, conn.req_headers) do
|
if Headers.verify(conn.method, conn.request_path, conn.req_headers) do
|
||||||
case Activities.process_activity(params) do
|
case Activities.process_activity(params) do
|
||||||
{:ok, _activity} ->
|
{:ok, _activity} ->
|
||||||
render(conn, :ok)
|
Plug.Conn.send_resp(conn, 200, Jason.encode!(params))
|
||||||
error ->
|
error ->
|
||||||
Logger.error(error)
|
Logger.error(error)
|
||||||
render(conn, :unprocessable_entity)
|
Plug.Conn.send_resp(conn, 422, "unprocessable entity")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
render(conn, :forbidden)
|
Plug.Conn.send_resp(conn, 403, "forbidden")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ defmodule PostlandWeb.Router do
|
||||||
get "/.well-known/webfinger", WebfingerController, :get
|
get "/.well-known/webfinger", WebfingerController, :get
|
||||||
|
|
||||||
get "/actor", ActorController, :get
|
get "/actor", ActorController, :get
|
||||||
get "/inbox", InboxController, :post
|
post "/inbox", InboxController, :post
|
||||||
get "/outbox", OutboxController, :get
|
get "/outbox", OutboxController, :get
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue