feat: 重构 RBAC1 角色权限模型
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -7,6 +9,10 @@ using Microsoft.Extensions.Options;
|
||||
using TakeoutSaaS.Infrastructure.Identity.Options;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
using DomainIdentityUser = TakeoutSaaS.Domain.Identity.Entities.IdentityUser;
|
||||
using DomainPermission = TakeoutSaaS.Domain.Identity.Entities.Permission;
|
||||
using DomainRole = TakeoutSaaS.Domain.Identity.Entities.Role;
|
||||
using DomainRolePermission = TakeoutSaaS.Domain.Identity.Entities.RolePermission;
|
||||
using DomainUserRole = TakeoutSaaS.Domain.Identity.Entities.UserRole;
|
||||
|
||||
namespace TakeoutSaaS.Infrastructure.Identity.Persistence;
|
||||
|
||||
@@ -47,9 +53,7 @@ public sealed class IdentityDataSeeder(IServiceProvider serviceProvider, ILogger
|
||||
DisplayName = userOptions.DisplayName,
|
||||
TenantId = userOptions.TenantId,
|
||||
MerchantId = userOptions.MerchantId,
|
||||
Avatar = null,
|
||||
Roles = roles,
|
||||
Permissions = permissions,
|
||||
Avatar = null
|
||||
};
|
||||
user.PasswordHash = passwordHasher.HashPassword(user, userOptions.Password);
|
||||
context.IdentityUsers.Add(user);
|
||||
@@ -60,11 +64,94 @@ public sealed class IdentityDataSeeder(IServiceProvider serviceProvider, ILogger
|
||||
user.DisplayName = userOptions.DisplayName;
|
||||
user.TenantId = userOptions.TenantId;
|
||||
user.MerchantId = userOptions.MerchantId;
|
||||
user.Roles = roles;
|
||||
user.Permissions = permissions;
|
||||
user.PasswordHash = passwordHasher.HashPassword(user, userOptions.Password);
|
||||
logger.LogInformation("已更新后台账号 {Account}", user.Account);
|
||||
}
|
||||
|
||||
// 确保角色存在
|
||||
var existingRoles = await context.Roles
|
||||
.Where(r => r.TenantId == userOptions.TenantId && roles.Contains(r.Code))
|
||||
.ToListAsync(cancellationToken);
|
||||
var existingRoleCodes = existingRoles.Select(r => r.Code).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var code in roles)
|
||||
{
|
||||
if (existingRoleCodes.Contains(code))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
context.Roles.Add(new DomainRole
|
||||
{
|
||||
TenantId = userOptions.TenantId,
|
||||
Code = code,
|
||||
Name = code,
|
||||
Description = $"Seed role {code}"
|
||||
});
|
||||
}
|
||||
|
||||
// 确保权限存在
|
||||
var existingPermissions = await context.Permissions
|
||||
.Where(p => p.TenantId == userOptions.TenantId && permissions.Contains(p.Code))
|
||||
.ToListAsync(cancellationToken);
|
||||
var existingPermissionCodes = existingPermissions.Select(p => p.Code).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var code in permissions)
|
||||
{
|
||||
if (existingPermissionCodes.Contains(code))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
context.Permissions.Add(new DomainPermission
|
||||
{
|
||||
TenantId = userOptions.TenantId,
|
||||
Code = code,
|
||||
Name = code,
|
||||
Description = $"Seed permission {code}"
|
||||
});
|
||||
}
|
||||
|
||||
await context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// 重新加载角色/权限以获取 Id
|
||||
var roleEntities = await context.Roles
|
||||
.Where(r => r.TenantId == userOptions.TenantId && roles.Contains(r.Code))
|
||||
.ToListAsync(cancellationToken);
|
||||
var permissionEntities = await context.Permissions
|
||||
.Where(p => p.TenantId == userOptions.TenantId && permissions.Contains(p.Code))
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
// 重置用户角色
|
||||
var existingUserRoles = await context.UserRoles
|
||||
.Where(ur => ur.TenantId == userOptions.TenantId && ur.UserId == user.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
context.UserRoles.RemoveRange(existingUserRoles);
|
||||
|
||||
var roleIds = roleEntities.Select(r => r.Id).Distinct().ToArray();
|
||||
var userRoles = roleIds.Select(roleId => new DomainUserRole
|
||||
{
|
||||
TenantId = userOptions.TenantId,
|
||||
UserId = user.Id,
|
||||
RoleId = roleId
|
||||
});
|
||||
await context.UserRoles.AddRangeAsync(userRoles, cancellationToken);
|
||||
|
||||
// 为种子角色绑定种子权限
|
||||
if (permissions.Length > 0 && roleIds.Length > 0)
|
||||
{
|
||||
var permissionIds = permissionEntities.Select(p => p.Id).Distinct().ToArray();
|
||||
var existingRolePermissions = await context.RolePermissions
|
||||
.Where(rp => rp.TenantId == userOptions.TenantId && roleIds.Contains(rp.RoleId))
|
||||
.ToListAsync(cancellationToken);
|
||||
context.RolePermissions.RemoveRange(existingRolePermissions);
|
||||
|
||||
var newRolePermissions = roleIds.SelectMany(roleId => permissionIds.Select(permissionId => new DomainRolePermission
|
||||
{
|
||||
TenantId = userOptions.TenantId,
|
||||
RoleId = roleId,
|
||||
PermissionId = permissionId
|
||||
}));
|
||||
await context.RolePermissions.AddRangeAsync(newRolePermissions, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
await context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
Reference in New Issue
Block a user