Seeds: use ADMIN_PASSWORD/ADMIN_PASSWORD_FILE; fallback only in dev/test
No fallback in production; prod uses Release.seed_admin in entrypoint.
This commit is contained in:
parent
7a56a0920b
commit
09a4b7c937
1 changed files with 55 additions and 18 deletions
|
|
@ -135,6 +135,23 @@ end
|
||||||
# Get admin email from environment variable or use default
|
# Get admin email from environment variable or use default
|
||||||
admin_email = System.get_env("ADMIN_EMAIL") || "admin@localhost"
|
admin_email = System.get_env("ADMIN_EMAIL") || "admin@localhost"
|
||||||
|
|
||||||
|
# Admin password: use ADMIN_PASSWORD or ADMIN_PASSWORD_FILE if set; otherwise fallback
|
||||||
|
# only in dev/test (no fallback in production - prod uses Release.seed_admin in entrypoint)
|
||||||
|
get_admin_password = fn ->
|
||||||
|
from_file =
|
||||||
|
System.get_env("ADMIN_PASSWORD_FILE") |> then(fn path -> path && File.read(path) end)
|
||||||
|
|
||||||
|
from_env = System.get_env("ADMIN_PASSWORD")
|
||||||
|
|
||||||
|
case {from_file, from_env} do
|
||||||
|
{{:ok, content}, _} -> String.trim_trailing(content)
|
||||||
|
{_, p} when is_binary(p) and p != "" -> p
|
||||||
|
_ -> if Mix.env() in [:dev, :test], do: "testpassword", else: nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
admin_password = get_admin_password.()
|
||||||
|
|
||||||
# Create all authorization roles (idempotent - creates only if they don't exist)
|
# Create all authorization roles (idempotent - creates only if they don't exist)
|
||||||
# Roles are created using create_role_with_system_flag to allow setting is_system_role
|
# Roles are created using create_role_with_system_flag to allow setting is_system_role
|
||||||
role_configs = [
|
role_configs = [
|
||||||
|
|
@ -215,34 +232,50 @@ if is_nil(admin_role) do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Assign admin role to user with ADMIN_EMAIL (if user exists)
|
# Assign admin role to user with ADMIN_EMAIL (if user exists)
|
||||||
# This handles both existing users (e.g., from OIDC) and newly created users
|
# This handles both existing users (e.g., from OIDC) and newly created users.
|
||||||
|
# Password: use admin_password (from ENV or dev/test fallback); if nil, do not set password (prod-safe).
|
||||||
case Accounts.User
|
case Accounts.User
|
||||||
|> Ash.Query.filter(email == ^admin_email)
|
|> Ash.Query.filter(email == ^admin_email)
|
||||||
|> Ash.read_one(domain: Mv.Accounts, authorize?: false) do
|
|> Ash.read_one(domain: Mv.Accounts, authorize?: false) do
|
||||||
{:ok, existing_admin_user} when not is_nil(existing_admin_user) ->
|
{:ok, existing_admin_user} when not is_nil(existing_admin_user) ->
|
||||||
# User already exists (e.g., via OIDC) - assign admin role
|
# User already exists (e.g., via OIDC) - set password if we have one, then assign admin role
|
||||||
# Use authorize?: false for bootstrap - this is initial setup
|
user_after_password =
|
||||||
existing_admin_user
|
if is_binary(admin_password) and admin_password != "" do
|
||||||
|
existing_admin_user
|
||||||
|
|> Ash.Changeset.for_update(:admin_set_password, %{password: admin_password})
|
||||||
|
|> Ash.update!(authorize?: false)
|
||||||
|
else
|
||||||
|
existing_admin_user
|
||||||
|
end
|
||||||
|
|
||||||
|
user_after_password
|
||||||
|> Ash.Changeset.for_update(:update, %{})
|
|> Ash.Changeset.for_update(:update, %{})
|
||||||
|> Ash.Changeset.manage_relationship(:role, admin_role, type: :append_and_remove)
|
|> Ash.Changeset.manage_relationship(:role, admin_role, type: :append_and_remove)
|
||||||
|> Ash.update!(authorize?: false)
|
|> Ash.update!(authorize?: false)
|
||||||
|
|
||||||
{:ok, nil} ->
|
{:ok, nil} ->
|
||||||
# User doesn't exist - create admin user and set password (so Password column shows "Enabled")
|
# User doesn't exist - create admin user; set password only if we have one (no fallback in prod)
|
||||||
# Use authorize?: false for bootstrap - no admin user exists yet to use as actor
|
# Use authorize?: false for bootstrap - no admin user exists yet to use as actor
|
||||||
Accounts.create_user!(%{email: admin_email},
|
user =
|
||||||
upsert?: true,
|
Accounts.create_user!(%{email: admin_email},
|
||||||
upsert_identity: :unique_email,
|
upsert?: true,
|
||||||
authorize?: false
|
upsert_identity: :unique_email,
|
||||||
)
|
authorize?: false
|
||||||
|> Ash.Changeset.for_update(:admin_set_password, %{password: "testpassword"})
|
)
|
||||||
|
|
||||||
|
user =
|
||||||
|
if is_binary(admin_password) and admin_password != "" do
|
||||||
|
user
|
||||||
|
|> Ash.Changeset.for_update(:admin_set_password, %{password: admin_password})
|
||||||
|
|> Ash.update!(authorize?: false)
|
||||||
|
else
|
||||||
|
user
|
||||||
|
end
|
||||||
|
|
||||||
|
user
|
||||||
|
|> Ash.Changeset.for_update(:update, %{})
|
||||||
|
|> Ash.Changeset.manage_relationship(:role, admin_role, type: :append_and_remove)
|
||||||
|> Ash.update!(authorize?: false)
|
|> Ash.update!(authorize?: false)
|
||||||
|> then(fn user ->
|
|
||||||
user
|
|
||||||
|> Ash.Changeset.for_update(:update, %{})
|
|
||||||
|> Ash.Changeset.manage_relationship(:role, admin_role, type: :append_and_remove)
|
|
||||||
|> Ash.update!(authorize?: false)
|
|
||||||
end)
|
|
||||||
|
|
||||||
{:error, error} ->
|
{:error, error} ->
|
||||||
raise "Failed to check for existing admin user: #{inspect(error)}"
|
raise "Failed to check for existing admin user: #{inspect(error)}"
|
||||||
|
|
@ -747,7 +780,11 @@ IO.puts("📝 Created sample data:")
|
||||||
IO.puts(" - Global settings: club_name = #{default_club_name}")
|
IO.puts(" - Global settings: club_name = #{default_club_name}")
|
||||||
IO.puts(" - Membership fee types: 4 types (Yearly, Half-yearly, Quarterly, Monthly)")
|
IO.puts(" - Membership fee types: 4 types (Yearly, Half-yearly, Quarterly, Monthly)")
|
||||||
IO.puts(" - Custom fields: 12 fields (String, Date, Boolean, Email, + 8 realistic fields)")
|
IO.puts(" - Custom fields: 12 fields (String, Date, Boolean, Email, + 8 realistic fields)")
|
||||||
IO.puts(" - Admin user: #{admin_email} (password: testpassword)")
|
|
||||||
|
IO.puts(
|
||||||
|
" - Admin user: #{admin_email} (password: #{if admin_password, do: "set", else: "not set"})"
|
||||||
|
)
|
||||||
|
|
||||||
IO.puts(" - Sample members: Hans, Greta, Friedrich")
|
IO.puts(" - Sample members: Hans, Greta, Friedrich")
|
||||||
|
|
||||||
IO.puts(
|
IO.puts(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue