Create/promote the ADMIN_EMAIL account on every start, before the seeds, so the public admin@claper.co/claper default is never created. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
60 lines
2.1 KiB
Elixir
60 lines
2.1 KiB
Elixir
# Ensures that the account ADMIN_EMAIL exists and is an admin. Runs on every
|
|
# start, between the migrations and the seeds:
|
|
# - missing account: created with the admin_pass secret as password
|
|
# - account without admin role: promoted to admin
|
|
# - existing admin: left untouched, the password is never overwritten
|
|
#
|
|
# Because the account exists before the seeds run, the seeds never create the
|
|
# default admin@claper.co/claper account.
|
|
# Without ADMIN_EMAIL nothing is done and the upstream seeds apply.
|
|
|
|
alias Claper.Accounts
|
|
alias Claper.Accounts.Role
|
|
alias Claper.Repo
|
|
|
|
case System.get_env("ADMIN_EMAIL", "") |> String.trim() do
|
|
"" ->
|
|
IO.puts("ADMIN_EMAIL not set, skipping admin bootstrap")
|
|
|
|
email ->
|
|
Application.load(:claper)
|
|
|
|
{:ok, _, _} =
|
|
Ecto.Migrator.with_repo(Repo, fn _repo ->
|
|
# The roles are normally created by the seeds, which run after this.
|
|
admin_role =
|
|
Repo.get_by(Role, name: "admin") ||
|
|
Repo.insert!(%Role{name: "admin", permissions: %{"all" => true}})
|
|
|
|
Repo.get_by(Role, name: "user") || Repo.insert!(%Role{name: "user", permissions: %{}})
|
|
|
|
case Accounts.get_user_by_email(email) do
|
|
nil ->
|
|
pw = File.read!("/run/secrets/admin_pass") |> String.trim()
|
|
|
|
case Accounts.register_user(%{
|
|
email: email,
|
|
first_name: "Claper",
|
|
last_name: "Admin",
|
|
password: pw,
|
|
role_id: admin_role.id,
|
|
confirmed_at: NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
|
|
}) do
|
|
{:ok, _} ->
|
|
IO.puts("Created admin #{email} with the admin_pass secret as password")
|
|
|
|
{:error, changeset} ->
|
|
raise "Could not create admin #{email}: #{inspect(changeset.errors)}"
|
|
end
|
|
|
|
user ->
|
|
if user.role_id == admin_role.id do
|
|
IO.puts("Admin #{email} exists, nothing to do")
|
|
else
|
|
{:ok, _} = Accounts.assign_role(user, admin_role)
|
|
IO.puts("Promoted #{email} to admin")
|
|
end
|
|
end
|
|
end)
|
|
end
|