Hide system actor from user list and block show/edit

Index: filter out SystemActor.system_user_email() in query. Show/Form:
redirect to /users with flash when viewing or editing system actor user.
Index format_error: handle Ash errors without :message field.
This commit is contained in:
Moritz 2026-01-27 14:29:13 +01:00 committed by moritz
parent b7f37c80bd
commit 8ad5201e1a
3 changed files with 47 additions and 9 deletions

View file

@ -266,10 +266,31 @@ defmodule MvWeb.UserLive.Form do
user =
case params["id"] do
nil -> nil
id -> Ash.get!(Mv.Accounts.User, id, domain: Mv.Accounts, load: [:member], actor: actor)
nil ->
nil
id ->
loaded =
Ash.get!(Mv.Accounts.User, id, domain: Mv.Accounts, load: [:member], actor: actor)
if to_string(loaded.email) == Mv.Helpers.SystemActor.system_user_email() do
{:redirect, loaded}
else
loaded
end
end
if match?({:redirect, _}, user) do
{:ok,
socket
|> put_flash(:error, gettext("This user cannot be edited."))
|> push_navigate(to: ~p"/users")}
else
mount_continue(user, params, socket)
end
end
defp mount_continue(user, params, socket) do
action = if is_nil(user), do: gettext("New"), else: gettext("Edit")
page_title = action <> " " <> gettext("User")

View file

@ -25,10 +25,17 @@ defmodule MvWeb.UserLive.Index do
import MvWeb.LiveHelpers, only: [current_actor: 1]
require Ash.Query
@impl true
def mount(_params, _session, socket) do
actor = current_actor(socket)
users = Ash.read!(Mv.Accounts.User, domain: Mv.Accounts, load: [:member], actor: actor)
users =
Mv.Accounts.User
|> Ash.Query.filter(email != ^Mv.Helpers.SystemActor.system_user_email())
|> Ash.read!(domain: Mv.Accounts, load: [:member], actor: actor)
sorted = Enum.sort_by(users, & &1.email)
{:ok,
@ -138,8 +145,11 @@ defmodule MvWeb.UserLive.Index do
defp sort_fun(:asc), do: &<=/2
defp sort_fun(:desc), do: &>=/2
defp format_error(%Ash.Error.Invalid{errors: errors}) do
Enum.map_join(errors, ", ", fn %{message: message} -> message end)
defp format_error(%Ash.Error.Invalid{errors: errors}) when is_list(errors) do
Enum.map_join(errors, ", ", fn
%{message: message} when is_binary(message) -> message
other -> inspect(other)
end)
end
defp format_error(error) do

View file

@ -75,9 +75,16 @@ defmodule MvWeb.UserLive.Show do
actor = current_actor(socket)
user = Ash.get!(Mv.Accounts.User, id, domain: Mv.Accounts, load: [:member], actor: actor)
if to_string(user.email) == Mv.Helpers.SystemActor.system_user_email() do
{:ok,
socket
|> put_flash(:error, gettext("This user cannot be viewed."))
|> push_navigate(to: ~p"/users")}
else
{:ok,
socket
|> assign(:page_title, gettext("Show User"))
|> assign(:user, user)}
end
end
end