Implement client get state event endpoint
This commit is contained in:
parent
222b6a309a
commit
f700be5dbe
4 changed files with 93 additions and 5 deletions
|
@ -62,6 +62,7 @@ Here, implemented and some unimplemented features are listed.
|
|||
- PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}
|
||||
- GET /_matrix/client/r0/rooms/{roomId}/messages: Except filtering.
|
||||
- GET /_matrix/client/r0/rooms/{roomId}/state
|
||||
- GET /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}
|
||||
- GET /_matrix/client/r0/directory/list/room/{roomId}
|
||||
- PUT /_matrix/client/r0/directory/list/room/{roomId}
|
||||
- GET /_matrix/client/r0/capabilities
|
||||
|
|
|
@ -200,6 +200,12 @@ defmodule Architex.RoomServer do
|
|||
GenServer.call(pid, {:get_current_state, account})
|
||||
end
|
||||
|
||||
@spec get_state_event(pid(), Account.t(), String.t(), String.t()) ::
|
||||
{:ok, map()} | {:error, :unauthorized} | {:error, :not_found}
|
||||
def get_state_event(pid, account, event_type, state_key) do
|
||||
GenServer.call(pid, {:get_state_event, account, event_type, state_key})
|
||||
end
|
||||
|
||||
### Implementation
|
||||
|
||||
@impl true
|
||||
|
@ -445,6 +451,10 @@ defmodule Architex.RoomServer do
|
|||
|
||||
%Event{content: %{"membership" => "leave"}} = event ->
|
||||
# Get the state of the room, after leaving.
|
||||
# TODO: This does not work properly, as a user's membership can change to "leave"
|
||||
# even after they left/are banned.
|
||||
# I think it is best to seperately keep track when a user left, maybe in the
|
||||
# Membership table.
|
||||
state_set = StateResolution.resolve(event)
|
||||
{:reply, {:ok, Map.values(state_set)}, state}
|
||||
|
||||
|
@ -453,6 +463,34 @@ defmodule Architex.RoomServer do
|
|||
end
|
||||
end
|
||||
|
||||
def handle_call(
|
||||
{:get_state_event, account, event_type, state_key},
|
||||
_from,
|
||||
%{state_set: state_set} = state
|
||||
) do
|
||||
mxid = Account.get_mxid(account)
|
||||
|
||||
case state_set[{"m.room.member", mxid}] do
|
||||
%Event{content: %{"membership" => "join"}} ->
|
||||
case state_set[{event_type, state_key}] do
|
||||
%Event{content: content} -> {:reply, {:ok, content}, state}
|
||||
nil -> {:reply, {:error, :not_found}, state}
|
||||
end
|
||||
|
||||
%Event{content: %{"membership" => "leave"}} = event ->
|
||||
# TODO: See get_current_state.
|
||||
state_set = StateResolution.resolve(event)
|
||||
|
||||
case state_set[{event_type, state_key}] do
|
||||
%Event{content: content} -> {:reply, {:ok, content}, state}
|
||||
nil -> {:reply, {:error, :not_found}, state}
|
||||
end
|
||||
|
||||
_ ->
|
||||
{:reply, {:error, :unauthorized}, state}
|
||||
end
|
||||
end
|
||||
|
||||
@spec process_event_with_txn(t(), Room.t(), Device.t(), %Event{}, String.t()) ::
|
||||
(() -> {t(), Room.t(), String.t()} | {:error, atom()})
|
||||
defp process_event_with_txn(
|
||||
|
|
|
@ -317,7 +317,7 @@ defmodule ArchitexWeb.Client.RoomController do
|
|||
|
||||
Action for GET /_matrix/client/r0/rooms/{roomId}/state.
|
||||
"""
|
||||
def state(%Conn{assigns: %{account: account}} = conn, %{"room_id" => room_id}) do
|
||||
def get_state(%Conn{assigns: %{account: account}} = conn, %{"room_id" => room_id}) do
|
||||
case RoomServer.get_room_server(room_id) do
|
||||
{:ok, pid} ->
|
||||
case RoomServer.get_current_state(pid, account) do
|
||||
|
@ -340,4 +340,46 @@ defmodule ArchitexWeb.Client.RoomController do
|
|||
put_error(conn, :not_found, "The given room was not found.")
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Looks up the contents of a state event in a room.
|
||||
|
||||
Action for GET /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}.
|
||||
"""
|
||||
def get_state_event(conn, %{"state_key" => [state_key | _]} = params) do
|
||||
do_get_state_event(conn, params, state_key)
|
||||
end
|
||||
|
||||
def get_state_event(conn, params) do
|
||||
do_get_state_event(conn, params, "")
|
||||
end
|
||||
|
||||
defp do_get_state_event(
|
||||
%Conn{assigns: %{account: account}} = conn,
|
||||
%{"room_id" => room_id, "event_type" => event_type},
|
||||
state_key
|
||||
) do
|
||||
case RoomServer.get_room_server(room_id) do
|
||||
{:ok, pid} ->
|
||||
case RoomServer.get_state_event(pid, account, event_type, state_key) do
|
||||
{:ok, content} ->
|
||||
conn
|
||||
|> put_status(200)
|
||||
|> json(content)
|
||||
|
||||
{:error, :unauthorized} ->
|
||||
put_error(
|
||||
conn,
|
||||
:forbidden,
|
||||
"You aren't a member of the room and weren't previously a member of the room."
|
||||
)
|
||||
|
||||
{:error, :not_found} ->
|
||||
put_error(conn, :not_found, "The room has no state with the given type or key.")
|
||||
end
|
||||
|
||||
{:error, :not_found} ->
|
||||
put_error(conn, :not_found, "The given room was not found.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -61,13 +61,16 @@ defmodule ArchitexWeb.Router do
|
|||
|
||||
scope "/r0" do
|
||||
get "/account/whoami", AccountController, :whoami
|
||||
post "/logout", AccountController, :logout
|
||||
post "/logout/all", AccountController, :logout_all
|
||||
post "/createRoom", RoomController, :create
|
||||
get "/joined_rooms", RoomController, :joined_rooms
|
||||
get "/capabilities", InfoController, :capabilities
|
||||
get "/sync", SyncController, :sync
|
||||
|
||||
scope "/logout" do
|
||||
post "/", AccountController, :logout
|
||||
post "/all", AccountController, :logout_all
|
||||
end
|
||||
|
||||
scope "/profile/:user_id" do
|
||||
put "/avatar_url", ProfileController, :set_avatar_url
|
||||
put "/displayname", ProfileController, :set_displayname
|
||||
|
@ -89,8 +92,12 @@ defmodule ArchitexWeb.Router do
|
|||
get "/messages", RoomController, :messages
|
||||
|
||||
scope "/state" do
|
||||
get "/", RoomController, :state
|
||||
put "/:event_type/*state_key", RoomController, :send_state_event
|
||||
get "/", RoomController, :get_state
|
||||
|
||||
scope "/:event_type/*state_key" do
|
||||
get "/", RoomController, :get_state_event
|
||||
put "/", RoomController, :send_state_event
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue