Files
Hoard/API/Migrations/20260420174609_ReplaceIsAdminWithRoles.cs
T
Jonas b2984fcf1a Replace IsAdmin with role-based admin
Switch user admin handling from an AppUser boolean to ASP.NET Identity roles. Removed AppUser.IsAdmin and related configuration/model entries; added migration ReplaceIsAdminWithRoles to copy Users.IsAdmin=true into a persistent admin role and drop the IsAdmin column. CurrentUserResponse now exposes roles (string[]), AuthController returns ordered roles from UserManager, and IdentitySeedService now ensures the admin role exists and assigns/creates an initial admin user in that role. Program.cs registers an Admin-only policy (PolicyNames/RoleNames), adjusts cookie auth events to return 401/403 for API requests, and wires up authorization. Frontend updated to use roles: authSession normalizes roles, adds hasRole and ROLE_ADMIN, router and layout support meta.requiredRoles, and new Forbidden and AdminUsers pages/route are added. codexInfo.md updated to reflect the migration to role-based auth.
2026-04-20 19:57:49 +02:00

81 lines
2.6 KiB
C#

using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace API.Migrations
{
/// <inheritdoc />
public partial class ReplaceIsAdminWithRoles : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(
"""
DO $$
DECLARE
admin_role_id uuid;
BEGIN
SELECT "Id" INTO admin_role_id
FROM "Roles"
WHERE "NormalizedName" = 'ADMIN'
LIMIT 1;
IF admin_role_id IS NULL THEN
admin_role_id := '2b34c0e2-9d53-4d79-bb85-bff03ce9e1ee';
INSERT INTO "Roles" ("Id", "Name", "NormalizedName", "ConcurrencyStamp")
VALUES (admin_role_id, 'admin', 'ADMIN', NULL)
ON CONFLICT ("Id") DO NOTHING;
SELECT "Id" INTO admin_role_id
FROM "Roles"
WHERE "NormalizedName" = 'ADMIN'
LIMIT 1;
END IF;
INSERT INTO "UserRoles" ("UserId", "RoleId")
SELECT u."Id", admin_role_id
FROM "Users" u
WHERE u."IsAdmin" = TRUE
AND admin_role_id IS NOT NULL
AND NOT EXISTS (
SELECT 1
FROM "UserRoles" ur
WHERE ur."UserId" = u."Id"
AND ur."RoleId" = admin_role_id
);
END $$;
""");
migrationBuilder.DropColumn(
name: "IsAdmin",
table: "Users");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsAdmin",
table: "Users",
type: "boolean",
nullable: false,
defaultValue: false);
migrationBuilder.Sql(
"""
UPDATE "Users" u
SET "IsAdmin" = TRUE
WHERE EXISTS (
SELECT 1
FROM "UserRoles" ur
INNER JOIN "Roles" r ON r."Id" = ur."RoleId"
WHERE ur."UserId" = u."Id"
AND r."NormalizedName" = 'ADMIN'
);
""");
}
}
}