Implement client get/set avatar URL endpoint
This commit is contained in:
parent
b12872fe2c
commit
3e1a377226
7 changed files with 80 additions and 7 deletions
|
@ -56,6 +56,8 @@ Here, implemented and some unimplemented features are listed.
|
|||
- GET /_matrix/client/r0/directory/list/room/{roomId}
|
||||
- PUT /_matrix/client/r0/directory/list/room/{roomId}
|
||||
- GET /_matrix/client/r0/capabilities
|
||||
- GET /_matrix/client/r0/profile/{userId}/avatar_url: Except federation.
|
||||
- PUT /_matrix/client/r0/profile/{userId}/avatar_url
|
||||
|
||||
#### Federation API
|
||||
|
||||
|
|
|
@ -263,6 +263,10 @@ defmodule Architex do
|
|||
end
|
||||
|
||||
# https://stackoverflow.com/a/45754361
|
||||
@doc """
|
||||
Validate whether the given fields are not nil for the changeset.
|
||||
"""
|
||||
@spec validate_not_nil(Ecto.Changeset.t(), [atom()]) :: Ecto.Changeset.t()
|
||||
def validate_not_nil(changeset, fields) do
|
||||
Enum.reduce(fields, changeset, fn field, changeset ->
|
||||
if Ecto.Changeset.get_field(changeset, field) == nil do
|
||||
|
|
|
@ -16,6 +16,7 @@ defmodule Architex.Account do
|
|||
schema "accounts" do
|
||||
field :localpart, :string
|
||||
field :password_hash, :string, redact: true
|
||||
field :avatar_url
|
||||
has_many :devices, Device
|
||||
|
||||
many_to_many :joined_rooms, Room,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
defmodule ArchitexWeb.Client.AccountController do
|
||||
use ArchitexWeb, :controller
|
||||
|
||||
import Architex
|
||||
import ArchitexWeb.Error
|
||||
|
||||
alias Architex.{Account, Repo}
|
||||
|
@ -32,7 +31,7 @@ defmodule ArchitexWeb.Client.AccountController do
|
|||
Action for GET /_matrix/client/r0/account/whoami.
|
||||
"""
|
||||
def whoami(%Conn{assigns: %{account: %Account{localpart: localpart}}} = conn, _params) do
|
||||
data = %{user_id: get_mxid(localpart)}
|
||||
data = %{user_id: Architex.get_mxid(localpart)}
|
||||
|
||||
conn
|
||||
|> put_status(200)
|
||||
|
|
64
lib/architex_web/client/controllers/profile_controller.ex
Normal file
64
lib/architex_web/client/controllers/profile_controller.ex
Normal file
|
@ -0,0 +1,64 @@
|
|||
defmodule ArchitexWeb.Client.ProfileController do
|
||||
use ArchitexWeb, :controller
|
||||
|
||||
import ArchitexWeb.Error
|
||||
import Ecto.Query
|
||||
|
||||
alias Architex.{Repo, Account}
|
||||
alias Architex.Types.UserId
|
||||
alias Plug.Conn
|
||||
alias Ecto.Changeset
|
||||
|
||||
@doc """
|
||||
Get the user's avatar URL.
|
||||
|
||||
Action for GET /_matrix/client/r0/profile/{userId}/avatar_url.
|
||||
"""
|
||||
def get_avatar_url(conn, %{"user_id" => user_id}) do
|
||||
case UserId.cast(user_id) do
|
||||
{:ok, %UserId{localpart: localpart, domain: domain}} ->
|
||||
if domain == Architex.server_name() do
|
||||
case Repo.one(from a in Account, where: a.localpart == ^localpart) do
|
||||
%Account{avatar_url: avatar_url} ->
|
||||
data = if avatar_url, do: %{avatar_url: avatar_url}, else: %{}
|
||||
|
||||
conn
|
||||
|> put_status(200)
|
||||
|> json(data)
|
||||
|
||||
nil ->
|
||||
put_error(conn, :not_found, "User was not found.")
|
||||
end
|
||||
else
|
||||
# TODO: Use federation to lookup avatar URL.
|
||||
put_error(conn, :not_found, "User was not found.")
|
||||
end
|
||||
|
||||
:error ->
|
||||
put_error(conn, :not_found, "User ID is invalid.")
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
This API sets the given user's 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
|
||||
if Account.get_mxid(account) == user_id do
|
||||
avatar_url = Map.get(params, "avatar_url")
|
||||
|
||||
if not is_nil(avatar_url) do
|
||||
account
|
||||
|> Changeset.change(avatar_url: avatar_url)
|
||||
|> Repo.update()
|
||||
end
|
||||
|
||||
conn
|
||||
|> send_resp(200, [])
|
||||
|> halt()
|
||||
else
|
||||
put_error(conn, :unauthorized, "User ID does not match access token.")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -31,6 +31,7 @@ defmodule ArchitexWeb.Router do
|
|||
get "/login", LoginController, :login_types
|
||||
post "/login", LoginController, :login
|
||||
get "/directory/list/room/:room_id", RoomDirectoryController, :get_visibility
|
||||
get "/profile/:user_id/avatar_url", ProfileController, :get_avatar_url
|
||||
end
|
||||
|
||||
get "/versions", InfoController, :versions
|
||||
|
@ -55,6 +56,7 @@ defmodule ArchitexWeb.Router do
|
|||
get "/joined_rooms", RoomController, :joined_rooms
|
||||
get "/capabilities", InfoController, :capabilities
|
||||
get "/sync", SyncController, :sync
|
||||
put "/profile/:user_id/avatar_url", ProfileController, :set_avatar_url
|
||||
|
||||
scope "/directory" do
|
||||
put "/room/:alias", AliasesController, :create
|
||||
|
|
|
@ -5,13 +5,14 @@ defmodule Architex.Repo.Migrations.CreateInitialTables do
|
|||
create table(:accounts) do
|
||||
add :localpart, :string, null: false
|
||||
add :password_hash, :string, size: 60, null: false
|
||||
add :avatar_url, :string, null: true
|
||||
timestamps(updated_at: false)
|
||||
end
|
||||
|
||||
create index(:accounts, [:localpart], unique: true)
|
||||
|
||||
create table(:rooms, primary_key: false) do
|
||||
add :id, :string, primary_key: true, null: false
|
||||
add :id, :string, primary_key: true
|
||||
add :state, {:array, {:array, :string}}, default: [], null: false
|
||||
add :forward_extremities, {:array, :string}, default: [], null: false
|
||||
add :visibility, :string, null: false, default: "public"
|
||||
|
@ -43,7 +44,7 @@ defmodule Architex.Repo.Migrations.CreateInitialTables do
|
|||
|
||||
create table(:server_key_info, primary_key: false) do
|
||||
add :valid_until, :bigint, default: 0, null: false
|
||||
add :server_name, :string, primary_key: true, null: false
|
||||
add :server_name, :string, primary_key: true
|
||||
end
|
||||
|
||||
create table(:signing_keys, primary_key: false) do
|
||||
|
@ -51,12 +52,12 @@ defmodule Architex.Repo.Migrations.CreateInitialTables do
|
|||
references(:server_key_info, column: :server_name, type: :string, on_delete: :delete_all),
|
||||
null: false
|
||||
|
||||
add :signing_key_id, :string, primary_key: true, null: false
|
||||
add :signing_key_id, :string, primary_key: true
|
||||
add :signing_key, :binary, null: false
|
||||
end
|
||||
|
||||
create table(:aliases, primary_key: false) do
|
||||
add :alias, :string, primary_key: true, null: false
|
||||
add :alias, :string, primary_key: true
|
||||
add :room_id, references(:rooms, type: :string, on_delete: :delete_all), null: false
|
||||
end
|
||||
|
||||
|
@ -76,7 +77,7 @@ defmodule Architex.Repo.Migrations.CreateInitialTables do
|
|||
create index(:devices, [:access_token], unique: true)
|
||||
|
||||
create table(:device_transactions, primary_key: false) do
|
||||
add :txn_id, :string, primary_key: true, null: false
|
||||
add :txn_id, :string, primary_key: true
|
||||
|
||||
add :device_nid, references(:devices, column: :nid, on_delete: :delete_all),
|
||||
primary_key: true
|
||||
|
|
Loading…
Reference in a new issue