- 在JWT中添加permver权限版本号claim,用于实时权限变更检测 - 实现PermissionVersionMiddleware中间件,在认证后授权前校验权限版本 - 修改AssignPermissionsCommandHandler,角色权限变更时自增相关用户权限版本号 - 修改AssignRolesCommandHandler,用户角色变更时自增权限版本号强制重登录 - 集成Redis存储权限版本镜像,支持分布式环境下的版本同步 - 添加PermissionVersion字段到User实体,用于存储权限版本号 - 实现分布式登录失败计数与账号锁定功能,增强安全防护 - 配置文件中新增AccessTokenMinutes和RefreshTokenDays可配置项 - 更新CORS策略配置,添加127.0.0.1本地访问支持 - 完善异常处理,统一使用ErrorCode枚举进行错误码管理 - 添加SOP测试单元设计文档,规范端到端测试流程
54 lines
2.1 KiB
C#
54 lines
2.1 KiB
C#
using FluentAssertions;
|
||
using NSubstitute;
|
||
using BuildFlow.Platform.Application.Users.Commands;
|
||
using BuildFlow.Platform.Application.Users.Handlers;
|
||
using BuildFlow.Platform.Domain.Common;
|
||
using BuildFlow.Shared.Domain.Exceptions;
|
||
|
||
namespace BuildFlow.Platform.Tests.Users;
|
||
|
||
/// <summary>
|
||
/// 分配角色 Command 处理器单元测试。覆盖分配成功 + 权限版本号自增、角色不存在拒绝。
|
||
/// </summary>
|
||
public class AssignRolesCommandHandlerTests
|
||
{
|
||
[Fact]
|
||
public async Task Handle_ValidAssignment_ShouldBumpPermissionVersion()
|
||
{
|
||
// Arrange
|
||
var db = PlatformTestDb.CreateDbContext();
|
||
var userId = Guid.NewGuid();
|
||
await PlatformTestDb.SeedUserAsync(db, userId, "assign-target", permissionVersion: 3);
|
||
var roleId = Guid.NewGuid();
|
||
db.Roles.Add(PlatformTestDb.WithAudit(new BuildFlow.Platform.Domain.Entities.Role { Id = roleId, Name = "Editor" }));
|
||
await db.SaveChangesAsync();
|
||
var versionStore = Substitute.For<IPermissionVersionStore>();
|
||
var handler = new AssignRolesCommandHandler(db, versionStore);
|
||
|
||
// Act
|
||
await handler.Handle(new AssignRolesCommand(userId, [roleId]), CancellationToken.None);
|
||
|
||
// Assert:版本号自增(3 → 4)+ Redis 镜像同步
|
||
var user = await db.Users.FirstAsync(u => u.Id == userId);
|
||
user.PermissionVersion.Should().Be(4);
|
||
await versionStore.Received(1).BumpAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(userId)), Arg.Any<CancellationToken>());
|
||
}
|
||
|
||
[Fact]
|
||
public async Task Handle_NonExistentRole_ShouldThrowNotFound()
|
||
{
|
||
// Arrange
|
||
var db = PlatformTestDb.CreateDbContext();
|
||
var userId = Guid.NewGuid();
|
||
await PlatformTestDb.SeedUserAsync(db, userId, "victim");
|
||
var handler = new AssignRolesCommandHandler(db, Substitute.For<IPermissionVersionStore>());
|
||
|
||
// Act
|
||
var act = () => handler.Handle(new AssignRolesCommand(userId, [Guid.NewGuid()]), CancellationToken.None);
|
||
|
||
// Assert
|
||
await act.Should().ThrowAsync<NotFoundException>()
|
||
.WithMessage("*部分角色不存在*");
|
||
}
|
||
}
|