diff --git a/lib/matrix_server/room.ex b/lib/matrix_server/room.ex index df5db54..c01b647 100644 --- a/lib/matrix_server/room.ex +++ b/lib/matrix_server/room.ex @@ -4,7 +4,7 @@ defmodule MatrixServer.Room do import Ecto.Changeset import Ecto.Query - alias MatrixServer.{Repo, Room, Event} + alias MatrixServer.{Repo, Room, Event, RoomServer} alias MatrixServerWeb.API.CreateRoom @primary_key {:id, :string, []} @@ -39,10 +39,20 @@ defmodule MatrixServer.Room do ) do new_forward_extremities = [event_id | forward_extremities -- prev_event_ids] + # TODO: might not need to save to DB here. {_, [room]} = from(r in Room, where: r.id == ^room_id, select: r) |> Repo.update_all(set: [forward_extremities: new_forward_extremities]) room end + + def create(account, input) do + with {:ok, %Room{id: room_id}} <- Repo.insert(create_changeset(input)), + {:ok, pid} <- RoomServer.get_room_server(room_id) do + RoomServer.create_room(pid, account, input) + else + _ -> {:error, :unknown} + end + end end diff --git a/lib/matrix_server/room_server.ex b/lib/matrix_server/room_server.ex index 252528b..e0465c6 100644 --- a/lib/matrix_server/room_server.ex +++ b/lib/matrix_server/room_server.ex @@ -114,8 +114,9 @@ defmodule MatrixServer.RoomServer do end) case result do - {:ok, state_set} -> {:reply, :ok, %{state | state_set: state_set}} + {:ok, state_set} -> {:reply, {:ok, room_id}, %{state | state_set: state_set}} {:error, reason} -> {:reply, {:error, reason}, state} + _ -> {:reply, {:error, :unknown}, state} end end @@ -160,28 +161,17 @@ defmodule MatrixServer.RoomServer do # 6. Passes authorization rules based on the current state of the room, otherwise it is "soft failed". event = %Event{event | prev_events: forward_extremities} - if Event.prevalidate(event) do - if Authorization.authorized_by_auth_events?(event) do - state_set = StateResolution.resolve(event, false) - - if Authorization.authorized?(event, state_set) do - if Authorization.authorized?(event, current_state_set) do - # We assume here that the event is always a forward extremity. - room = Room.update_forward_extremities(event, room) - event = Repo.insert!(event) - state_set = StateResolution.resolve_forward_extremities(event) - {:ok, state_set, room} - else - {:error, :soft_failed} - end - else - {:error, :rejected} - end - else - {:error, :rejected} - end + with true <- Event.prevalidate(event), + true <- Authorization.authorized_by_auth_events?(event), + state_set <- StateResolution.resolve(event, false), + true <- Authorization.authorized?(event, state_set), + true <- Authorization.authorized?(event, current_state_set) do + room = Room.update_forward_extremities(event, room) + event = Repo.insert!(event) + state_set = StateResolution.resolve_forward_extremities(event) + {:ok, state_set, room} else - {:error, :invalid} + _ -> {:error, :authorization} end end end diff --git a/lib/matrix_server_web/controllers/room_controller.ex b/lib/matrix_server_web/controllers/room_controller.ex index fc00b43..1b874f7 100644 --- a/lib/matrix_server_web/controllers/room_controller.ex +++ b/lib/matrix_server_web/controllers/room_controller.ex @@ -4,7 +4,7 @@ defmodule MatrixServerWeb.RoomController do import MatrixServerWeb.Plug.Error import Ecto.Changeset - alias MatrixServer.{Repo, Room, RoomServer} + alias MatrixServer.Room alias MatrixServerWeb.API.{CreateRoom} alias Ecto.Changeset alias Plug.Conn @@ -14,15 +14,18 @@ defmodule MatrixServerWeb.RoomController do %Changeset{valid?: true} = cs -> input = apply_changes(cs) - # TODO: refactor - # Room.create(account, input) - # %Room{id: room_id} = Repo.insert!(Room.create_changeset(input)) - # {:ok, pid} = RoomServer.get_room_server(room_id) - # RoomServer.create_room(pid, account, input) + case Room.create(account, input) do + {:ok, room_id} -> + conn + |> put_status(200) + |> json(%{room_id: room_id}) - conn - |> put_status(200) - |> json(%{}) + {:error, :authorization} -> + put_error(conn, :invalid_room_state) + + {:error, :unknown} -> + put_error(conn, :unknown) + end _ -> put_error(conn, :bad_json) diff --git a/lib/matrix_server_web/plug/error.ex b/lib/matrix_server_web/plug/error.ex index a2ff711..465232d 100644 --- a/lib/matrix_server_web/plug/error.ex +++ b/lib/matrix_server_web/plug/error.ex @@ -9,13 +9,15 @@ defmodule MatrixServerWeb.Plug.Error do forbidden: {400, "M_FORBIDDEN", "The requested action is forbidden."}, unrecognized: {400, "M_UNRECOGNIZED", "Unrecognized request."}, unknown: {400, "M_UNKNOWN", "An unknown error occurred."}, + invalid_room_state: + {400, "M_INVALID_ROOM_STATE", "The request would result in and invalid room state."}, unknown_token: {401, "M_UNKNOWN_TOKEN", "Invalid access token."}, missing_token: {401, "M_MISSING_TOKEN", "Access token required."} } def put_error(conn, error, msg \\ nil) do {status, errcode, default_msg} = @error_map[error] - data = %{errcode: errcode, error: msg or default_msg} + data = %{errcode: errcode, error: msg || default_msg} conn |> put_status(status)