Add some documentation
This commit is contained in:
parent
a44595bb99
commit
9d40f8bc8b
5 changed files with 162 additions and 25 deletions
|
@ -1,4 +1,8 @@
|
||||||
defmodule MatrixServer do
|
defmodule MatrixServer do
|
||||||
|
@moduledoc """
|
||||||
|
Utility functions used throughout the project.
|
||||||
|
"""
|
||||||
|
|
||||||
alias MatrixServer.EncodableMap
|
alias MatrixServer.EncodableMap
|
||||||
|
|
||||||
@random_string_alphabet Enum.into(?a..?z, []) ++ Enum.into(?A..?Z, [])
|
@random_string_alphabet Enum.into(?a..?z, []) ++ Enum.into(?A..?Z, [])
|
||||||
|
@ -6,30 +10,49 @@ defmodule MatrixServer do
|
||||||
@ipv4_regex ~r/^(?<hostname>[^:]+)(?<port>:\d{1,5})?$/
|
@ipv4_regex ~r/^(?<hostname>[^:]+)(?<port>:\d{1,5})?$/
|
||||||
@dns_regex ~r/^[[:alnum:]-.]{1,255}$/
|
@dns_regex ~r/^[[:alnum:]-.]{1,255}$/
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the full MXID for a user's localpart, using the homeserver's
|
||||||
|
server name as the domain.
|
||||||
|
"""
|
||||||
@spec get_mxid(String.t()) :: String.t()
|
@spec get_mxid(String.t()) :: String.t()
|
||||||
def get_mxid(localpart) when is_binary(localpart) do
|
def get_mxid(localpart) when is_binary(localpart) do
|
||||||
"@#{localpart}:#{server_name()}"
|
"@#{localpart}:#{server_name()}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the homeserver's server name.
|
||||||
|
"""
|
||||||
@spec server_name() :: String.t()
|
@spec server_name() :: String.t()
|
||||||
def server_name do
|
def server_name do
|
||||||
Application.get_env(:matrix_server, :server_name)
|
Application.get_env(:matrix_server, :server_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get a regex to match a user's localpart.
|
||||||
|
"""
|
||||||
@spec localpart_regex() :: Regex.t()
|
@spec localpart_regex() :: Regex.t()
|
||||||
def localpart_regex, do: ~r/^([a-z0-9\._=\/])+$/
|
def localpart_regex, do: ~r/^([a-z0-9\._=\/])+$/
|
||||||
|
|
||||||
@spec random_string(pos_integer()) :: String.t()
|
@doc """
|
||||||
def random_string(length), do: random_string(length, @random_string_alphabet)
|
Get a random string of `length` length and using `alphabet`'s characters.
|
||||||
|
"""
|
||||||
@spec random_string(pos_integer(), Enum.t()) :: String.t()
|
@spec random_string(pos_integer(), Enum.t()) :: String.t()
|
||||||
def random_string(length, alphabet) when length >= 1 do
|
def random_string(length, alphabet \\ @random_string_alphabet) when length >= 1 do
|
||||||
for _ <- 1..length, into: "", do: <<Enum.random(alphabet)>>
|
for _ <- 1..length, into: "", do: <<Enum.random(alphabet)>>
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the homeserver's default room version.
|
||||||
|
"""
|
||||||
@spec default_room_version() :: String.t()
|
@spec default_room_version() :: String.t()
|
||||||
def default_room_version, do: "7"
|
def default_room_version, do: "7"
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the domain from an ID.
|
||||||
|
|
||||||
|
Return `nil` if no domain was found.
|
||||||
|
No validation on the domain is performed whatsoever.
|
||||||
|
"""
|
||||||
@spec get_domain(String.t()) :: String.t() | nil
|
@spec get_domain(String.t()) :: String.t() | nil
|
||||||
def get_domain(id) do
|
def get_domain(id) do
|
||||||
case String.split(id, ":", parts: 2) do
|
case String.split(id, ":", parts: 2) do
|
||||||
|
@ -38,6 +61,12 @@ defmodule MatrixServer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the localpart from a MXID.
|
||||||
|
|
||||||
|
Return `nil` if no localpart was found.
|
||||||
|
No validation on the localpart is performed whatsoever.
|
||||||
|
"""
|
||||||
@spec get_localpart(String.t()) :: String.t() | nil
|
@spec get_localpart(String.t()) :: String.t() | nil
|
||||||
def get_localpart(id) do
|
def get_localpart(id) do
|
||||||
with [part, _] <- String.split(id, ":", parts: 2),
|
with [part, _] <- String.split(id, ":", parts: 2),
|
||||||
|
@ -48,9 +77,12 @@ defmodule MatrixServer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# https://elixirforum.com/t/22709/9
|
@doc """
|
||||||
|
Check whether the given list contains duplicates.
|
||||||
|
"""
|
||||||
@spec has_duplicates?(list()) :: boolean()
|
@spec has_duplicates?(list()) :: boolean()
|
||||||
def has_duplicates?(list) do
|
def has_duplicates?(list) do
|
||||||
|
# https://elixirforum.com/t/22709/9
|
||||||
list
|
list
|
||||||
|> Enum.reduce_while(%MapSet{}, fn x, acc ->
|
|> Enum.reduce_while(%MapSet{}, fn x, acc ->
|
||||||
if MapSet.member?(acc, x), do: {:halt, false}, else: {:cont, MapSet.put(acc, x)}
|
if MapSet.member?(acc, x), do: {:halt, false}, else: {:cont, MapSet.put(acc, x)}
|
||||||
|
@ -58,15 +90,25 @@ defmodule MatrixServer do
|
||||||
|> is_boolean()
|
|> is_boolean()
|
||||||
end
|
end
|
||||||
|
|
||||||
# https://matrix.org/docs/spec/appendices#unpadded-base64
|
@doc """
|
||||||
|
Encode the given string using unpadded base64.
|
||||||
|
|
||||||
|
Unpadded base64 is the same as base64, except the "=" padding is removed.
|
||||||
|
"""
|
||||||
@spec encode_unpadded_base64(String.t()) :: String.t()
|
@spec encode_unpadded_base64(String.t()) :: String.t()
|
||||||
def encode_unpadded_base64(data) do
|
def encode_unpadded_base64(data) do
|
||||||
|
# https://matrix.org/docs/spec/appendices#unpadded-base64
|
||||||
data
|
data
|
||||||
|> Base.encode64()
|
|> Base.encode64()
|
||||||
|> String.trim_trailing("=")
|
|> String.trim_trailing("=")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Decode (possibly unpadded) base64.
|
@doc """
|
||||||
|
Decode the given base64 string.
|
||||||
|
|
||||||
|
The base64 is allowed to be unpadded, as specified in `encode_unpadded_base64`.
|
||||||
|
Return `:error` on decode error.
|
||||||
|
"""
|
||||||
@spec decode_base64(String.t()) :: {:ok, String.t()} | :error
|
@spec decode_base64(String.t()) :: {:ok, String.t()} | :error
|
||||||
def decode_base64(data) when is_binary(data) do
|
def decode_base64(data) when is_binary(data) do
|
||||||
rem = rem(String.length(data), 4)
|
rem = rem(String.length(data), 4)
|
||||||
|
@ -74,6 +116,13 @@ defmodule MatrixServer do
|
||||||
Base.decode64(padded_data)
|
Base.decode64(padded_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Encode the given map as canonical JSON.
|
||||||
|
|
||||||
|
See [the Matrix docs](https://matrix.org/docs/spec/appendices#canonical-json) for explanation
|
||||||
|
for canonical JSON.
|
||||||
|
Return an error if the map could not be encoded.
|
||||||
|
"""
|
||||||
@spec encode_canonical_json(map()) :: {:ok, String.t()} | {:error, Jason.EncodeError.t()}
|
@spec encode_canonical_json(map()) :: {:ok, String.t()} | {:error, Jason.EncodeError.t()}
|
||||||
def encode_canonical_json(object) do
|
def encode_canonical_json(object) do
|
||||||
object
|
object
|
||||||
|
@ -81,9 +130,13 @@ defmodule MatrixServer do
|
||||||
|> Jason.encode()
|
|> Jason.encode()
|
||||||
end
|
end
|
||||||
|
|
||||||
# https://stackoverflow.com/questions/41523762/41671211
|
@doc """
|
||||||
|
Convert a struct to a map, removing any schema or association fields,
|
||||||
|
as well as fields that have `nil` values.
|
||||||
|
"""
|
||||||
@spec to_serializable_map(struct()) :: map()
|
@spec to_serializable_map(struct()) :: map()
|
||||||
def to_serializable_map(struct) do
|
def to_serializable_map(struct) do
|
||||||
|
# https://stackoverflow.com/questions/41523762/41671211
|
||||||
association_fields =
|
association_fields =
|
||||||
if Kernel.function_exported?(struct.__struct__, :__schema__, 1) do
|
if Kernel.function_exported?(struct.__struct__, :__schema__, 1) do
|
||||||
struct.__struct__.__schema__(:associations)
|
struct.__struct__.__schema__(:associations)
|
||||||
|
@ -101,6 +154,9 @@ defmodule MatrixServer do
|
||||||
|> Enum.into(%{})
|
|> Enum.into(%{})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Serialize and encode the given struct.
|
||||||
|
"""
|
||||||
@spec serialize_and_encode(struct()) :: {:ok, String.t()} | {:error, Jason.EncodeError.t()}
|
@spec serialize_and_encode(struct()) :: {:ok, String.t()} | {:error, Jason.EncodeError.t()}
|
||||||
def serialize_and_encode(struct) do
|
def serialize_and_encode(struct) do
|
||||||
struct
|
struct
|
||||||
|
@ -108,6 +164,11 @@ defmodule MatrixServer do
|
||||||
|> encode_canonical_json()
|
|> encode_canonical_json()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Add a signature to the given map under the `:signatures` key.
|
||||||
|
|
||||||
|
If the map has no `:signatures` key, it is created.
|
||||||
|
"""
|
||||||
@spec add_signature(map(), String.t(), String.t()) :: map()
|
@spec add_signature(map(), String.t(), String.t()) :: map()
|
||||||
def add_signature(object, key_id, sig) when not is_map_key(object, :signatures) do
|
def add_signature(object, key_id, sig) when not is_map_key(object, :signatures) do
|
||||||
Map.put(object, :signatures, %{MatrixServer.server_name() => %{key_id => sig}})
|
Map.put(object, :signatures, %{MatrixServer.server_name() => %{key_id => sig}})
|
||||||
|
@ -120,6 +181,9 @@ defmodule MatrixServer do
|
||||||
%{object | signatures: new_sigs}
|
%{object | signatures: new_sigs}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Validate a changeset's field where the reason for invalidation is not needed.
|
||||||
|
"""
|
||||||
@spec validate_change_simple(Ecto.Changeset.t(), atom(), (term() -> boolean())) ::
|
@spec validate_change_simple(Ecto.Changeset.t(), atom(), (term() -> boolean())) ::
|
||||||
Ecto.Changeset.t()
|
Ecto.Changeset.t()
|
||||||
def validate_change_simple(changeset, field, func) do
|
def validate_change_simple(changeset, field, func) do
|
||||||
|
@ -130,8 +194,11 @@ defmodule MatrixServer do
|
||||||
Ecto.Changeset.validate_change(changeset, field, augmented_func)
|
Ecto.Changeset.validate_change(changeset, field, augmented_func)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a Boolean whether the signature is valid.
|
@doc """
|
||||||
# Also returns false on ArgumentError.
|
Return a Boolean whether the given signature is valid.
|
||||||
|
|
||||||
|
Returns `false` if `:enacl` throws an exception.
|
||||||
|
"""
|
||||||
@spec sign_verify(binary(), String.t(), binary()) :: boolean()
|
@spec sign_verify(binary(), String.t(), binary()) :: boolean()
|
||||||
def sign_verify(sig, text, key) do
|
def sign_verify(sig, text, key) do
|
||||||
try do
|
try do
|
||||||
|
@ -141,6 +208,9 @@ defmodule MatrixServer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the earliest of the two given `DateTime`s.
|
||||||
|
"""
|
||||||
@spec min_datetime(DateTime.t(), DateTime.t()) :: DateTime.t()
|
@spec min_datetime(DateTime.t(), DateTime.t()) :: DateTime.t()
|
||||||
def min_datetime(datetime1, datetime2) do
|
def min_datetime(datetime1, datetime2) do
|
||||||
if DateTime.compare(datetime1, datetime2) == :gt do
|
if DateTime.compare(datetime1, datetime2) == :gt do
|
||||||
|
@ -150,6 +220,13 @@ defmodule MatrixServer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Encode the given string using URL-safe base64.
|
||||||
|
|
||||||
|
URL-safe base64 is the same was unpadded base64, except "+" is replaced by "-"
|
||||||
|
and "/" is replaced by "_".
|
||||||
|
See [the Matrix docs](https://spec.matrix.org/unstable/rooms/v4/) for more details.
|
||||||
|
"""
|
||||||
@spec encode_url_safe_base64(String.t()) :: String.t()
|
@spec encode_url_safe_base64(String.t()) :: String.t()
|
||||||
def encode_url_safe_base64(data) do
|
def encode_url_safe_base64(data) do
|
||||||
data
|
data
|
||||||
|
@ -158,6 +235,12 @@ defmodule MatrixServer do
|
||||||
|> String.replace("/", "_")
|
|> String.replace("/", "_")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Check whether the given domain (including port) is valid.
|
||||||
|
|
||||||
|
The domain could be a DNS name, IPv4 or IPv6 address.
|
||||||
|
See [the Matrix docs](https://matrix.org/docs/spec/appendices#server-name) for more details.
|
||||||
|
"""
|
||||||
@spec valid_domain?(String.t()) :: boolean()
|
@spec valid_domain?(String.t()) :: boolean()
|
||||||
def valid_domain?(domain) do
|
def valid_domain?(domain) do
|
||||||
if String.starts_with?(domain, "[") do
|
if String.starts_with?(domain, "[") do
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
defmodule MatrixServer.KeyServer do
|
defmodule MatrixServer.KeyServer do
|
||||||
|
@moduledoc """
|
||||||
|
A GenServer holding the homeserver's keys, and responsible for signing objects.
|
||||||
|
|
||||||
|
Currently, it only supports one key pair that cannot expire.
|
||||||
|
"""
|
||||||
|
|
||||||
use GenServer
|
use GenServer
|
||||||
|
|
||||||
# TODO: only support one signing key for now.
|
# TODO: only support one signing key for now.
|
||||||
|
@ -10,11 +16,22 @@ defmodule MatrixServer.KeyServer do
|
||||||
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
|
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Sign the given object using the homeserver's signing keys.
|
||||||
|
|
||||||
|
Return the signature and the key ID used.
|
||||||
|
On error, return `:error`.
|
||||||
|
"""
|
||||||
@spec sign_object(map()) :: {:ok, String.t(), String.t()} | :error
|
@spec sign_object(map()) :: {:ok, String.t(), String.t()} | :error
|
||||||
def sign_object(object) do
|
def sign_object(object) do
|
||||||
GenServer.call(__MODULE__, {:sign_object, object})
|
GenServer.call(__MODULE__, {:sign_object, object})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the homeserver's signing keys.
|
||||||
|
|
||||||
|
Return a list of tuples, each holding the key ID and the key itself.
|
||||||
|
"""
|
||||||
@spec get_own_signing_keys() :: list({String.t(), binary()})
|
@spec get_own_signing_keys() :: list({String.t(), binary()})
|
||||||
def get_own_signing_keys() do
|
def get_own_signing_keys() do
|
||||||
GenServer.call(__MODULE__, :get_own_signing_keys)
|
GenServer.call(__MODULE__, :get_own_signing_keys)
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
defmodule MatrixServer.RoomServer do
|
defmodule MatrixServer.RoomServer do
|
||||||
|
@moduledoc """
|
||||||
|
A GenServer to hold and manipulate the state of a Matrix room.
|
||||||
|
|
||||||
|
Each RoomServer corresponds to one Matrix room that the homeserver participates in.
|
||||||
|
The RoomServers are supervised by a DynamicSupervisor RoomServer.Supervisor.
|
||||||
|
"""
|
||||||
|
|
||||||
use GenServer
|
use GenServer
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
@ -18,17 +25,16 @@ defmodule MatrixServer.RoomServer do
|
||||||
GenServer.start_link(__MODULE__, opts, name: name)
|
GenServer.start_link(__MODULE__, opts, name: name)
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec get_room_server(Room.t()) :: {:error, :not_found} | DynamicSupervisor.on_start_child()
|
@doc """
|
||||||
def get_room_server(%Room{id: room_id}), do: get_room_server(room_id)
|
Get the PID of the RoomServer for a room.
|
||||||
|
|
||||||
# Get room server pid, or spin one up for the room.
|
If the given room has no running RoomServer yet, it is created.
|
||||||
# If the room does not exist, return an error.
|
If the given room does not exist, an error is returned.
|
||||||
|
"""
|
||||||
@spec get_room_server(String.t()) :: {:error, :not_found} | DynamicSupervisor.on_start_child()
|
@spec get_room_server(String.t()) :: {:error, :not_found} | DynamicSupervisor.on_start_child()
|
||||||
def get_room_server(room_id) do
|
def get_room_server(room_id) do
|
||||||
|
# TODO: Might be wise to use a transaction here to prevent race conditions.
|
||||||
case Repo.one(from r in Room, where: r.id == ^room_id) do
|
case Repo.one(from r in Room, where: r.id == ^room_id) do
|
||||||
nil ->
|
|
||||||
{:error, :not_found}
|
|
||||||
|
|
||||||
%Room{state: serialized_state_set} ->
|
%Room{state: serialized_state_set} ->
|
||||||
case Registry.lookup(@registry, room_id) do
|
case Registry.lookup(@registry, room_id) do
|
||||||
[{pid, _}] ->
|
[{pid, _}] ->
|
||||||
|
@ -43,9 +49,19 @@ defmodule MatrixServer.RoomServer do
|
||||||
|
|
||||||
DynamicSupervisor.start_child(@supervisor, {__MODULE__, opts})
|
DynamicSupervisor.start_child(@supervisor, {__MODULE__, opts})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
nil ->
|
||||||
|
{:error, :not_found}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Create a new Matrix room.
|
||||||
|
|
||||||
|
The new room is created with the given `account` as creator.
|
||||||
|
Events are inserted into the new room depending on the input `input` and according
|
||||||
|
to the [Matrix documentation](https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-createroom).
|
||||||
|
"""
|
||||||
@spec create_room(
|
@spec create_room(
|
||||||
pid(),
|
pid(),
|
||||||
MatrixServer.Account.t(),
|
MatrixServer.Account.t(),
|
||||||
|
@ -55,16 +71,30 @@ defmodule MatrixServer.RoomServer do
|
||||||
GenServer.call(pid, {:create_room, account, input})
|
GenServer.call(pid, {:create_room, account, input})
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec server_in_room(pid(), String.t()) :: boolean()
|
@doc """
|
||||||
def server_in_room(pid, domain) do
|
Check whether the given server participates in a room.
|
||||||
GenServer.call(pid, {:server_in_room, domain})
|
|
||||||
|
Check whether any participant of the room has a server name matching
|
||||||
|
the given `domain`.
|
||||||
|
"""
|
||||||
|
@spec server_in_room?(pid(), String.t()) :: boolean()
|
||||||
|
def server_in_room?(pid, domain) do
|
||||||
|
GenServer.call(pid, {:server_in_room?, domain})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get the state of a room, before the given event was inserted.
|
||||||
|
|
||||||
|
Return a list of all state events and the auth chain.
|
||||||
|
"""
|
||||||
@spec get_state_at_event(pid(), Event.t()) :: {[Event.t()], [Event.t()]}
|
@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
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Same as `get_state_at_event/2`, except returns the lists as event IDs.
|
||||||
|
"""
|
||||||
@spec get_state_ids_at_event(pid(), Event.t()) :: {[String.t()], [String.t()]}
|
@spec get_state_ids_at_event(pid(), Event.t()) :: {[String.t()], [String.t()]}
|
||||||
def get_state_ids_at_event(pid, event) do
|
def get_state_ids_at_event(pid, event) do
|
||||||
GenServer.call(pid, {:get_state_ids_at_event, event})
|
GenServer.call(pid, {:get_state_ids_at_event, event})
|
||||||
|
@ -101,7 +131,7 @@ defmodule MatrixServer.RoomServer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_call({:server_in_room, domain}, _from, %{state_set: state_set} = state) do
|
def handle_call({:server_in_room?, domain}, _from, %{state_set: state_set} = state) do
|
||||||
result =
|
result =
|
||||||
Enum.any?(state_set, fn
|
Enum.any?(state_set, fn
|
||||||
{{"m.room.member", user_id}, %Event{content: %{"membership" => "join"}}} ->
|
{{"m.room.member", user_id}, %Event{content: %{"membership" => "join"}}} ->
|
||||||
|
|
|
@ -18,7 +18,7 @@ defmodule MatrixServerWeb.Federation.EventController do
|
||||||
%Event{room: room} = event ->
|
%Event{room: room} = event ->
|
||||||
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
|
||||||
data = Transaction.new([event])
|
data = Transaction.new([event])
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
@ -57,7 +57,13 @@ defmodule MatrixServerWeb.Federation.EventController do
|
||||||
|
|
||||||
def state_ids(conn, _), do: put_error(conn, :missing_param)
|
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()
|
@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
|
defp get_state_or_state_ids(conn, state_or_state_ids, origin, event_id, room_id) do
|
||||||
query =
|
query =
|
||||||
Event
|
Event
|
||||||
|
@ -68,7 +74,7 @@ defmodule MatrixServerWeb.Federation.EventController do
|
||||||
%Event{room: room} = event ->
|
%Event{room: room} = event ->
|
||||||
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} =
|
{state_events, auth_chain} =
|
||||||
case state_or_state_ids do
|
case state_or_state_ids do
|
||||||
:state -> RoomServer.get_state_at_event(pid, event)
|
:state -> RoomServer.get_state_at_event(pid, event)
|
||||||
|
|
|
@ -75,7 +75,8 @@ defmodule MatrixServerWeb.Federation.HTTPClient do
|
||||||
|
|
||||||
def get_state_ids(client, room_id, event_id) do
|
def get_state_ids(client, room_id, event_id) do
|
||||||
path =
|
path =
|
||||||
RouteHelpers.event_path(Endpoint, :state_ids, room_id) |> Tesla.build_url(event_id: event_id)
|
RouteHelpers.event_path(Endpoint, :state_ids, room_id)
|
||||||
|
|> Tesla.build_url(event_id: event_id)
|
||||||
|
|
||||||
Tesla.get(client, path)
|
Tesla.get(client, path)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue