Implement retrieving a single event over federation
Fix url encoding during homeserver signature check
This commit is contained in:
parent
1881b7f3d6
commit
e510c3bb6a
14 changed files with 173 additions and 22 deletions
|
@ -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) ->
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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: []
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue