User form: persist role, member linking, Forbidden handling
- User resource: update_user accepts role_id, manage_relationship :member - user_live/form: touch role_id, params_with_member_if_unchanged to avoid unlink - Handle Forbidden in form, extract error message for display - user_policies_test and form_test coverage
This commit is contained in:
parent
5ed41555e9
commit
8ec4a07103
4 changed files with 196 additions and 8 deletions
|
|
@ -343,6 +343,64 @@ defmodule Mv.Accounts.UserPoliciesTest do
|
|||
# Verify user is deleted
|
||||
assert {:error, _} = Ash.get(Accounts.User, other_user.id, domain: Mv.Accounts)
|
||||
end
|
||||
|
||||
test "admin can assign role to another user via update_user", %{
|
||||
actor: actor,
|
||||
other_user: other_user
|
||||
} do
|
||||
admin = create_user_with_permission_set("admin", actor)
|
||||
normal_user_role = create_role_with_permission_set("normal_user", actor)
|
||||
|
||||
{:ok, updated} =
|
||||
other_user
|
||||
|> Ash.Changeset.for_update(:update_user, %{role_id: normal_user_role.id})
|
||||
|> Ash.update(actor: admin)
|
||||
|
||||
assert updated.role_id == normal_user_role.id
|
||||
end
|
||||
end
|
||||
|
||||
describe "admin role assignment and last-admin validation" do
|
||||
test "two admins: one can change own role to normal_user (other remains admin)", %{
|
||||
actor: actor
|
||||
} do
|
||||
_admin_role = create_role_with_permission_set("admin", actor)
|
||||
normal_user_role = create_role_with_permission_set("normal_user", actor)
|
||||
|
||||
admin_a = create_user_with_permission_set("admin", actor)
|
||||
_admin_b = create_user_with_permission_set("admin", actor)
|
||||
|
||||
{:ok, updated} =
|
||||
admin_a
|
||||
|> Ash.Changeset.for_update(:update_user, %{role_id: normal_user_role.id})
|
||||
|> Ash.update(actor: admin_a)
|
||||
|
||||
assert updated.role_id == normal_user_role.id
|
||||
end
|
||||
|
||||
test "single admin: changing own role to normal_user returns validation error", %{
|
||||
actor: actor
|
||||
} do
|
||||
normal_user_role = create_role_with_permission_set("normal_user", actor)
|
||||
single_admin = create_user_with_permission_set("admin", actor)
|
||||
|
||||
assert {:error, %Ash.Error.Invalid{errors: errors}} =
|
||||
single_admin
|
||||
|> Ash.Changeset.for_update(:update_user, %{role_id: normal_user_role.id})
|
||||
|> Ash.update(actor: single_admin)
|
||||
|
||||
error_messages =
|
||||
Enum.flat_map(errors, fn
|
||||
%Ash.Error.Changes.InvalidAttribute{message: msg} when is_binary(msg) -> [msg]
|
||||
%{message: msg} when is_binary(msg) -> [msg]
|
||||
_ -> []
|
||||
end)
|
||||
|
||||
assert Enum.any?(error_messages, fn msg ->
|
||||
msg =~ "least one user must keep the Admin role" or msg =~ "Admin role"
|
||||
end),
|
||||
"Expected last-admin validation message, got: #{inspect(error_messages)}"
|
||||
end
|
||||
end
|
||||
|
||||
describe "AshAuthentication bypass" do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue