From 658efa228fdcfb1c62b8e267cb3af544ca65f21b Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Wed, 25 Aug 2021 12:25:14 +0200 Subject: [PATCH] Implement client join endpoint --- lib/matrix_server/room_server.ex | 32 +++++++++++++++++++ .../state_resolution/authorization.ex | 3 -- .../client/controllers/room_controller.ex | 26 +++++++++++++++ lib/matrix_server_web/router.ex | 1 + 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/lib/matrix_server/room_server.ex b/lib/matrix_server/room_server.ex index 29a7d27..7e8be49 100644 --- a/lib/matrix_server/room_server.ex +++ b/lib/matrix_server/room_server.ex @@ -107,6 +107,14 @@ defmodule MatrixServer.RoomServer do GenServer.call(pid, {:invite, account, user_id}) end + @doc """ + Join a room. + """ + @spec join(pid(), Account.t()) :: {:ok, String.t()} | {:error, atom()} + def join(pid, account) do + GenServer.call(pid, {:join, account}) + end + ### Implementation @impl true @@ -200,6 +208,30 @@ defmodule MatrixServer.RoomServer do end end + def handle_call({:join, account}, _from, %{room: %Room{id: room_id} = room, state_set: state_set} = state) do + case Repo.transaction(join_insert_event(room, state_set, account)) do + {:ok, state_set} -> {:reply, {:ok, room_id}, %{state | state_set: state_set}} + {:error, reason} -> {:reply, {:error, reason}, state} + end + end + + # Get a function that inserts a join event into the room for the given account. + @spec join_insert_event(Room.t(), t(), Account.t()) :: (-> {:ok, t()} | {:error, atom()}) + defp join_insert_event(room, state_set, account) do + join_event = Event.join(room, account) + + fn -> + case finalize_and_insert_event(join_event, state_set, room) do + {:ok, state_set, room} -> + _ = update_room_state_set(room, state_set) + state_set + + {:error, reason} -> + Repo.rollback(reason) + end + end + end + # Get a function that inserts an invite event into a room. @spec invite_insert_event(Room.t(), t(), Account.t(), String.t()) :: (() -> {:ok, t()} | {:error, atom()}) diff --git a/lib/matrix_server/state_resolution/authorization.ex b/lib/matrix_server/state_resolution/authorization.ex index 68ec447..c643d1d 100644 --- a/lib/matrix_server/state_resolution/authorization.ex +++ b/lib/matrix_server/state_resolution/authorization.ex @@ -312,9 +312,6 @@ defmodule MatrixServer.StateResolution.Authorization do |> Repo.all() |> Enum.reduce(%{}, &update_state_set/2) - IO.inspect(event) - IO.inspect(state_set) - authorized?(event, state_set) end end diff --git a/lib/matrix_server_web/client/controllers/room_controller.ex b/lib/matrix_server_web/client/controllers/room_controller.ex index 0b537ac..bb94754 100644 --- a/lib/matrix_server_web/client/controllers/room_controller.ex +++ b/lib/matrix_server_web/client/controllers/room_controller.ex @@ -86,4 +86,30 @@ defmodule MatrixServerWeb.Client.RoomController do end def invite(conn, _), do: put_error(conn, :missing_param) + + @doc """ + This API starts a user participating in a particular room, if that user is allowed to participate in that room. + + Action for POST /_matrix/client/r0/rooms/{roomId}/join. + TODO: third_party_signed + """ + def join(%Conn{assigns: %{account: account}} = conn, %{"room_id" => room_id}) do + case RoomServer.get_room_server(room_id) do + {:ok, pid} -> + case RoomServer.join(pid, account) do + {:ok, room_id} -> + conn + |> put_status(200) + |> json(%{room_id: room_id}) + + {:error, _} -> + put_error(conn, :unknown) + end + + {:error, :not_found} -> + put_error(conn, :not_found, "The given room was not found.") + end + end + + def join(conn, _), do: put_error(conn, :missing_param) end diff --git a/lib/matrix_server_web/router.ex b/lib/matrix_server_web/router.ex index f82fc7d..bb60f87 100644 --- a/lib/matrix_server_web/router.ex +++ b/lib/matrix_server_web/router.ex @@ -59,6 +59,7 @@ defmodule MatrixServerWeb.Router do scope "/rooms/:room_id" do post "/invite", RoomController, :invite + post "/join", RoomController, :join end end end