Implement get/set visibility client endpoints

This commit is contained in:
Pim Kunis 2021-08-27 15:09:17 +02:00
parent 2088f0a869
commit de950fc769
3 changed files with 91 additions and 3 deletions

View file

@ -146,6 +146,14 @@ defmodule MatrixServer.RoomServer do
GenServer.call(pid, {:unban, account, user_id}) GenServer.call(pid, {:unban, account, user_id})
end 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 ### Implementation
@impl true @impl true
@ -306,6 +314,26 @@ defmodule MatrixServer.RoomServer do
end end
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()} @spec insert_single_event(Room.t(), t(), Event.t()) :: {:ok, {t(), Room.t()}} | {:error, atom()}
defp insert_single_event(room, state_set, event) do defp insert_single_event(room, state_set, event) do
Repo.transaction(fn -> Repo.transaction(fn ->

View file

@ -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

View file

@ -30,6 +30,7 @@ defmodule MatrixServerWeb.Router do
get "/register/available", AccountController, :available get "/register/available", AccountController, :available
get "/login", LoginController, :login_types get "/login", LoginController, :login_types
post "/login", LoginController, :login post "/login", LoginController, :login
get "/directory/list/room/:room_id", RoomDirectoryController, :get_visibility
end end
get "/versions", InfoController, :versions get "/versions", InfoController, :versions
@ -53,8 +54,9 @@ defmodule MatrixServerWeb.Router do
post "/createRoom", RoomController, :create post "/createRoom", RoomController, :create
get "/joined_rooms", RoomController, :joined_rooms get "/joined_rooms", RoomController, :joined_rooms
scope "/directory/room" do scope "/directory" do
put "/:alias", AliasesController, :create put "/room/:alias", AliasesController, :create
put "/list/room/:room_id", RoomDirectoryController, :set_visibility
end end
scope "/rooms/:room_id" do scope "/rooms/:room_id" do