Add function to query whether server participates in a room
Move from integer timestamps to datetimes
This commit is contained in:
parent
5d75244bc0
commit
02edff90e7
7 changed files with 65 additions and 20 deletions
|
@ -126,4 +126,12 @@ defmodule MatrixServer do
|
||||||
ArgumentError -> false
|
ArgumentError -> false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def min_datetime(datetime1, datetime2) do
|
||||||
|
if DateTime.compare(datetime1, datetime2) == :gt do
|
||||||
|
datetime2
|
||||||
|
else
|
||||||
|
datetime1
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -46,6 +46,10 @@ defmodule MatrixServer.RoomServer do
|
||||||
GenServer.call(pid, {:create_room, account, input})
|
GenServer.call(pid, {:create_room, account, input})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def server_in_room(pid, domain) do
|
||||||
|
GenServer.call(pid, {:server_in_room, domain})
|
||||||
|
end
|
||||||
|
|
||||||
### Implementation
|
### Implementation
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
@ -120,6 +124,18 @@ defmodule MatrixServer.RoomServer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_call({:server_in_room, domain}, _from, %{state_set: state_set} = state) do
|
||||||
|
result = Enum.any?(state_set, fn
|
||||||
|
{{"m.room.member", user_id}, %Event{content: %{"membership" => "join"}}} ->
|
||||||
|
MatrixServer.get_domain(user_id) == domain
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end)
|
||||||
|
|
||||||
|
{:reply, result, state}
|
||||||
|
end
|
||||||
|
|
||||||
# TODO: trusted_private_chat:
|
# TODO: trusted_private_chat:
|
||||||
# All invitees are given the same power level as the room creator.
|
# All invitees are given the same power level as the room creator.
|
||||||
defp room_creation_preset(account, nil, %Room{visibility: visibility} = room, auth_events) do
|
defp room_creation_preset(account, nil, %Room{visibility: visibility} = room, auth_events) do
|
||||||
|
|
|
@ -8,7 +8,7 @@ defmodule MatrixServer.Event do
|
||||||
@primary_key {:event_id, :string, []}
|
@primary_key {:event_id, :string, []}
|
||||||
schema "events" do
|
schema "events" do
|
||||||
field :type, :string
|
field :type, :string
|
||||||
field :origin_server_ts, :integer
|
field :origin_server_ts, :utc_datetime_usec
|
||||||
field :state_key, :string
|
field :state_key, :string
|
||||||
field :sender, :string
|
field :sender, :string
|
||||||
field :content, :map
|
field :content, :map
|
||||||
|
@ -27,7 +27,7 @@ defmodule MatrixServer.Event do
|
||||||
room_id: room_id,
|
room_id: room_id,
|
||||||
sender: MatrixServer.get_mxid(localpart),
|
sender: MatrixServer.get_mxid(localpart),
|
||||||
event_id: generate_event_id(),
|
event_id: generate_event_id(),
|
||||||
origin_server_ts: System.os_time(:millisecond),
|
origin_server_ts: DateTime.utc_now(),
|
||||||
prev_events: [],
|
prev_events: [],
|
||||||
auth_events: []
|
auth_events: []
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ defmodule MatrixServer.ServerKeyInfo do
|
||||||
|
|
||||||
@primary_key {:server_name, :string, []}
|
@primary_key {:server_name, :string, []}
|
||||||
schema "server_key_info" do
|
schema "server_key_info" do
|
||||||
field :valid_until, :integer
|
field :valid_until, :utc_datetime
|
||||||
|
|
||||||
has_many :signing_keys, SigningKey, foreign_key: :server_name
|
has_many :signing_keys, SigningKey, foreign_key: :server_name
|
||||||
end
|
end
|
||||||
|
@ -34,31 +34,33 @@ defmodule MatrixServer.ServerKeyInfo do
|
||||||
|
|
||||||
defp refresh_signing_keys(server_name) do
|
defp refresh_signing_keys(server_name) do
|
||||||
# TODO: Handle expired keys.
|
# TODO: Handle expired keys.
|
||||||
in_a_week = System.os_time(:millisecond) + 1000 * 60 * 60 * 24 * 7
|
in_a_week = DateTime.utc_now() |> DateTime.add(60 * 60 * 24 * 7, :second)
|
||||||
client = HTTPClient.client(server_name)
|
client = HTTPClient.client(server_name)
|
||||||
|
|
||||||
with {:ok,
|
with {:ok,
|
||||||
%GetSigningKeys{
|
%GetSigningKeys{
|
||||||
server_name: server_name,
|
server_name: server_name,
|
||||||
verify_keys: verify_keys,
|
verify_keys: verify_keys,
|
||||||
valid_until_ts: valid_until
|
valid_until_ts: valid_until_ts
|
||||||
}} <-
|
}} <- HTTPClient.get_signing_keys(client),
|
||||||
HTTPClient.get_signing_keys(client) do
|
{:ok, valid_until} <- DateTime.from_unix(valid_until_ts) do
|
||||||
signing_keys =
|
signing_keys =
|
||||||
Enum.map(verify_keys, fn {key_id, %{"key" => key}} ->
|
Enum.map(verify_keys, fn {key_id, %{"key" => key}} ->
|
||||||
[server_name: server_name, signing_key_id: key_id, signing_key: key]
|
[server_name: server_name, signing_key_id: key_id, signing_key: key]
|
||||||
end)
|
end)
|
||||||
|
|
||||||
# Always check every week to prevent misuse.
|
# Always check every week to prevent misuse.
|
||||||
ski = %ServerKeyInfo{server_name: server_name, valid_until: min(valid_until, in_a_week)}
|
ski = %ServerKeyInfo{
|
||||||
|
server_name: server_name,
|
||||||
|
valid_until: MatrixServer.min_datetime(in_a_week, valid_until)
|
||||||
|
}
|
||||||
|
|
||||||
case upsert_multi(server_name, ski, signing_keys) |> Repo.transaction() do
|
case upsert_multi(server_name, ski, signing_keys) |> Repo.transaction() do
|
||||||
{:ok, %{new_ski: ski}} -> {:ok, ski}
|
{:ok, %{new_ski: ski}} -> {:ok, ski}
|
||||||
{:error, _} -> :error
|
{:error, _} -> :error
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
:error ->
|
_ -> :error
|
||||||
:error
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,6 @@ defmodule MatrixServerWeb.Federation.KeyController do
|
||||||
|
|
||||||
alias MatrixServer.KeyServer
|
alias MatrixServer.KeyServer
|
||||||
|
|
||||||
@key_valid_time_ms 1000 * 60 * 24 * 30
|
|
||||||
|
|
||||||
def get_signing_keys(conn, _params) do
|
def get_signing_keys(conn, _params) do
|
||||||
keys =
|
keys =
|
||||||
KeyServer.get_own_signing_keys()
|
KeyServer.get_own_signing_keys()
|
||||||
|
@ -14,11 +12,15 @@ defmodule MatrixServerWeb.Federation.KeyController do
|
||||||
{key_id, %{"key" => key}}
|
{key_id, %{"key" => key}}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
# TODO: Consider using TimeX.
|
||||||
|
# Valid for one month.
|
||||||
|
valid_until = DateTime.utc_now() |> DateTime.add(60 * 60 * 24 * 30, :second)
|
||||||
|
|
||||||
data = %{
|
data = %{
|
||||||
server_name: MatrixServer.server_name(),
|
server_name: MatrixServer.server_name(),
|
||||||
verify_keys: keys,
|
verify_keys: keys,
|
||||||
old_verify_keys: %{},
|
old_verify_keys: %{},
|
||||||
valid_until_ts: System.os_time(:millisecond) + @key_valid_time_ms
|
valid_until_ts: valid_until
|
||||||
}
|
}
|
||||||
|
|
||||||
case KeyServer.sign_object(data) do
|
case KeyServer.sign_object(data) do
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
defmodule MatrixServer.Repo.Migrations.ChangeTimestampsToDatetime do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table(:events) do
|
||||||
|
remove :origin_server_ts, :integer, null: false
|
||||||
|
add :origin_server_ts, :utc_datetime_usec, null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
alter table(:server_key_info) do
|
||||||
|
remove :valid_until, :bigint, default: 0, null: false
|
||||||
|
add :valid_until, :utc_datetime_usec, null: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,7 @@
|
||||||
alias MatrixServer.{Repo, Room, Event, Account, Device}
|
alias MatrixServer.{Repo, Room, Event, Account, Device}
|
||||||
|
|
||||||
|
timestamp = fn n -> DateTime.from_unix!(n, :microsecond) end
|
||||||
|
|
||||||
Repo.insert!(%Account{
|
Repo.insert!(%Account{
|
||||||
localpart: "chuck",
|
localpart: "chuck",
|
||||||
password_hash: Bcrypt.hash_pwd_salt("sneed")
|
password_hash: Bcrypt.hash_pwd_salt("sneed")
|
||||||
|
@ -40,7 +42,7 @@ room =
|
||||||
|
|
||||||
Repo.insert!(
|
Repo.insert!(
|
||||||
Event.create_room(room, alice, "v1")
|
Event.create_room(room, alice, "v1")
|
||||||
|> Map.put(:origin_server_ts, 0)
|
|> Map.put(:origin_server_ts, timestamp.(0))
|
||||||
|> Map.put(:event_id, "create")
|
|> Map.put(:event_id, "create")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -48,7 +50,7 @@ Repo.insert!(
|
||||||
Event.join(room, alice)
|
Event.join(room, alice)
|
||||||
|> Map.put(:prev_events, ["create"])
|
|> Map.put(:prev_events, ["create"])
|
||||||
|> Map.put(:auth_events, ["create"])
|
|> Map.put(:auth_events, ["create"])
|
||||||
|> Map.put(:origin_server_ts, 1)
|
|> Map.put(:origin_server_ts, timestamp.(1))
|
||||||
|> Map.put(:event_id, "join_alice")
|
|> Map.put(:event_id, "join_alice")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -56,7 +58,7 @@ Repo.insert!(
|
||||||
Event.join(room, bob)
|
Event.join(room, bob)
|
||||||
|> Map.put(:prev_events, ["join_alice"])
|
|> Map.put(:prev_events, ["join_alice"])
|
||||||
|> Map.put(:auth_events, ["create"])
|
|> Map.put(:auth_events, ["create"])
|
||||||
|> Map.put(:origin_server_ts, 2)
|
|> Map.put(:origin_server_ts, timestamp.(2))
|
||||||
|> Map.put(:event_id, "join_bob")
|
|> Map.put(:event_id, "join_bob")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -64,7 +66,7 @@ Repo.insert!(
|
||||||
Event.join(room, charlie)
|
Event.join(room, charlie)
|
||||||
|> Map.put(:prev_events, ["join_bob"])
|
|> Map.put(:prev_events, ["join_bob"])
|
||||||
|> Map.put(:auth_events, ["create"])
|
|> Map.put(:auth_events, ["create"])
|
||||||
|> Map.put(:origin_server_ts, 3)
|
|> Map.put(:origin_server_ts, timestamp.(3))
|
||||||
|> Map.put(:event_id, "join_charlie")
|
|> Map.put(:event_id, "join_charlie")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -75,7 +77,7 @@ Repo.insert!(
|
||||||
event
|
event
|
||||||
|> Map.put(:prev_events, ["join_alice"])
|
|> Map.put(:prev_events, ["join_alice"])
|
||||||
|> Map.put(:auth_events, ["create", "join_alice"])
|
|> Map.put(:auth_events, ["create", "join_alice"])
|
||||||
|> Map.put(:origin_server_ts, 4)
|
|> Map.put(:origin_server_ts, timestamp.(4))
|
||||||
|> Map.put(:event_id, "a")
|
|> Map.put(:event_id, "a")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -90,7 +92,7 @@ Repo.insert!(
|
||||||
event
|
event
|
||||||
|> Map.put(:prev_events, ["a"])
|
|> Map.put(:prev_events, ["a"])
|
||||||
|> Map.put(:auth_events, ["create", "join_bob", "a"])
|
|> Map.put(:auth_events, ["create", "join_bob", "a"])
|
||||||
|> Map.put(:origin_server_ts, 5)
|
|> Map.put(:origin_server_ts, timestamp.(5))
|
||||||
|> Map.put(:event_id, "b")
|
|> Map.put(:event_id, "b")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -98,6 +100,6 @@ Repo.insert!(
|
||||||
Event.topic(room, alice, "sneed")
|
Event.topic(room, alice, "sneed")
|
||||||
|> Map.put(:prev_events, ["a"])
|
|> Map.put(:prev_events, ["a"])
|
||||||
|> Map.put(:auth_events, ["create", "join_alice", "a"])
|
|> Map.put(:auth_events, ["create", "join_alice", "a"])
|
||||||
|> Map.put(:origin_server_ts, 5)
|
|> Map.put(:origin_server_ts, timestamp.(5))
|
||||||
|> Map.put(:event_id, "fork")
|
|> Map.put(:event_id, "fork")
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue