feat: expose CRUD, onboarding, pubsub via web
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
defmodule Localiser.Web.Controllers.UserController do
|
||||
use Phoenix.Controller, formats: [:json]
|
||||
use OpenApiSpex.ControllerSpecs
|
||||
|
||||
alias Localiser.Domain.Users
|
||||
alias Localiser.Web.Schemas
|
||||
|
||||
tags ["Users"]
|
||||
security [%{"bearerAuth" => []}]
|
||||
|
||||
operation :me,
|
||||
summary: "Get own profile",
|
||||
responses: [
|
||||
ok: {"Current user", "application/json", Schemas.User},
|
||||
unauthorized: {"Unauthorized", "application/json", Schemas.Error}
|
||||
]
|
||||
|
||||
operation :index,
|
||||
summary: "List all users (admin)",
|
||||
responses: [
|
||||
ok: {"User list", "application/json", %OpenApiSpex.Schema{type: :array, items: Schemas.User}},
|
||||
unauthorized: {"Unauthorized", "application/json", Schemas.Error},
|
||||
forbidden: {"Forbidden", "application/json", Schemas.Error}
|
||||
]
|
||||
|
||||
operation :show,
|
||||
summary: "Get a user (admin)",
|
||||
parameters: [id: [in: :path, type: :integer, required: true]],
|
||||
responses: [
|
||||
ok: {"User", "application/json", Schemas.User},
|
||||
unauthorized: {"Unauthorized", "application/json", Schemas.Error},
|
||||
forbidden: {"Forbidden", "application/json", Schemas.Error}
|
||||
]
|
||||
|
||||
operation :create,
|
||||
summary: "Create a user (admin)",
|
||||
request_body: {"User params", "application/json", Schemas.UserCreateParams, required: true},
|
||||
responses: [
|
||||
created: {"Created user", "application/json", Schemas.User},
|
||||
unauthorized: {"Unauthorized", "application/json", Schemas.Error},
|
||||
forbidden: {"Forbidden", "application/json", Schemas.Error},
|
||||
unprocessable_entity: {"Validation errors", "application/json", Schemas.ValidationErrors}
|
||||
]
|
||||
|
||||
operation :update,
|
||||
summary: "Update a user (admin)",
|
||||
parameters: [id: [in: :path, type: :integer, required: true]],
|
||||
request_body: {"User params", "application/json", Schemas.UserUpdateParams},
|
||||
responses: [
|
||||
ok: {"Updated user", "application/json", Schemas.User},
|
||||
unauthorized: {"Unauthorized", "application/json", Schemas.Error},
|
||||
forbidden: {"Forbidden", "application/json", Schemas.Error},
|
||||
unprocessable_entity: {"Validation errors", "application/json", Schemas.ValidationErrors}
|
||||
]
|
||||
|
||||
operation :delete,
|
||||
summary: "Delete a user (admin)",
|
||||
parameters: [id: [in: :path, type: :integer, required: true]],
|
||||
responses: [
|
||||
no_content: "Deleted",
|
||||
unauthorized: {"Unauthorized", "application/json", Schemas.Error},
|
||||
forbidden: {"Forbidden", "application/json", Schemas.Error}
|
||||
]
|
||||
|
||||
operation :promote,
|
||||
summary: "Promote a user to admin",
|
||||
parameters: [id: [in: :path, type: :integer, required: true]],
|
||||
responses: [
|
||||
ok: {"Updated user", "application/json", Schemas.User},
|
||||
unauthorized: {"Unauthorized", "application/json", Schemas.Error},
|
||||
forbidden: {"Forbidden", "application/json", Schemas.Error}
|
||||
]
|
||||
|
||||
def me(conn, _params) do
|
||||
json(conn, render_user(conn.assigns.current_user))
|
||||
end
|
||||
|
||||
def index(conn, _params) do
|
||||
json(conn, Enum.map(Users.list_users(), &render_user/1))
|
||||
end
|
||||
|
||||
def show(conn, %{"id" => id}) do
|
||||
user = Users.get_user!(id)
|
||||
json(conn, render_user(user))
|
||||
end
|
||||
|
||||
def create(conn, params) do
|
||||
case Users.create_user(params) do
|
||||
{:ok, user} ->
|
||||
conn
|
||||
|> put_status(:created)
|
||||
|> json(render_user(user))
|
||||
|
||||
{:error, changeset} ->
|
||||
conn
|
||||
|> put_status(:unprocessable_entity)
|
||||
|> json(%{errors: format_errors(changeset)})
|
||||
end
|
||||
end
|
||||
|
||||
def update(conn, %{"id" => id} = params) do
|
||||
user = Users.get_user!(id)
|
||||
attrs = Map.drop(params, ["id"])
|
||||
|
||||
case Users.update_user(user, attrs) do
|
||||
{:ok, updated} ->
|
||||
json(conn, render_user(updated))
|
||||
|
||||
{:error, changeset} ->
|
||||
conn
|
||||
|> put_status(:unprocessable_entity)
|
||||
|> json(%{errors: format_errors(changeset)})
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, %{"id" => id}) do
|
||||
user = Users.get_user!(id)
|
||||
{:ok, _} = Users.delete_user(user)
|
||||
send_resp(conn, :no_content, "")
|
||||
end
|
||||
|
||||
def promote(conn, %{"id" => id}) do
|
||||
user = Users.get_user!(id)
|
||||
|
||||
case Users.promote_to_admin(user) do
|
||||
{:ok, updated} ->
|
||||
json(conn, render_user(updated))
|
||||
|
||||
{:error, changeset} ->
|
||||
conn
|
||||
|> put_status(:unprocessable_entity)
|
||||
|> json(%{errors: format_errors(changeset)})
|
||||
end
|
||||
end
|
||||
|
||||
defp render_user(user) do
|
||||
%{id: user.id, username: user.username, is_admin: user.is_admin}
|
||||
end
|
||||
|
||||
defp format_errors(changeset) do
|
||||
Ecto.Changeset.traverse_errors(changeset, fn {msg, opts} ->
|
||||
Enum.reduce(opts, msg, fn {key, val}, acc ->
|
||||
String.replace(acc, "%{#{key}}", to_string(val))
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user