Add Role resource policies (defense-in-depth)

- 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
This commit is contained in:
Moritz 2026-02-04 12:37:48 +01:00
parent 10f37a1246
commit 4d3a64c177
Signed by: moritz
GPG key ID: 1020A035E5DD0824
8 changed files with 304 additions and 51 deletions

View file

@ -18,18 +18,21 @@ defmodule Mv.Helpers.SystemActorTest do
Ecto.Adapters.SQL.query!(Mv.Repo, "DELETE FROM users WHERE id = $1", [id])
end
# Helper function to ensure admin role exists
# Helper function to ensure admin role exists (bootstrap: no actor yet, use authorize?: false)
defp ensure_admin_role do
case Authorization.list_roles() do
case Authorization.list_roles(authorize?: false) do
{:ok, roles} ->
case Enum.find(roles, &(&1.permission_set_name == "admin")) do
nil ->
{:ok, role} =
Authorization.create_role(%{
name: "Admin",
description: "Administrator with full access",
permission_set_name: "admin"
})
Authorization.create_role(
%{
name: "Admin",
description: "Administrator with full access",
permission_set_name: "admin"
},
authorize?: false
)
role
@ -39,11 +42,14 @@ defmodule Mv.Helpers.SystemActorTest do
_ ->
{:ok, role} =
Authorization.create_role(%{
name: "Admin",
description: "Administrator with full access",
permission_set_name: "admin"
})
Authorization.create_role(
%{
name: "Admin",
description: "Administrator with full access",
permission_set_name: "admin"
},
authorize?: false
)
role
end
@ -364,12 +370,17 @@ defmodule Mv.Helpers.SystemActorTest do
test "raises error if system user has wrong role", %{system_user: system_user} do
# Create a non-admin role (using read_only as it's a valid permission set)
system_actor = SystemActor.get_system_actor()
{:ok, read_only_role} =
Authorization.create_role(%{
name: "Read Only Role",
description: "Read-only access",
permission_set_name: "read_only"
})
Authorization.create_role(
%{
name: "Read Only Role",
description: "Read-only access",
permission_set_name: "read_only"
},
actor: system_actor
)
system_actor = SystemActor.get_system_actor()