Use current_actor/1 helper in all LiveViews
Replace inconsistent actor access patterns with current_actor/1 helper and ensure actor is passed to all Ash operations for proper authorization.
This commit is contained in:
parent
74fe60f768
commit
cd7e6b0843
9 changed files with 268 additions and 57 deletions
|
|
@ -33,6 +33,9 @@ defmodule MvWeb.UserLive.Form do
|
|||
"""
|
||||
use MvWeb, :live_view
|
||||
|
||||
on_mount {MvWeb.LiveHelpers, :ensure_user_role_loaded}
|
||||
import MvWeb.LiveHelpers, only: [current_actor: 1]
|
||||
|
||||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
|
|
@ -258,10 +261,12 @@ defmodule MvWeb.UserLive.Form do
|
|||
|
||||
@impl true
|
||||
def mount(params, _session, socket) do
|
||||
actor = current_actor(socket)
|
||||
|
||||
user =
|
||||
case params["id"] do
|
||||
nil -> nil
|
||||
id -> Ash.get!(Mv.Accounts.User, id, domain: Mv.Accounts, load: [:member])
|
||||
id -> Ash.get!(Mv.Accounts.User, id, domain: Mv.Accounts, load: [:member], actor: actor)
|
||||
end
|
||||
|
||||
action = if is_nil(user), do: gettext("New"), else: gettext("Edit")
|
||||
|
|
@ -307,7 +312,7 @@ defmodule MvWeb.UserLive.Form do
|
|||
socket =
|
||||
if Map.has_key?(user_params, "email") do
|
||||
user_email = user_params["email"]
|
||||
members = load_members_for_linking(user_email, socket.assigns.member_search_query)
|
||||
members = load_members_for_linking(user_email, socket.assigns.member_search_query, socket)
|
||||
|
||||
assign(socket, form: validated_form, available_members: members)
|
||||
else
|
||||
|
|
@ -318,19 +323,27 @@ defmodule MvWeb.UserLive.Form do
|
|||
end
|
||||
|
||||
def handle_event("save", %{"user" => user_params}, socket) do
|
||||
actor = current_actor(socket)
|
||||
# First save the user without member changes
|
||||
case AshPhoenix.Form.submit(socket.assigns.form, params: user_params) do
|
||||
case AshPhoenix.Form.submit(socket.assigns.form,
|
||||
params: user_params,
|
||||
action_opts: [actor: actor]
|
||||
) do
|
||||
{:ok, user} ->
|
||||
# Then handle member linking/unlinking as a separate step
|
||||
actor = current_actor(socket)
|
||||
|
||||
result =
|
||||
cond do
|
||||
# Selected member ID takes precedence (new link)
|
||||
socket.assigns.selected_member_id ->
|
||||
Mv.Accounts.update_user(user, %{member: %{id: socket.assigns.selected_member_id}})
|
||||
Mv.Accounts.update_user(user, %{member: %{id: socket.assigns.selected_member_id}},
|
||||
actor: actor
|
||||
)
|
||||
|
||||
# Unlink flag is set
|
||||
socket.assigns[:unlink_member] ->
|
||||
Mv.Accounts.update_user(user, %{member: nil})
|
||||
Mv.Accounts.update_user(user, %{member: nil}, actor: actor)
|
||||
|
||||
# No changes to member relationship
|
||||
true ->
|
||||
|
|
@ -497,18 +510,21 @@ defmodule MvWeb.UserLive.Form do
|
|||
|
||||
@spec assign_form(Phoenix.LiveView.Socket.t()) :: Phoenix.LiveView.Socket.t()
|
||||
defp assign_form(%{assigns: %{user: user, show_password_fields: show_password_fields}} = socket) do
|
||||
actor = current_actor(socket)
|
||||
|
||||
form =
|
||||
if user do
|
||||
# For existing users, use admin password action if password fields are shown
|
||||
action = if show_password_fields, do: :admin_set_password, else: :update_user
|
||||
AshPhoenix.Form.for_update(user, action, domain: Mv.Accounts, as: "user")
|
||||
AshPhoenix.Form.for_update(user, action, domain: Mv.Accounts, as: "user", actor: actor)
|
||||
else
|
||||
# For new users, use password registration if password fields are shown
|
||||
action = if show_password_fields, do: :register_with_password, else: :create_user
|
||||
|
||||
AshPhoenix.Form.for_create(Mv.Accounts.User, action,
|
||||
domain: Mv.Accounts,
|
||||
as: "user"
|
||||
as: "user",
|
||||
actor: actor
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -524,7 +540,7 @@ defmodule MvWeb.UserLive.Form do
|
|||
user = socket.assigns.user
|
||||
user_email = if user, do: user.email, else: nil
|
||||
|
||||
members = load_members_for_linking(user_email, "")
|
||||
members = load_members_for_linking(user_email, "", socket)
|
||||
|
||||
# Dropdown should ALWAYS be hidden initially
|
||||
# It will only show when user focuses the input field (show_member_dropdown event)
|
||||
|
|
@ -539,12 +555,15 @@ defmodule MvWeb.UserLive.Form do
|
|||
user = socket.assigns.user
|
||||
user_email = if user, do: user.email, else: nil
|
||||
|
||||
members = load_members_for_linking(user_email, query)
|
||||
members = load_members_for_linking(user_email, query, socket)
|
||||
assign(socket, available_members: members)
|
||||
end
|
||||
|
||||
@spec load_members_for_linking(String.t() | nil, String.t() | nil) :: [Mv.Membership.Member.t()]
|
||||
defp load_members_for_linking(user_email, search_query) do
|
||||
@spec load_members_for_linking(String.t() | nil, String.t() | nil, Phoenix.LiveView.Socket.t()) ::
|
||||
[
|
||||
Mv.Membership.Member.t()
|
||||
]
|
||||
defp load_members_for_linking(user_email, search_query, socket) do
|
||||
user_email_str = if user_email, do: to_string(user_email), else: nil
|
||||
search_query_str = if search_query && search_query != "", do: search_query, else: nil
|
||||
|
||||
|
|
@ -555,7 +574,9 @@ defmodule MvWeb.UserLive.Form do
|
|||
search_query: search_query_str
|
||||
})
|
||||
|
||||
case Ash.read(query, domain: Mv.Membership) do
|
||||
actor = current_actor(socket)
|
||||
|
||||
case Ash.read(query, domain: Mv.Membership, actor: actor) do
|
||||
{:ok, members} ->
|
||||
# Apply email match filter if user_email is provided
|
||||
if user_email_str do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue