Implement state_ids federation endpoint
This commit is contained in:
parent
ba3e290bf1
commit
a44595bb99
6 changed files with 56 additions and 9 deletions
|
@ -48,8 +48,6 @@ defmodule MatrixServer.KeyServer do
|
||||||
object = Map.drop(object, [:signatures, :unsigned])
|
object = Map.drop(object, [:signatures, :unsigned])
|
||||||
|
|
||||||
with {:ok, json} <- MatrixServer.encode_canonical_json(object) do
|
with {:ok, json} <- MatrixServer.encode_canonical_json(object) do
|
||||||
IO.puts(json)
|
|
||||||
|
|
||||||
signature =
|
signature =
|
||||||
json
|
json
|
||||||
|> :enacl.sign_detached(private_key)
|
|> :enacl.sign_detached(private_key)
|
||||||
|
|
|
@ -60,10 +60,16 @@ defmodule MatrixServer.RoomServer do
|
||||||
GenServer.call(pid, {:server_in_room, domain})
|
GenServer.call(pid, {:server_in_room, domain})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_state_at_event(pid(), Event.t()) :: {[Event.t()], [Event.t()]}
|
||||||
def get_state_at_event(pid, event) do
|
def get_state_at_event(pid, event) do
|
||||||
GenServer.call(pid, {:get_state_at_event, event})
|
GenServer.call(pid, {:get_state_at_event, event})
|
||||||
end
|
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
|
### Implementation
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@ -128,6 +134,26 @@ defmodule MatrixServer.RoomServer do
|
||||||
{:reply, {state_events, auth_chain}, state}
|
{:reply, {state_events, auth_chain}, state}
|
||||||
end
|
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{
|
defp create_room_insert_events(room, account, %CreateRoom{
|
||||||
room_version: room_version,
|
room_version: room_version,
|
||||||
preset: preset,
|
preset: preset,
|
||||||
|
|
|
@ -49,7 +49,6 @@ defmodule MatrixServerWeb.Federation.AuthenticateServer do
|
||||||
ServerKeyInfo.with_fresh_signing_keys(origin) do
|
ServerKeyInfo.with_fresh_signing_keys(origin) do
|
||||||
Enum.find_value(keys, false, fn %SigningKey{signing_key: signing_key} ->
|
Enum.find_value(keys, false, fn %SigningKey{signing_key: signing_key} ->
|
||||||
with {:ok, decoded_key} <- MatrixServer.decode_base64(signing_key) do
|
with {:ok, decoded_key} <- MatrixServer.decode_base64(signing_key) do
|
||||||
IO.puts(encoded_object)
|
|
||||||
MatrixServer.sign_verify(raw_sig, encoded_object, decoded_key)
|
MatrixServer.sign_verify(raw_sig, encoded_object, decoded_key)
|
||||||
else
|
else
|
||||||
_ -> false
|
_ -> false
|
||||||
|
|
|
@ -43,6 +43,22 @@ defmodule MatrixServerWeb.Federation.EventController do
|
||||||
"event_id" => event_id,
|
"event_id" => event_id,
|
||||||
"room_id" => room_id
|
"room_id" => room_id
|
||||||
}) do
|
}) 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 =
|
query =
|
||||||
Event
|
Event
|
||||||
|> where([e], e.event_id == ^event_id and e.room_id == ^room_id)
|
|> 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
|
case RoomServer.get_room_server(room) do
|
||||||
{:ok, pid} ->
|
{:ok, pid} ->
|
||||||
if RoomServer.server_in_room(pid, origin) do
|
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 = %{
|
data = %{
|
||||||
auth_chain: auth_chain,
|
auth_chain: auth_chain,
|
||||||
|
@ -75,6 +95,4 @@ defmodule MatrixServerWeb.Federation.EventController do
|
||||||
put_error(conn, :not_found, "Event or room not found.")
|
put_error(conn, :not_found, "Event or room not found.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def state(conn, _), do: put_error(conn, :missing_param)
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -73,14 +73,19 @@ defmodule MatrixServerWeb.Federation.HTTPClient do
|
||||||
Tesla.get(client, path)
|
Tesla.get(client, path)
|
||||||
end
|
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
|
defp tesla_request(method, client, path, request_schema) do
|
||||||
with {:ok, %Tesla.Env{body: body}} <- Tesla.request(client, url: path, method: method),
|
with {:ok, %Tesla.Env{body: body}} <- Tesla.request(client, url: path, method: method),
|
||||||
%Ecto.Changeset{valid?: true} = cs <- apply(request_schema, :changeset, [body]) do
|
%Ecto.Changeset{valid?: true} = cs <- apply(request_schema, :changeset, [body]) do
|
||||||
{:ok, Ecto.Changeset.apply_changes(cs)}
|
{:ok, Ecto.Changeset.apply_changes(cs)}
|
||||||
else
|
else
|
||||||
x ->
|
_ -> :error
|
||||||
IO.inspect(x)
|
|
||||||
:error
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -66,6 +66,7 @@ defmodule MatrixServerWeb.Router do
|
||||||
get "/query/profile", QueryController, :profile
|
get "/query/profile", QueryController, :profile
|
||||||
get "/event/:event_id", EventController, :event
|
get "/event/:event_id", EventController, :event
|
||||||
get "/state/:room_id", EventController, :state
|
get "/state/:room_id", EventController, :state
|
||||||
|
get "/state_ids/:room_id", EventController, :state_ids
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue