Save state set in database
This commit is contained in:
parent
8a5bba72fb
commit
d3c16dd7aa
3 changed files with 48 additions and 15 deletions
|
@ -9,11 +9,6 @@ defmodule MatrixServer.RoomServer do
|
||||||
@registry MatrixServer.RoomServer.Registry
|
@registry MatrixServer.RoomServer.Registry
|
||||||
@supervisor MatrixServer.RoomServer.Supervisor
|
@supervisor MatrixServer.RoomServer.Supervisor
|
||||||
|
|
||||||
def start_link(opts) do
|
|
||||||
{name, opts} = Keyword.pop(opts, :name)
|
|
||||||
GenServer.start_link(__MODULE__, opts, name: name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_room(input, account) do
|
def create_room(input, account) do
|
||||||
%Room{id: room_id} = room = Repo.insert!(Room.create_changeset(input))
|
%Room{id: room_id} = room = Repo.insert!(Room.create_changeset(input))
|
||||||
|
|
||||||
|
@ -27,6 +22,11 @@ defmodule MatrixServer.RoomServer do
|
||||||
DynamicSupervisor.start_child(@supervisor, {__MODULE__, opts})
|
DynamicSupervisor.start_child(@supervisor, {__MODULE__, opts})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def start_link(opts) do
|
||||||
|
{name, opts} = Keyword.pop(opts, :name)
|
||||||
|
GenServer.start_link(__MODULE__, opts, name: name)
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def init(opts) do
|
def init(opts) do
|
||||||
%Room{id: room_id} = Keyword.fetch!(opts, :room)
|
%Room{id: room_id} = Keyword.fetch!(opts, :room)
|
||||||
|
@ -36,6 +36,8 @@ defmodule MatrixServer.RoomServer do
|
||||||
Repo.transaction(fn ->
|
Repo.transaction(fn ->
|
||||||
with {:ok, state_set} <- insert_create_room_event(account, input, room_id) do
|
with {:ok, state_set} <- insert_create_room_event(account, input, room_id) do
|
||||||
{:ok, %{room_id: room_id, state_set: state_set}}
|
{:ok, %{room_id: room_id, state_set: state_set}}
|
||||||
|
else
|
||||||
|
_ -> {:error, :something}
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
@ -47,27 +49,30 @@ defmodule MatrixServer.RoomServer do
|
||||||
) do
|
) do
|
||||||
create_room_event = Event.create_room(room_id, MatrixServer.get_mxid(localpart), room_version)
|
create_room_event = Event.create_room(room_id, MatrixServer.get_mxid(localpart), room_version)
|
||||||
|
|
||||||
verify_and_insert_event(create_room_event)
|
verify_and_insert_event(create_room_event, %{})
|
||||||
|
|
||||||
{:ok, %{}}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp verify_and_insert_event(event) do
|
defp verify_and_insert_event(event, current_state_set) do
|
||||||
# Check the following things:
|
# Check the following things:
|
||||||
# 1. TODO: Is a valid event, otherwise it is dropped.
|
# 1. TODO: Is a valid event, otherwise it is dropped.
|
||||||
# 2. TODO: Passes signature checks, otherwise it is dropped.
|
# 2. TODO: Passes signature checks, otherwise it is dropped.
|
||||||
# 3. TODO: Passes hash checks, otherwise it is redacted before being processed further.
|
# 3. TODO: Passes hash checks, otherwise it is redacted before being processed further.
|
||||||
# 4. Passes authorization rules based on the event's auth events, otherwise it is rejected.
|
# 4. Passes authorization rules based on the event's auth events, otherwise it is rejected.
|
||||||
# 5. Passes authorization rules based on the state at the event, otherwise it is rejected.
|
# 5. Passes authorization rules based on the state at the event, otherwise it is rejected.
|
||||||
# 6. TODO: Passes authorization rules based on the current state of the room, otherwise it is "soft failed".
|
# 6. Passes authorization rules based on the current state of the room, otherwise it is "soft failed".
|
||||||
if StateResolution.is_authorized_by_auth_events(event) do
|
if StateResolution.is_authorized_by_auth_events(event) do
|
||||||
state_set = StateResolution.resolve(event, false)
|
state_set = StateResolution.resolve(event, false)
|
||||||
|
|
||||||
if StateResolution.is_authorized(event, state_set) do
|
if StateResolution.is_authorized(event, state_set) do
|
||||||
|
if StateResolution.is_authorized(event, current_state_set) do
|
||||||
# TODO: Assume the event is a forward extremity, should check this actually.
|
# TODO: Assume the event is a forward extremity, should check this actually.
|
||||||
Room.update_forward_extremities(event)
|
Room.update_forward_extremities(event)
|
||||||
{:ok, event} = Repo.insert(event)
|
{:ok, event} = Repo.insert(event)
|
||||||
|
state_set = StateResolution.resolve_forward_extremities(event)
|
||||||
{:ok, state_set}
|
{:ok, state_set}
|
||||||
|
else
|
||||||
|
{:error, :soft_failed}
|
||||||
|
end
|
||||||
else
|
else
|
||||||
{:error, :rejected}
|
{:error, :rejected}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
defmodule MatrixServer.StateResolution do
|
defmodule MatrixServer.StateResolution do
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
alias MatrixServer.{Repo, Event}
|
alias MatrixServer.{Repo, Event, Room}
|
||||||
|
|
||||||
|
def resolve(event), do: resolve(event, true)
|
||||||
|
|
||||||
def resolve(%Event{room_id: room_id} = event, apply_state) do
|
def resolve(%Event{room_id: room_id} = event, apply_state) do
|
||||||
room_events =
|
room_events =
|
||||||
|
@ -322,6 +324,23 @@ defmodule MatrixServer.StateResolution do
|
||||||
is_authorized(event, state_set)
|
is_authorized(event, state_set)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def resolve_forward_extremities(%Event{room_id: room_id}) do
|
||||||
|
room_events =
|
||||||
|
Event
|
||||||
|
|> where([e], e.room_id == ^room_id)
|
||||||
|
|> select([e], {e.event_id, e})
|
||||||
|
|> Repo.all()
|
||||||
|
|> Enum.into(%{})
|
||||||
|
|
||||||
|
Event
|
||||||
|
|> where([e], e.room_id == ^room_id)
|
||||||
|
|> join(:inner, [e], r in Room, on: e.room_id == r.id)
|
||||||
|
|> where([e, r], e.event_id == fragment("ANY(?)", r.forward_extremities))
|
||||||
|
|> Repo.all()
|
||||||
|
|> Enum.map(&resolve/1)
|
||||||
|
|> do_resolve(room_events)
|
||||||
|
end
|
||||||
|
|
||||||
def testing do
|
def testing do
|
||||||
%Event{content: content} = event = Event.power_levels("room1", "charlie")
|
%Event{content: content} = event = Event.power_levels("room1", "charlie")
|
||||||
event = %Event{event | content: %{content | "ban" => 0}}
|
event = %Event{event | content: %{content | "ban" => 0}}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
defmodule MatrixServer.Repo.Migrations.AddStateToRoom do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table(:rooms) do
|
||||||
|
add :state, :map, default: %{}, null: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue