Init an admin user in prod closes #381 #409

Merged
moritz merged 14 commits from feature/381_init_admin into main 2026-02-04 20:53:02 +01:00
2 changed files with 24 additions and 9 deletions
Showing only changes of commit ad42a53919 - Show all commits

View file

@ -271,15 +271,24 @@ defmodule Mv.Accounts.User do
filter expr(oidc_id == get_path(^arg(:user_info), [:sub])) filter expr(oidc_id == get_path(^arg(:user_info), [:sub]))
# Sync role from OIDC groups after sign-in (e.g. admin group → Admin role) # Sync role from OIDC groups after sign-in (e.g. admin group → Admin role)
prepare Ash.Resource.Preparation.Builtins.after_action(fn query, records, _context -> # get? true can return nil, a single %User{}, or a list; normalize to list for Enum.each
prepare Ash.Resource.Preparation.Builtins.after_action(fn query, result, _context ->
user_info = Ash.Query.get_argument(query, :user_info) || %{} user_info = Ash.Query.get_argument(query, :user_info) || %{}
oauth_tokens = Ash.Query.get_argument(query, :oauth_tokens) || %{} oauth_tokens = Ash.Query.get_argument(query, :oauth_tokens) || %{}
Enum.each(records, fn user -> users =
case result do
nil -> []
u when is_struct(u, User) -> [u]
list when is_list(list) -> list
_ -> []
end
Enum.each(users, fn user ->
Mv.OidcRoleSync.apply_admin_role_from_user_info(user, user_info, oauth_tokens) Mv.OidcRoleSync.apply_admin_role_from_user_info(user, user_info, oauth_tokens)
end) end)
{:ok, records} {:ok, result}
end) end)
end end

View file

@ -132,11 +132,17 @@ defmodule Mv.OidcRoleSync do
end end
defp do_set_role(user, role) do defp do_set_role(user, role) do
user if user.role_id == role.id do
|> Ash.Changeset.for_update(:set_role_from_oidc_sync, %{role_id: role.id}) :ok
|> Ash.Changeset.set_context(%{private: %{oidc_role_sync: true}}) else
|> Ash.update!(domain: Mv.Accounts, context: %{private: %{oidc_role_sync: true}}) user
|> Ash.Changeset.for_update(:set_role_from_oidc_sync, %{role_id: role.id})
:ok |> Ash.Changeset.set_context(%{private: %{oidc_role_sync: true}})
|> Ash.update(domain: Mv.Accounts, context: %{private: %{oidc_role_sync: true}})
|> case do
{:ok, _} -> :ok
{:error, _} -> :ok
end
end
end end
end end