Implement client get/set display name endpoint

Add ability to unset avatar URL/display name
This commit is contained in:
Pim Kunis 2021-09-08 17:32:10 +02:00
parent 3e1a377226
commit af40cebc01
4 changed files with 61 additions and 17 deletions

View file

@ -16,7 +16,8 @@ defmodule Architex.Account do
schema "accounts" do schema "accounts" do
field :localpart, :string field :localpart, :string
field :password_hash, :string, redact: true field :password_hash, :string, redact: true
field :avatar_url field :avatar_url, :string
field :displayname, :string
has_many :devices, Device has_many :devices, Device
many_to_many :joined_rooms, Room, many_to_many :joined_rooms, Room,

View file

@ -1,4 +1,5 @@
defmodule ArchitexWeb.Client.ProfileController do defmodule ArchitexWeb.Client.ProfileController do
# TODO: Changes should be propagated using join events and presence.
use ArchitexWeb, :controller use ArchitexWeb, :controller
import ArchitexWeb.Error import ArchitexWeb.Error
@ -9,18 +10,32 @@ defmodule ArchitexWeb.Client.ProfileController do
alias Plug.Conn alias Plug.Conn
alias Ecto.Changeset alias Ecto.Changeset
@doc """
Get the user's display name.
Action for GET /_matrix/client/r0/profile/{userId}/displayname.
"""
def get_displayname(conn, %{"user_id" => user_id}) do
get_property(conn, :displayname, user_id)
end
@doc """ @doc """
Get the user's avatar URL. Get the user's avatar URL.
Action for GET /_matrix/client/r0/profile/{userId}/avatar_url. Action for GET /_matrix/client/r0/profile/{userId}/avatar_url.
""" """
def get_avatar_url(conn, %{"user_id" => user_id}) do def get_avatar_url(conn, %{"user_id" => user_id}) do
get_property(conn, :avatar_url, user_id)
end
defp get_property(conn, property_key, user_id) do
case UserId.cast(user_id) do case UserId.cast(user_id) do
{:ok, %UserId{localpart: localpart, domain: domain}} -> {:ok, %UserId{localpart: localpart, domain: domain}} ->
if domain == Architex.server_name() do if domain == Architex.server_name() do
case Repo.one(from a in Account, where: a.localpart == ^localpart) do case Repo.one(from a in Account, where: a.localpart == ^localpart) do
%Account{avatar_url: avatar_url} -> %Account{} = account ->
data = if avatar_url, do: %{avatar_url: avatar_url}, else: %{} property_val = Map.get(account, property_key)
data = if property_val, do: %{property_key => property_val}, else: %{}
conn conn
|> put_status(200) |> put_status(200)
@ -39,21 +54,34 @@ defmodule ArchitexWeb.Client.ProfileController do
end end
end end
@doc """
This API sets the given user's display name.
Action for PUT /_matrix/client/r0/profile/{userId}/displayname.
"""
def set_displayname(conn, %{"user_id" => user_id} = params) do
displayname = Map.get(params, "displayname")
update_property(conn, :displayname, displayname, user_id)
end
@doc """ @doc """
This API sets the given user's avatar URL. This API sets the given user's avatar URL.
Action for PUT /_matrix/client/r0/profile/{userId}/avatar_url. Action for PUT /_matrix/client/r0/profile/{userId}/avatar_url.
""" """
def set_avatar_url(%Conn{assigns: %{account: account}} = conn, %{"user_id" => user_id} = params) do def set_avatar_url(conn, %{"user_id" => user_id} = params) do
if Account.get_mxid(account) == user_id do
avatar_url = Map.get(params, "avatar_url") avatar_url = Map.get(params, "avatar_url")
if not is_nil(avatar_url) do update_property(conn, :avatar_url, avatar_url, user_id)
account
|> Changeset.change(avatar_url: avatar_url)
|> Repo.update()
end end
defp update_property(%Conn{assigns: %{account: account}} = conn, property_key, property, user_id) do
if Account.get_mxid(account) == user_id do
account
|> Changeset.change([{property_key, property}])
|> Repo.update()
conn conn
|> send_resp(200, []) |> send_resp(200, [])
|> halt() |> halt()

View file

@ -26,12 +26,22 @@ defmodule ArchitexWeb.Router do
pipe_through :public pipe_through :public
scope "/r0" do scope "/r0" do
post "/register", RegisterController, :register
get "/register/available", AccountController, :available
get "/login", LoginController, :login_types
post "/login", LoginController, :login
get "/directory/list/room/:room_id", RoomDirectoryController, :get_visibility get "/directory/list/room/:room_id", RoomDirectoryController, :get_visibility
get "/profile/:user_id/avatar_url", ProfileController, :get_avatar_url
scope "/login" do
get "/", LoginController, :login_types
post "/", LoginController, :login
end
scope "/register" do
post "/", RegisterController, :register
get "/available", AccountController, :available
end
scope "/profile/:user_id" do
get "/avatar_url", ProfileController, :get_avatar_url
get "/displayname", ProfileController, :get_displayname
end
end end
get "/versions", InfoController, :versions get "/versions", InfoController, :versions
@ -56,7 +66,11 @@ defmodule ArchitexWeb.Router do
get "/joined_rooms", RoomController, :joined_rooms get "/joined_rooms", RoomController, :joined_rooms
get "/capabilities", InfoController, :capabilities get "/capabilities", InfoController, :capabilities
get "/sync", SyncController, :sync get "/sync", SyncController, :sync
put "/profile/:user_id/avatar_url", ProfileController, :set_avatar_url
scope "/profile/:user_id" do
put "/avatar_url", ProfileController, :set_avatar_url
put "/displayname", ProfileController, :set_displayname
end
scope "/directory" do scope "/directory" do
put "/room/:alias", AliasesController, :create put "/room/:alias", AliasesController, :create

View file

@ -6,6 +6,7 @@ defmodule Architex.Repo.Migrations.CreateInitialTables do
add :localpart, :string, null: false add :localpart, :string, null: false
add :password_hash, :string, size: 60, null: false add :password_hash, :string, size: 60, null: false
add :avatar_url, :string, null: true add :avatar_url, :string, null: true
add :displayname, :string, null: true
timestamps(updated_at: false) timestamps(updated_at: false)
end end