diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index 705217e..f686c73 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -132,26 +132,16 @@ for attrs <- [ ) end -# Get admin email from environment variable or use default +# Admin email: default for dev/test so seed_admin has a target admin_email = System.get_env("ADMIN_EMAIL") || "admin@localhost" +System.put_env("ADMIN_EMAIL", admin_email) -# 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 +# In dev/test, set fallback password so seed_admin creates the admin user when none is set +if Mix.env() in [:dev, :test] and is_nil(System.get_env("ADMIN_PASSWORD")) and + is_nil(System.get_env("ADMIN_PASSWORD_FILE")) do + System.put_env("ADMIN_PASSWORD", "testpassword") end -admin_password = get_admin_password.() - # 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 role_configs = [ @@ -231,55 +221,9 @@ if is_nil(admin_role) do raise "Failed to create or find admin role. Cannot proceed with member seeding." end -# Assign admin role to user with ADMIN_EMAIL (if user exists) -# 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 - |> Ash.Query.filter(email == ^admin_email) - |> Ash.read_one(domain: Mv.Accounts, authorize?: false) do - {:ok, existing_admin_user} when not is_nil(existing_admin_user) -> - # User already exists (e.g., via OIDC) - set password if we have one, then assign admin role - user_after_password = - 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.manage_relationship(:role, admin_role, type: :append_and_remove) - |> Ash.update!(authorize?: false) - - {:ok, nil} -> - # 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 - user = - Accounts.create_user!(%{email: admin_email}, - upsert?: true, - upsert_identity: :unique_email, - authorize?: false - ) - - 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) - - {:error, error} -> - raise "Failed to check for existing admin user: #{inspect(error)}" -end +# Create/update admin user via Release.seed_admin (uses ADMIN_EMAIL, ADMIN_PASSWORD / ADMIN_PASSWORD_FILE). +# Reduces duplication and exercises the same path as production entrypoint. +Mv.Release.seed_admin() # Load admin user with role for use as actor in member operations # This ensures all member operations have proper authorization @@ -781,8 +725,11 @@ IO.puts(" - Global settings: club_name = #{default_club_name}") 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)") +password_configured = + System.get_env("ADMIN_PASSWORD") != nil or System.get_env("ADMIN_PASSWORD_FILE") != nil + IO.puts( - " - Admin user: #{admin_email} (password: #{if admin_password, do: "set", else: "not set"})" + " - Admin user: #{admin_email} (password: #{if password_configured, do: "set", else: "not set"})" ) IO.puts(" - Sample members: Hans, Greta, Friedrich")