58 lines
1.8 KiB
Elixir
58 lines
1.8 KiB
Elixir
defmodule Localiser.Web.Controllers.SetupController do
|
|
use Phoenix.Controller, formats: [:json]
|
|
use OpenApiSpex.ControllerSpecs
|
|
|
|
alias Localiser.Domain.Users
|
|
alias Localiser.Web.Token
|
|
alias Localiser.Web.Schemas
|
|
|
|
tags ["Auth"]
|
|
|
|
operation :create,
|
|
summary: "Create first admin user",
|
|
description: "Only succeeds when no users exist. Blocked with 403 afterwards.",
|
|
security: [],
|
|
request_body: {"Setup params", "application/json", Schemas.SetupParams, required: true},
|
|
responses: [
|
|
created: {"Admin user created", "application/json", Schemas.TokenResponse},
|
|
bad_request: {"Missing username/password", "application/json", Schemas.Error},
|
|
forbidden: {"System already initialised", "application/json", Schemas.Error},
|
|
unprocessable_entity: {"Validation errors", "application/json", Schemas.ValidationErrors}
|
|
]
|
|
|
|
def create(conn, %{"username" => username, "password" => password}) do
|
|
attrs = %{"username" => username, "password" => password, "is_admin" => true}
|
|
|
|
case Users.create_user(attrs) do
|
|
{:ok, user} ->
|
|
token = Token.generate(%{"sub" => user.id})
|
|
conn
|
|
|> put_status(:created)
|
|
|> json(%{token: token, user: render_user(user)})
|
|
|
|
{:error, changeset} ->
|
|
conn
|
|
|> put_status(:unprocessable_entity)
|
|
|> json(%{errors: format_errors(changeset)})
|
|
end
|
|
end
|
|
|
|
def create(conn, _params) do
|
|
conn
|
|
|> put_status(:bad_request)
|
|
|> json(%{error: "username and password are required"})
|
|
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
|