From a44595bb9990a96d2937dfbfd4b2ac1b839bde56 Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sun, 22 Aug 2021 12:19:47 +0200 Subject: [PATCH] Implement state_ids federation endpoint --- lib/matrix_server/key_server.ex | 2 -- lib/matrix_server/room_server.ex | 26 +++++++++++++++++++ .../federation/authenticate_server.ex | 1 - .../controllers/event_controller.ex | 24 ++++++++++++++--- .../federation/http_client.ex | 11 +++++--- lib/matrix_server_web/router.ex | 1 + 6 files changed, 56 insertions(+), 9 deletions(-) diff --git a/lib/matrix_server/key_server.ex b/lib/matrix_server/key_server.ex index fe80da5..39b4e07 100644 --- a/lib/matrix_server/key_server.ex +++ b/lib/matrix_server/key_server.ex @@ -48,8 +48,6 @@ defmodule MatrixServer.KeyServer do object = Map.drop(object, [:signatures, :unsigned]) with {:ok, json} <- MatrixServer.encode_canonical_json(object) do - IO.puts(json) - signature = json |> :enacl.sign_detached(private_key) diff --git a/lib/matrix_server/room_server.ex b/lib/matrix_server/room_server.ex index 11fa69b..a9a393a 100644 --- a/lib/matrix_server/room_server.ex +++ b/lib/matrix_server/room_server.ex @@ -60,10 +60,16 @@ defmodule MatrixServer.RoomServer do GenServer.call(pid, {:server_in_room, domain}) end + @spec get_state_at_event(pid(), Event.t()) :: {[Event.t()], [Event.t()]} def get_state_at_event(pid, event) do GenServer.call(pid, {:get_state_at_event, event}) end + @spec get_state_ids_at_event(pid(), Event.t()) :: {[String.t()], [String.t()]} + def get_state_ids_at_event(pid, event) do + GenServer.call(pid, {:get_state_ids_at_event, event}) + end + ### Implementation @impl true @@ -128,6 +134,26 @@ defmodule MatrixServer.RoomServer do {:reply, {state_events, auth_chain}, state} end + def handle_call({:get_state_ids_at_event, %Event{room_id: room_id} = event}, _from, state) do + room_events = + Event + |> where([e], e.room_id == ^room_id) + |> select([e], {e.event_id, e}) + |> Repo.all() + |> Enum.into(%{}) + + state_set = StateResolution.resolve(event, false) + state_events = Enum.map(state_set, fn {_, %Event{event_id: event_id}} -> event_id end) + + auth_chain = + state_set + |> Map.values() + |> StateResolution.full_auth_chain(room_events) + |> MapSet.to_list() + + {:reply, {state_events, auth_chain}, state} + end + defp create_room_insert_events(room, account, %CreateRoom{ room_version: room_version, preset: preset, diff --git a/lib/matrix_server_web/federation/authenticate_server.ex b/lib/matrix_server_web/federation/authenticate_server.ex index 247af30..b81a0ed 100644 --- a/lib/matrix_server_web/federation/authenticate_server.ex +++ b/lib/matrix_server_web/federation/authenticate_server.ex @@ -49,7 +49,6 @@ defmodule MatrixServerWeb.Federation.AuthenticateServer do ServerKeyInfo.with_fresh_signing_keys(origin) do Enum.find_value(keys, false, fn %SigningKey{signing_key: signing_key} -> with {:ok, decoded_key} <- MatrixServer.decode_base64(signing_key) do - IO.puts(encoded_object) MatrixServer.sign_verify(raw_sig, encoded_object, decoded_key) else _ -> false diff --git a/lib/matrix_server_web/federation/controllers/event_controller.ex b/lib/matrix_server_web/federation/controllers/event_controller.ex index 091a099..5a7d05e 100644 --- a/lib/matrix_server_web/federation/controllers/event_controller.ex +++ b/lib/matrix_server_web/federation/controllers/event_controller.ex @@ -43,6 +43,22 @@ defmodule MatrixServerWeb.Federation.EventController do "event_id" => event_id, "room_id" => room_id }) do + get_state_or_state_ids(conn, :state, origin, event_id, room_id) + end + + def state(conn, _), do: put_error(conn, :missing_param) + + def state_ids(%Plug.Conn{assigns: %{origin: origin}} = conn, %{ + "event_id" => event_id, + "room_id" => room_id + }) do + get_state_or_state_ids(conn, :state_ids, origin, event_id, room_id) + end + + def state_ids(conn, _), do: put_error(conn, :missing_param) + + @spec get_state_or_state_ids(Plug.Conn.t(), :state | :state_ids, String.t(), String.t(), String.t()) :: Plug.Conn.t() + defp get_state_or_state_ids(conn, state_or_state_ids, origin, event_id, room_id) do query = Event |> where([e], e.event_id == ^event_id and e.room_id == ^room_id) @@ -53,7 +69,11 @@ defmodule MatrixServerWeb.Federation.EventController do case RoomServer.get_room_server(room) do {:ok, pid} -> if RoomServer.server_in_room(pid, origin) do - {state_events, auth_chain} = RoomServer.get_state_at_event(pid, event) + {state_events, auth_chain} = + case state_or_state_ids do + :state -> RoomServer.get_state_at_event(pid, event) + :state_ids -> RoomServer.get_state_ids_at_event(pid, event) + end data = %{ auth_chain: auth_chain, @@ -75,6 +95,4 @@ defmodule MatrixServerWeb.Federation.EventController do put_error(conn, :not_found, "Event or room not found.") end end - - def state(conn, _), do: put_error(conn, :missing_param) end diff --git a/lib/matrix_server_web/federation/http_client.ex b/lib/matrix_server_web/federation/http_client.ex index a923952..fff2920 100644 --- a/lib/matrix_server_web/federation/http_client.ex +++ b/lib/matrix_server_web/federation/http_client.ex @@ -73,14 +73,19 @@ defmodule MatrixServerWeb.Federation.HTTPClient do Tesla.get(client, path) end + def get_state_ids(client, room_id, event_id) do + path = + RouteHelpers.event_path(Endpoint, :state_ids, room_id) |> Tesla.build_url(event_id: event_id) + + Tesla.get(client, path) + end + defp tesla_request(method, client, path, request_schema) do with {:ok, %Tesla.Env{body: body}} <- Tesla.request(client, url: path, method: method), %Ecto.Changeset{valid?: true} = cs <- apply(request_schema, :changeset, [body]) do {:ok, Ecto.Changeset.apply_changes(cs)} else - x -> - IO.inspect(x) - :error + _ -> :error end end end diff --git a/lib/matrix_server_web/router.ex b/lib/matrix_server_web/router.ex index d3d30e2..5bd6f3f 100644 --- a/lib/matrix_server_web/router.ex +++ b/lib/matrix_server_web/router.ex @@ -66,6 +66,7 @@ defmodule MatrixServerWeb.Router do get "/query/profile", QueryController, :profile get "/event/:event_id", EventController, :event get "/state/:room_id", EventController, :state + get "/state_ids/:room_id", EventController, :state_ids end end