Implement retrieving a single event over federation

Fix url encoding during homeserver signature check
This commit is contained in:
Pim Kunis 2021-08-21 11:25:36 +02:00
parent 1881b7f3d6
commit e510c3bb6a
14 changed files with 173 additions and 22 deletions

View file

@ -1,6 +1,6 @@
# https://github.com/michalmuskala/jason/issues/69
defmodule MatrixServer.EncodableMap do
alias MatrixServer.EncodableMap
alias MatrixServer.{EncodableMap, Event}
alias MatrixServer.Types.{UserId, RoomId, EventId, GroupId, AliasId}
defstruct pairs: []
@ -15,12 +15,10 @@ defmodule MatrixServer.EncodableMap do
pairs =
map
|> Enum.map(fn
{k, v} when is_struct(v, DateTime) ->
{k, DateTime.to_unix(v, :millisecond)}
{k, v}
when is_struct(v, UserId) or is_struct(v, RoomId) or is_struct(v, EventId) or
is_struct(v, GroupId) or is_struct(v, AliasId) ->
# Simply convert IDs to a string.
{k, to_string(v)}
{k, v} when is_map(v) ->

View file

@ -48,6 +48,8 @@ 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)

View file

@ -18,6 +18,9 @@ defmodule MatrixServer.RoomServer do
GenServer.start_link(__MODULE__, opts, name: name)
end
@spec get_room_server(Room.t()) :: {:error, :not_found} | DynamicSupervisor.on_start_child()
def get_room_server(%Room{id: room_id}), do: get_room_server(room_id)
# Get room server pid, or spin one up for the room.
# If the room does not exist, return an error.
@spec get_room_server(String.t()) :: {:error, :not_found} | DynamicSupervisor.on_start_child()

View file

@ -9,7 +9,7 @@ defmodule MatrixServer.Event do
# TODO: Could refactor to also always set prev_events, but not necessary.
@type t :: %__MODULE__{
type: String.t(),
origin_server_ts: DateTime.t(),
origin_server_ts: integer(),
state_key: String.t(),
sender: UserId.t(),
content: map(),
@ -23,7 +23,7 @@ defmodule MatrixServer.Event do
@primary_key {:event_id, :string, []}
schema "events" do
field :type, :string
field :origin_server_ts, :utc_datetime_usec
field :origin_server_ts, :integer
field :state_key, :string
field :sender, UserId
field :content, :map
@ -36,12 +36,38 @@ defmodule MatrixServer.Event do
belongs_to :room, Room, type: :string
end
defimpl Jason.Encoder, for: Event do
@pdu_keys [
:auth_events,
:content,
:depth,
:hashes,
:origin,
:origin_server_ts,
:prev_events,
:redacts,
:room_id,
:sender,
:signatures,
:state_key,
:type,
:unsigned
]
def encode(event, opts) do
event
|> Map.take(@pdu_keys)
|> Map.update!(:sender, &Kernel.to_string/1)
|> Jason.Encode.map(opts)
end
end
@spec new(Room.t(), Account.t()) :: %Event{}
def new(%Room{id: room_id}, %Account{localpart: localpart}) do
%Event{
room_id: room_id,
sender: %UserId{localpart: localpart, domain: MatrixServer.server_name()},
origin_server_ts: DateTime.utc_now(),
origin_server_ts: DateTime.utc_now() |> DateTime.to_unix(:millisecond),
prev_events: [],
auth_events: []
}

View file

@ -10,7 +10,7 @@ defmodule MatrixServer.ServerKeyInfo do
@primary_key {:server_name, :string, []}
schema "server_key_info" do
field :valid_until, :utc_datetime
field :valid_until, :integer
has_many :signing_keys, SigningKey, foreign_key: :server_name
end
@ -43,7 +43,7 @@ defmodule MatrixServer.ServerKeyInfo do
verify_keys: verify_keys,
valid_until_ts: valid_until_ts
}} <- HTTPClient.get_signing_keys(client),
{:ok, valid_until} <- DateTime.from_unix(valid_until_ts) do
{:ok, valid_until} <- DateTime.from_unix(valid_until_ts, :millisecond) do
signing_keys =
Enum.map(verify_keys, fn {key_id, %{"key" => key}} ->
[server_name: server_name, signing_key_id: key_id, signing_key: key]
@ -52,7 +52,8 @@ defmodule MatrixServer.ServerKeyInfo do
# Always check every week to prevent misuse.
ski = %ServerKeyInfo{
server_name: server_name,
valid_until: MatrixServer.min_datetime(in_a_week, valid_until)
valid_until:
MatrixServer.min_datetime(in_a_week, valid_until) |> DateTime.to_unix(:millisecond)
}
case upsert_multi(server_name, ski, signing_keys) |> Repo.transaction() do

View file

@ -18,6 +18,12 @@ defmodule MatrixServer.Types.UserId do
end
end
defimpl Jason.Encoder, for: UserId do
def encode(user_id, opts) do
Jason.Encode.string(to_string(user_id), opts)
end
end
def type(), do: :string
def cast(s) when is_binary(s) do