- PermissionSets: Role read :all for own_data, read_only, normal_user; admin keeps full CRUD - Role resource: authorizers and policies with HasPermission - Tests: role_policies_test.exs (read all, create/update/destroy admin only) - Fix existing tests to pass actor or authorize?: false for Role operations
226 lines
7.6 KiB
Elixir
226 lines
7.6 KiB
Elixir
defmodule Mv.Authorization.RolePoliciesTest do
|
|
@moduledoc """
|
|
Tests for Role resource authorization policies.
|
|
|
|
Rule: All permission sets (own_data, read_only, normal_user, admin) can **read** roles.
|
|
Only **admin** can create, update, or destroy roles.
|
|
"""
|
|
use Mv.DataCase, async: false
|
|
|
|
alias Mv.Authorization
|
|
alias Mv.Authorization.Role
|
|
|
|
describe "read access - all permission sets can read roles" do
|
|
setup do
|
|
# Create a role to read (via system_actor; once policies exist, system_actor is admin)
|
|
role = Mv.Fixtures.role_fixture("read_only")
|
|
%{role: role}
|
|
end
|
|
|
|
@tag :permission_set_own_data
|
|
test "own_data can list roles", %{role: _role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("own_data")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
{:ok, roles} = Authorization.list_roles(actor: user)
|
|
|
|
assert is_list(roles)
|
|
assert roles != []
|
|
end
|
|
|
|
@tag :permission_set_own_data
|
|
test "own_data can get role by id", %{role: role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("own_data")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
{:ok, loaded} = Ash.get(Role, role.id, actor: user, domain: Mv.Authorization)
|
|
|
|
assert loaded.id == role.id
|
|
end
|
|
|
|
@tag :permission_set_read_only
|
|
test "read_only can list roles", %{role: _role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("read_only")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
{:ok, roles} = Authorization.list_roles(actor: user)
|
|
|
|
assert is_list(roles)
|
|
assert roles != []
|
|
end
|
|
|
|
@tag :permission_set_read_only
|
|
test "read_only can get role by id", %{role: role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("read_only")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
{:ok, loaded} = Ash.get(Role, role.id, actor: user, domain: Mv.Authorization)
|
|
|
|
assert loaded.id == role.id
|
|
end
|
|
|
|
@tag :permission_set_normal_user
|
|
test "normal_user can list roles", %{role: _role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("normal_user")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
{:ok, roles} = Authorization.list_roles(actor: user)
|
|
|
|
assert is_list(roles)
|
|
assert roles != []
|
|
end
|
|
|
|
@tag :permission_set_normal_user
|
|
test "normal_user can get role by id", %{role: role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("normal_user")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
{:ok, loaded} = Ash.get(Role, role.id, actor: user, domain: Mv.Authorization)
|
|
|
|
assert loaded.id == role.id
|
|
end
|
|
|
|
@tag :permission_set_admin
|
|
test "admin can list roles", %{role: _role} do
|
|
admin = Mv.Fixtures.user_with_role_fixture("admin")
|
|
admin = Mv.Authorization.Actor.ensure_loaded(admin)
|
|
|
|
{:ok, roles} = Authorization.list_roles(actor: admin)
|
|
|
|
assert is_list(roles)
|
|
assert roles != []
|
|
end
|
|
|
|
@tag :permission_set_admin
|
|
test "admin can get role by id", %{role: role} do
|
|
admin = Mv.Fixtures.user_with_role_fixture("admin")
|
|
admin = Mv.Authorization.Actor.ensure_loaded(admin)
|
|
|
|
{:ok, loaded} = Ash.get(Role, role.id, actor: admin, domain: Mv.Authorization)
|
|
|
|
assert loaded.id == role.id
|
|
end
|
|
end
|
|
|
|
describe "create/update/destroy - only admin allowed" do
|
|
setup do
|
|
# Non-system role for destroy test (role_fixture creates non-system roles)
|
|
role = Mv.Fixtures.role_fixture("normal_user")
|
|
%{role: role}
|
|
end
|
|
|
|
test "admin can create_role", %{role: _role} do
|
|
admin = Mv.Fixtures.user_with_role_fixture("admin")
|
|
admin = Mv.Authorization.Actor.ensure_loaded(admin)
|
|
|
|
attrs = %{
|
|
name: "New Role #{System.unique_integer([:positive])}",
|
|
description: "Test",
|
|
permission_set_name: "read_only"
|
|
}
|
|
|
|
assert {:ok, _created} = Authorization.create_role(attrs, actor: admin)
|
|
end
|
|
|
|
test "admin can update_role", %{role: role} do
|
|
admin = Mv.Fixtures.user_with_role_fixture("admin")
|
|
admin = Mv.Authorization.Actor.ensure_loaded(admin)
|
|
|
|
assert {:ok, updated} =
|
|
Authorization.update_role(role, %{description: "Updated by admin"}, actor: admin)
|
|
|
|
assert updated.description == "Updated by admin"
|
|
end
|
|
|
|
test "admin can destroy non-system role", %{role: role} do
|
|
admin = Mv.Fixtures.user_with_role_fixture("admin")
|
|
admin = Mv.Authorization.Actor.ensure_loaded(admin)
|
|
|
|
assert :ok = Authorization.destroy_role(role, actor: admin)
|
|
end
|
|
|
|
test "own_data cannot create_role (forbidden)", %{role: _role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("own_data")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
attrs = %{
|
|
name: "New Role #{System.unique_integer([:positive])}",
|
|
description: "Test",
|
|
permission_set_name: "read_only"
|
|
}
|
|
|
|
assert {:error, %Ash.Error.Forbidden{}} = Authorization.create_role(attrs, actor: user)
|
|
end
|
|
|
|
test "own_data cannot update_role (forbidden)", %{role: role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("own_data")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
assert {:error, %Ash.Error.Forbidden{}} =
|
|
Authorization.update_role(role, %{description: "Updated"}, actor: user)
|
|
end
|
|
|
|
test "own_data cannot destroy_role (forbidden)", %{role: role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("own_data")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
assert {:error, %Ash.Error.Forbidden{}} = Authorization.destroy_role(role, actor: user)
|
|
end
|
|
|
|
test "read_only cannot create_role (forbidden)", %{role: _role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("read_only")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
attrs = %{
|
|
name: "New Role #{System.unique_integer([:positive])}",
|
|
description: "Test",
|
|
permission_set_name: "read_only"
|
|
}
|
|
|
|
assert {:error, %Ash.Error.Forbidden{}} = Authorization.create_role(attrs, actor: user)
|
|
end
|
|
|
|
test "read_only cannot update_role (forbidden)", %{role: role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("read_only")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
assert {:error, %Ash.Error.Forbidden{}} =
|
|
Authorization.update_role(role, %{description: "Updated"}, actor: user)
|
|
end
|
|
|
|
test "read_only cannot destroy_role (forbidden)", %{role: role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("read_only")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
assert {:error, %Ash.Error.Forbidden{}} = Authorization.destroy_role(role, actor: user)
|
|
end
|
|
|
|
test "normal_user cannot create_role (forbidden)", %{role: _role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("normal_user")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
attrs = %{
|
|
name: "New Role #{System.unique_integer([:positive])}",
|
|
description: "Test",
|
|
permission_set_name: "normal_user"
|
|
}
|
|
|
|
assert {:error, %Ash.Error.Forbidden{}} = Authorization.create_role(attrs, actor: user)
|
|
end
|
|
|
|
test "normal_user cannot update_role (forbidden)", %{role: role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("normal_user")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
assert {:error, %Ash.Error.Forbidden{}} =
|
|
Authorization.update_role(role, %{description: "Updated"}, actor: user)
|
|
end
|
|
|
|
test "normal_user cannot destroy_role (forbidden)", %{role: role} do
|
|
user = Mv.Fixtures.user_with_role_fixture("normal_user")
|
|
user = Mv.Authorization.Actor.ensure_loaded(user)
|
|
|
|
assert {:error, %Ash.Error.Forbidden{}} = Authorization.destroy_role(role, actor: user)
|
|
end
|
|
end
|
|
end
|