From de950fc769e9f34206501af1c7642553c9f1f709 Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Fri, 27 Aug 2021 15:09:17 +0200 Subject: [PATCH] Implement get/set visibility client endpoints --- lib/matrix_server/room_server.ex | 30 +++++++++- .../controllers/room_directory_controller.ex | 58 +++++++++++++++++++ lib/matrix_server_web/router.ex | 6 +- 3 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 lib/matrix_server_web/client/controllers/room_directory_controller.ex diff --git a/lib/matrix_server/room_server.ex b/lib/matrix_server/room_server.ex index c68fef7..c104b85 100644 --- a/lib/matrix_server/room_server.ex +++ b/lib/matrix_server/room_server.ex @@ -146,6 +146,14 @@ defmodule MatrixServer.RoomServer do GenServer.call(pid, {:unban, account, user_id}) end + @doc """ + Attempt to set the room's visibility. + """ + @spec set_visibility(pid(), Account.t(), atom()) :: :ok | {:error, atom()} + def set_visibility(pid, account, visibility) do + GenServer.call(pid, {:set_visibility, account, visibility}) + end + ### Implementation @impl true @@ -297,7 +305,7 @@ defmodule MatrixServer.RoomServer do end end - def handle_call({:unban, account, user_id},_from,%{room: room, state_set: state_set} = state) do + def handle_call({:unban, account, user_id}, _from, %{room: room, state_set: state_set} = state) do unban_event = Event.unban(room, account, user_id) case insert_single_event(room, state_set, unban_event) do @@ -306,6 +314,26 @@ defmodule MatrixServer.RoomServer do end end + def handle_call( + {:set_visibility, account, visibility}, + _from, + %{room: room, state_set: state_set} = state + ) do + case state_set do + %{{"m.room.create", ""} => %Event{content: %{"creator" => creator}}} -> + if creator == Account.get_mxid(account) do + room = Repo.update!(change(room, visibility: visibility)) + + {:reply, :ok, %{state | room: room}} + else + {:reply, {:error, :unauthorized}, state} + end + + _ -> + {:reply, {:error, :unknown}, state} + end + end + @spec insert_single_event(Room.t(), t(), Event.t()) :: {:ok, {t(), Room.t()}} | {:error, atom()} defp insert_single_event(room, state_set, event) do Repo.transaction(fn -> diff --git a/lib/matrix_server_web/client/controllers/room_directory_controller.ex b/lib/matrix_server_web/client/controllers/room_directory_controller.ex new file mode 100644 index 0000000..b69bfff --- /dev/null +++ b/lib/matrix_server_web/client/controllers/room_directory_controller.ex @@ -0,0 +1,58 @@ +defmodule MatrixServerWeb.Client.RoomDirectoryController do + use MatrixServerWeb, :controller + + import MatrixServerWeb.Error + import Ecto.Query + + alias MatrixServer.{Repo, Room, RoomServer} + alias Plug.Conn + + @doc """ + Gets the visibility of a given room on the server's public room directory. + + Action for GET /_matrix/client/r0/directory/list/room/{roomId}. + """ + def get_visibility(conn, %{"room_id" => room_id}) do + case Repo.one(from r in Room, where: r.id == ^room_id) do + %Room{visibility: visibility} -> + conn + |> put_status(200) + |> json(%{visibility: visibility}) + + nil -> + put_error(conn, :not_found, "The room was not found.") + end + end + + @doc """ + Sets the visibility of a given room in the server's public room directory. + + Only allow the creator of the room to change visibility. + Action for PUT /_matrix/client/r0/directory/list/room/{roomId}. + """ + def set_visibility(%Conn{assigns: %{account: account}} = conn, %{"room_id" => room_id} = params) do + visibility = Map.get(params, "visibility", "public") + + if visibility in ["public", "private"] do + visibility = String.to_atom(visibility) + + with {:ok, pid} <- RoomServer.get_room_server(room_id), + :ok <- RoomServer.set_visibility(pid, account, visibility) do + conn + |> send_resp(200, []) + |> halt() + else + {:error, :not_found} -> + put_error(conn, :not_found, "The given room was not found.") + + {:error, :unauthorized} -> + put_error(conn, :unauthorized, "Only the room's creator can change visibility.") + + {:error, _} -> + put_error(conn, :unknown) + end + else + put_error(conn, :invalid_param, "Invalid visibility.") + end + end +end diff --git a/lib/matrix_server_web/router.ex b/lib/matrix_server_web/router.ex index b7004fa..1908588 100644 --- a/lib/matrix_server_web/router.ex +++ b/lib/matrix_server_web/router.ex @@ -30,6 +30,7 @@ defmodule MatrixServerWeb.Router do get "/register/available", AccountController, :available get "/login", LoginController, :login_types post "/login", LoginController, :login + get "/directory/list/room/:room_id", RoomDirectoryController, :get_visibility end get "/versions", InfoController, :versions @@ -53,8 +54,9 @@ defmodule MatrixServerWeb.Router do post "/createRoom", RoomController, :create get "/joined_rooms", RoomController, :joined_rooms - scope "/directory/room" do - put "/:alias", AliasesController, :create + scope "/directory" do + put "/room/:alias", AliasesController, :create + put "/list/room/:room_id", RoomDirectoryController, :set_visibility end scope "/rooms/:room_id" do