OIDC sign-in: robust after_action for get? result, non-bang role sync
- sign_in_with_rauthy after_action normalizes result (nil/struct/list) to list before Enum.each. - OidcRoleSync.do_set_role uses Ash.update and swallows errors so auth is not blocked; skip update if role already correct.
This commit is contained in:
parent
c5f1fdce0a
commit
ad42a53919
2 changed files with 24 additions and 9 deletions
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,11 +132,17 @@ defmodule Mv.OidcRoleSync do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp do_set_role(user, role) do
|
defp do_set_role(user, role) do
|
||||||
|
if user.role_id == role.id do
|
||||||
|
:ok
|
||||||
|
else
|
||||||
user
|
user
|
||||||
|> Ash.Changeset.for_update(:set_role_from_oidc_sync, %{role_id: role.id})
|
|> Ash.Changeset.for_update(:set_role_from_oidc_sync, %{role_id: role.id})
|
||||||
|> Ash.Changeset.set_context(%{private: %{oidc_role_sync: true}})
|
|> Ash.Changeset.set_context(%{private: %{oidc_role_sync: true}})
|
||||||
|> Ash.update!(domain: Mv.Accounts, context: %{private: %{oidc_role_sync: true}})
|
|> Ash.update(domain: Mv.Accounts, context: %{private: %{oidc_role_sync: true}})
|
||||||
|
|> case do
|
||||||
:ok
|
{:ok, _} -> :ok
|
||||||
|
{:error, _} -> :ok
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue