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
|
||||
@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
|
||||
%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})
|
||||
end
|
||||
|
||||
def start_link(opts) do
|
||||
{name, opts} = Keyword.pop(opts, :name)
|
||||
GenServer.start_link(__MODULE__, opts, name: name)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def init(opts) do
|
||||
%Room{id: room_id} = Keyword.fetch!(opts, :room)
|
||||
|
@ -36,6 +36,8 @@ defmodule MatrixServer.RoomServer do
|
|||
Repo.transaction(fn ->
|
||||
with {:ok, state_set} <- insert_create_room_event(account, input, room_id) do
|
||||
{:ok, %{room_id: room_id, state_set: state_set}}
|
||||
else
|
||||
_ -> {:error, :something}
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
@ -47,27 +49,30 @@ defmodule MatrixServer.RoomServer do
|
|||
) do
|
||||
create_room_event = Event.create_room(room_id, MatrixServer.get_mxid(localpart), room_version)
|
||||
|
||||
verify_and_insert_event(create_room_event)
|
||||
|
||||
{:ok, %{}}
|
||||
verify_and_insert_event(create_room_event, %{})
|
||||
end
|
||||
|
||||
defp verify_and_insert_event(event) do
|
||||
defp verify_and_insert_event(event, current_state_set) do
|
||||
# Check the following things:
|
||||
# 1. TODO: Is a valid event, 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.
|
||||
# 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.
|
||||
# 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
|
||||
state_set = StateResolution.resolve(event, false)
|
||||
|
||||
if StateResolution.is_authorized(event, state_set) do
|
||||
# TODO: Assume the event is a forward extremity, should check this actually.
|
||||
Room.update_forward_extremities(event)
|
||||
{:ok, event} = Repo.insert(event)
|
||||
{:ok, state_set}
|
||||
if StateResolution.is_authorized(event, current_state_set) do
|
||||
# TODO: Assume the event is a forward extremity, should check this actually.
|
||||
Room.update_forward_extremities(event)
|
||||
{:ok, event} = Repo.insert(event)
|
||||
state_set = StateResolution.resolve_forward_extremities(event)
|
||||
{:ok, state_set}
|
||||
else
|
||||
{:error, :soft_failed}
|
||||
end
|
||||
else
|
||||
{:error, :rejected}
|
||||
end
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
defmodule MatrixServer.StateResolution do
|
||||
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
|
||||
room_events =
|
||||
|
@ -322,6 +324,23 @@ defmodule MatrixServer.StateResolution do
|
|||
is_authorized(event, state_set)
|
||||
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
|
||||
%Event{content: content} = event = Event.power_levels("room1", "charlie")
|
||||
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