Save preset events when creating room
This commit is contained in:
parent
3c93ddd768
commit
dc12575923
4 changed files with 160 additions and 60 deletions
|
@ -3,7 +3,7 @@ defmodule MatrixServer.Event do
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
alias MatrixServer.{Repo, Room, Event}
|
alias MatrixServer.{Repo, Room, Event, Account}
|
||||||
|
|
||||||
@primary_key {:event_id, :string, []}
|
@primary_key {:event_id, :string, []}
|
||||||
schema "events" do
|
schema "events" do
|
||||||
|
@ -17,10 +17,10 @@ defmodule MatrixServer.Event do
|
||||||
belongs_to :room, Room, type: :string
|
belongs_to :room, Room, type: :string
|
||||||
end
|
end
|
||||||
|
|
||||||
def new(%Room{id: room_id}, sender) do
|
def new(%Room{id: room_id}, %Account{localpart: localpart}) do
|
||||||
%Event{
|
%Event{
|
||||||
room_id: room_id,
|
room_id: room_id,
|
||||||
sender: sender,
|
sender: MatrixServer.get_mxid(localpart),
|
||||||
event_id: generate_event_id(),
|
event_id: generate_event_id(),
|
||||||
origin_server_ts: DateTime.utc_now() |> DateTime.to_unix(),
|
origin_server_ts: DateTime.utc_now() |> DateTime.to_unix(),
|
||||||
prev_events: [],
|
prev_events: [],
|
||||||
|
@ -28,30 +28,36 @@ defmodule MatrixServer.Event do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_room(room, creator, room_version) do
|
def create_room(room, %Account{localpart: localpart} = creator, room_version) do
|
||||||
|
mxid = MatrixServer.get_mxid(localpart)
|
||||||
|
|
||||||
%Event{
|
%Event{
|
||||||
new(room, creator)
|
new(room, creator)
|
||||||
| type: "m.room.create",
|
| type: "m.room.create",
|
||||||
state_key: "",
|
state_key: "",
|
||||||
content: %{
|
content: %{
|
||||||
"creator" => creator,
|
"creator" => mxid,
|
||||||
"room_version" => room_version || MatrixServer.default_room_version()
|
"room_version" => room_version || MatrixServer.default_room_version()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def join(room, sender) do
|
def join(room, %Account{localpart: localpart} = sender) do
|
||||||
|
mxid = MatrixServer.get_mxid(localpart)
|
||||||
|
|
||||||
%Event{
|
%Event{
|
||||||
new(room, sender)
|
new(room, sender)
|
||||||
| type: "m.room.member",
|
| type: "m.room.member",
|
||||||
state_key: sender,
|
state_key: mxid,
|
||||||
content: %{
|
content: %{
|
||||||
"membership" => "join"
|
"membership" => "join"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def power_levels(room, sender) do
|
def power_levels(room, %Account{localpart: localpart} = sender) do
|
||||||
|
mxid = MatrixServer.get_mxid(localpart)
|
||||||
|
|
||||||
%Event{
|
%Event{
|
||||||
new(room, sender)
|
new(room, sender)
|
||||||
| type: "m.room.power_levels",
|
| type: "m.room.power_levels",
|
||||||
|
@ -65,7 +71,7 @@ defmodule MatrixServer.Event do
|
||||||
"redact" => 50,
|
"redact" => 50,
|
||||||
"state_default" => 50,
|
"state_default" => 50,
|
||||||
"users" => %{
|
"users" => %{
|
||||||
sender => 50
|
mxid => 50
|
||||||
},
|
},
|
||||||
"users_default" => 0,
|
"users_default" => 0,
|
||||||
"notifications" => %{
|
"notifications" => %{
|
||||||
|
@ -97,6 +103,39 @@ defmodule MatrixServer.Event do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def join_rules(room, sender, join_rule) do
|
||||||
|
%Event{
|
||||||
|
new(room, sender)
|
||||||
|
| type: "m.room.join_rules",
|
||||||
|
state_key: "",
|
||||||
|
content: %{
|
||||||
|
"join_rule" => join_rule
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def history_visibility(room, sender, history_visibility) do
|
||||||
|
%Event{
|
||||||
|
new(room, sender)
|
||||||
|
| type: "m.room.history_visibility",
|
||||||
|
state_key: "",
|
||||||
|
content: %{
|
||||||
|
"history_visibility" => history_visibility
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def guest_access(room, sender, guest_access) do
|
||||||
|
%Event{
|
||||||
|
new(room, sender)
|
||||||
|
| type: "m.room.guest_access",
|
||||||
|
state_key: "",
|
||||||
|
content: %{
|
||||||
|
"guest_access" => guest_access
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def generate_event_id do
|
def generate_event_id do
|
||||||
"$" <> MatrixServer.random_string(17) <> ":" <> MatrixServer.server_name()
|
"$" <> MatrixServer.random_string(17) <> ":" <> MatrixServer.server_name()
|
||||||
end
|
end
|
||||||
|
@ -122,15 +161,13 @@ defmodule MatrixServer.Event do
|
||||||
# We assume that required keys, as well as in the content, is already validated.
|
# We assume that required keys, as well as in the content, is already validated.
|
||||||
|
|
||||||
# Rule 1.4 is left to changeset validation.
|
# Rule 1.4 is left to changeset validation.
|
||||||
def prevalidate(
|
def prevalidate(%Event{
|
||||||
%Event{
|
|
||||||
type: "m.room.create",
|
type: "m.room.create",
|
||||||
prev_events: prev_events,
|
prev_events: prev_events,
|
||||||
auth_events: auth_events,
|
auth_events: auth_events,
|
||||||
room_id: room_id,
|
room_id: room_id,
|
||||||
sender: sender
|
sender: sender
|
||||||
} = event
|
}) do
|
||||||
) do
|
|
||||||
# TODO: error check on domains?
|
# TODO: error check on domains?
|
||||||
# TODO: rule 1.3
|
# TODO: rule 1.3
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,12 @@ defmodule MatrixServer.RoomServer do
|
||||||
state_set,
|
state_set,
|
||||||
[create_room_id, join_creator_id]
|
[create_room_id, join_creator_id]
|
||||||
),
|
),
|
||||||
|
{:ok, _, state_set, room} <-
|
||||||
|
room_creation_preset(account, input, room, state_set, [
|
||||||
|
create_room_id,
|
||||||
|
join_creator_id,
|
||||||
|
pl_id
|
||||||
|
]),
|
||||||
{:ok, _, state_set, room} <-
|
{:ok, _, state_set, room} <-
|
||||||
room_creation_name(account, input, room, state_set, [
|
room_creation_name(account, input, room, state_set, [
|
||||||
create_room_id,
|
create_room_id,
|
||||||
|
@ -64,33 +70,74 @@ defmodule MatrixServer.RoomServer do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp room_creation_create_room(
|
defp room_creation_create_room(account, %CreateRoom{room_version: room_version}, room) do
|
||||||
%Account{localpart: localpart},
|
Event.create_room(room, account, room_version)
|
||||||
%CreateRoom{room_version: room_version},
|
|
||||||
room
|
|
||||||
) do
|
|
||||||
Event.create_room(room, MatrixServer.get_mxid(localpart), room_version)
|
|
||||||
|> verify_and_insert_event(%{}, room)
|
|> verify_and_insert_event(%{}, room)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp room_creation_join_creator(
|
defp room_creation_join_creator(account, room, state_set, auth_events) do
|
||||||
%Account{localpart: localpart},
|
Event.join(room, account)
|
||||||
room,
|
|
||||||
state_set,
|
|
||||||
auth_events
|
|
||||||
) do
|
|
||||||
Event.join(room, MatrixServer.get_mxid(localpart))
|
|
||||||
|> Map.put(:auth_events, auth_events)
|
|> Map.put(:auth_events, auth_events)
|
||||||
|> verify_and_insert_event(state_set, room)
|
|> verify_and_insert_event(state_set, room)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp room_creation_power_levels(
|
defp room_creation_power_levels(account, room, state_set, auth_events) do
|
||||||
%Account{localpart: localpart},
|
Event.power_levels(room, account)
|
||||||
room,
|
|> Map.put(:auth_events, auth_events)
|
||||||
|
|> verify_and_insert_event(state_set, room)
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO: trusted_private_chat:
|
||||||
|
# All invitees are given the same power level as the room creator.
|
||||||
|
defp room_creation_preset(
|
||||||
|
account,
|
||||||
|
%CreateRoom{preset: nil},
|
||||||
|
%Room{visibility: visibility} = room,
|
||||||
state_set,
|
state_set,
|
||||||
auth_events
|
auth_events
|
||||||
) do
|
) do
|
||||||
Event.power_levels(room, MatrixServer.get_mxid(localpart))
|
preset =
|
||||||
|
case visibility do
|
||||||
|
:public -> "public_chat"
|
||||||
|
:private -> "private_chat"
|
||||||
|
end
|
||||||
|
|
||||||
|
room_creation_preset(account, preset, room, state_set, auth_events)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp room_creation_preset(account, %CreateRoom{preset: preset}, room, state_set, auth_events) do
|
||||||
|
room_creation_preset(account, preset, room, state_set, auth_events)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp room_creation_preset(account, preset, room, state_set, auth_events) do
|
||||||
|
{join_rule, his_vis, guest_access} =
|
||||||
|
case preset do
|
||||||
|
"private_chat" -> {"invite", "shared", "can_join"}
|
||||||
|
"trusted_private_chat" -> {"invite", "shared", "can_join"}
|
||||||
|
"public_chat" -> {"public", "shared", "forbidden"}
|
||||||
|
end
|
||||||
|
|
||||||
|
with {:ok, _, _, _} <-
|
||||||
|
room_creation_join_rules(account, join_rule, room, state_set, auth_events),
|
||||||
|
{:ok, _, _, _} <- room_creation_his_vis(account, his_vis, room, state_set, auth_events) do
|
||||||
|
room_creation_guest_access(account, guest_access, room, state_set, auth_events)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp room_creation_join_rules(account, join_rule, room, state_set, auth_events) do
|
||||||
|
Event.join_rules(room, account, join_rule)
|
||||||
|
|> Map.put(:auth_events, auth_events)
|
||||||
|
|> verify_and_insert_event(state_set, room)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp room_creation_his_vis(account, his_vis, room, state_set, auth_events) do
|
||||||
|
Event.history_visibility(room, account, his_vis)
|
||||||
|
|> Map.put(:auth_events, auth_events)
|
||||||
|
|> verify_and_insert_event(state_set, room)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp room_creation_guest_access(account, guest_access, room, state_set, auth_events) do
|
||||||
|
Event.guest_access(room, account, guest_access)
|
||||||
|> Map.put(:auth_events, auth_events)
|
|> Map.put(:auth_events, auth_events)
|
||||||
|> verify_and_insert_event(state_set, room)
|
|> verify_and_insert_event(state_set, room)
|
||||||
end
|
end
|
||||||
|
@ -99,14 +146,8 @@ defmodule MatrixServer.RoomServer do
|
||||||
{:ok, nil, state_set, room}
|
{:ok, nil, state_set, room}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp room_creation_name(
|
defp room_creation_name(account, %CreateRoom{name: name}, room, state_set, auth_events) do
|
||||||
%Account{localpart: localpart},
|
Event.name(room, account, name)
|
||||||
%CreateRoom{name: name},
|
|
||||||
room,
|
|
||||||
state_set,
|
|
||||||
auth_events
|
|
||||||
) do
|
|
||||||
Event.name(room, MatrixServer.get_mxid(localpart), name)
|
|
||||||
|> Map.put(:auth_events, auth_events)
|
|> Map.put(:auth_events, auth_events)
|
||||||
|> verify_and_insert_event(state_set, room)
|
|> verify_and_insert_event(state_set, room)
|
||||||
end
|
end
|
||||||
|
@ -115,14 +156,8 @@ defmodule MatrixServer.RoomServer do
|
||||||
{:ok, nil, state_set, room}
|
{:ok, nil, state_set, room}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp room_creation_topic(
|
defp room_creation_topic(account, %CreateRoom{topic: topic}, room, state_set, auth_events) do
|
||||||
%Account{localpart: localpart},
|
Event.topic(room, account, topic)
|
||||||
%CreateRoom{topic: topic},
|
|
||||||
room,
|
|
||||||
state_set,
|
|
||||||
auth_events
|
|
||||||
) do
|
|
||||||
Event.topic(room, MatrixServer.get_mxid(localpart), topic)
|
|
||||||
|> Map.put(:auth_events, auth_events)
|
|> Map.put(:auth_events, auth_events)
|
||||||
|> verify_and_insert_event(state_set, room)
|
|> verify_and_insert_event(state_set, room)
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,14 +13,24 @@ defmodule MatrixServerWeb.API.CreateRoom do
|
||||||
field :topic, :string
|
field :topic, :string
|
||||||
field :invite, {:array, :string}
|
field :invite, {:array, :string}
|
||||||
field :room_version, :string
|
field :room_version, :string
|
||||||
|
field :preset, :string
|
||||||
# TODO: unimplemented:
|
# TODO: unimplemented:
|
||||||
# creation_content, initial_state, invite_3pid, initial_state, preset,
|
# creation_content, initial_state, invite_3pid, initial_state,
|
||||||
# is_direct, power_level_content_override
|
# is_direct, power_level_content_override
|
||||||
end
|
end
|
||||||
|
|
||||||
def changeset(params) do
|
def changeset(params) do
|
||||||
%__MODULE__{}
|
%__MODULE__{}
|
||||||
|> cast(params, [:visibility, :room_alias_name, :name, :topic, :invite, :room_version])
|
|> cast(params, [
|
||||||
|
:visibility,
|
||||||
|
:room_alias_name,
|
||||||
|
:name,
|
||||||
|
:topic,
|
||||||
|
:invite,
|
||||||
|
:room_version,
|
||||||
|
:preset
|
||||||
|
])
|
||||||
|
|> validate_inclusion(:preset, ["private_chat", "public_chat", "trusted_private_chat"])
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_error(%Changeset{errors: [error | _]}), do: get_error(error)
|
def get_error(%Changeset{errors: [error | _]}), do: get_error(error)
|
||||||
|
|
|
@ -14,6 +14,24 @@ Repo.insert(%Device{
|
||||||
# Auth difference example from here:
|
# Auth difference example from here:
|
||||||
# https://matrix.org/docs/guides/implementing-stateres#auth-differences
|
# https://matrix.org/docs/guides/implementing-stateres#auth-differences
|
||||||
|
|
||||||
|
alice =
|
||||||
|
Repo.insert!(%Account{
|
||||||
|
localpart: "alice",
|
||||||
|
password_hash: Bcrypt.hash_pwd_salt("sneed")
|
||||||
|
})
|
||||||
|
|
||||||
|
bob =
|
||||||
|
Repo.insert!(%Account{
|
||||||
|
localpart: "bob",
|
||||||
|
password_hash: Bcrypt.hash_pwd_salt("sneed")
|
||||||
|
})
|
||||||
|
|
||||||
|
charlie =
|
||||||
|
Repo.insert!(%Account{
|
||||||
|
localpart: "charlie",
|
||||||
|
password_hash: Bcrypt.hash_pwd_salt("sneed")
|
||||||
|
})
|
||||||
|
|
||||||
room =
|
room =
|
||||||
Repo.insert!(%Room{
|
Repo.insert!(%Room{
|
||||||
id: "room1",
|
id: "room1",
|
||||||
|
@ -21,13 +39,13 @@ 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, 0)
|
||||||
|> Map.put(:event_id, "create")
|
|> Map.put(:event_id, "create")
|
||||||
)
|
)
|
||||||
|
|
||||||
Repo.insert!(
|
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, 1)
|
||||||
|
@ -35,7 +53,7 @@ Repo.insert!(
|
||||||
)
|
)
|
||||||
|
|
||||||
Repo.insert!(
|
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, 2)
|
||||||
|
@ -43,14 +61,14 @@ Repo.insert!(
|
||||||
)
|
)
|
||||||
|
|
||||||
Repo.insert!(
|
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, 3)
|
||||||
|> Map.put(:event_id, "join_charlie")
|
|> Map.put(:event_id, "join_charlie")
|
||||||
)
|
)
|
||||||
|
|
||||||
%Event{content: content} = event = Event.power_levels(room, "alice")
|
%Event{content: content} = event = Event.power_levels(room, alice)
|
||||||
event = %Event{event | content: %{content | "users" => %{"alice" => 100, "bob" => 100}}}
|
event = %Event{event | content: %{content | "users" => %{"alice" => 100, "bob" => 100}}}
|
||||||
|
|
||||||
Repo.insert!(
|
Repo.insert!(
|
||||||
|
@ -61,7 +79,7 @@ Repo.insert!(
|
||||||
|> Map.put(:event_id, "a")
|
|> Map.put(:event_id, "a")
|
||||||
)
|
)
|
||||||
|
|
||||||
%Event{content: content} = event = Event.power_levels(room, "bob")
|
%Event{content: content} = event = Event.power_levels(room, bob)
|
||||||
|
|
||||||
event = %Event{
|
event = %Event{
|
||||||
event
|
event
|
||||||
|
@ -77,7 +95,7 @@ Repo.insert!(
|
||||||
)
|
)
|
||||||
|
|
||||||
Repo.insert!(
|
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, 5)
|
||||||
|
|
Loading…
Reference in a new issue