feat: strengthen P0 security and operations
This commit is contained in:
@@ -19,6 +19,53 @@ namespace Tiku.IntegrationTests.Api;
|
||||
|
||||
public sealed class PlatformAdminEndpointTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Platform_staff_password_reset_revokes_sessions_and_requires_change()
|
||||
{
|
||||
await using var factory = new ApiTestFactory(configurationOverrides: new Dictionary<string, string?>
|
||||
{
|
||||
["Tenancy:Resolution:PlatformHosts:0"] = "localhost"
|
||||
});
|
||||
var administrator = await SeedPlatformAdminAsync(factory);
|
||||
var target = await SeedAdditionalPlatformUserAsync(factory);
|
||||
using var targetClient = factory.CreateClient();
|
||||
var targetTokens = await targetClient.LoginAsPlatformAsync(target.Email);
|
||||
using var adminClient = factory.CreateClient();
|
||||
adminClient.UseAccessToken(await adminClient.LoginAsPlatformAsync(administrator.Email));
|
||||
|
||||
var reset = await adminClient.PostAsJsonAsync(
|
||||
$"/api/platform-admin/staff/{target.UserId}/password-reset",
|
||||
new AdministrativePasswordResetDto
|
||||
{
|
||||
TemporaryPassword = "TemporaryPassword2026",
|
||||
Reason = "Platform staff recovery verification"
|
||||
});
|
||||
|
||||
Assert.Equal(HttpStatusCode.NoContent, reset.StatusCode);
|
||||
targetClient.UseAccessToken(targetTokens);
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, (await targetClient.GetAsync("/api/me")).StatusCode);
|
||||
targetClient.DefaultRequestHeaders.Authorization = null;
|
||||
var login = await targetClient.PostAsJsonAsync(
|
||||
"/api/auth/login/password",
|
||||
new PasswordLoginDto
|
||||
{
|
||||
Realm = AuthRealm.Platform,
|
||||
Identifier = target.Email,
|
||||
Password = "TemporaryPassword2026"
|
||||
});
|
||||
Assert.Equal(HttpStatusCode.OK, login.StatusCode);
|
||||
Assert.Contains("password_change_required", await login.Content.ReadAsStringAsync(), StringComparison.Ordinal);
|
||||
|
||||
using var scope = factory.CreateSystemScope("Verify platform administrative password reset");
|
||||
var dbContext = scope.ServiceProvider.GetRequiredService<TikuDbContext>();
|
||||
Assert.True(await dbContext.Users.Where(item => item.Id == target.UserId).Select(item => item.ForcePasswordChange).SingleAsync());
|
||||
Assert.True(await dbContext.AuditLogs.AnyAsync(item =>
|
||||
item.TenantId == null &&
|
||||
item.ActorUserId == administrator.UserId &&
|
||||
item.Action == "auth.password.reset_by_administrator" &&
|
||||
item.TargetId == target.UserId.ToString()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Platform_super_admin_can_load_every_platform_console_bootstrap_endpoint()
|
||||
{
|
||||
@@ -506,6 +553,43 @@ public sealed class PlatformAdminEndpointTests
|
||||
return await SeedPlatformUserAsync(factory, BackendPermissions.Platform);
|
||||
}
|
||||
|
||||
private static async Task<(Guid UserId, string Email)> SeedAdditionalPlatformUserAsync(ApiTestFactory factory)
|
||||
{
|
||||
var userId = Guid.NewGuid();
|
||||
var roleId = Guid.NewGuid();
|
||||
var email = $"platform-target-{Guid.NewGuid():N}@example.test";
|
||||
await factory.SeedAsync(
|
||||
new User
|
||||
{
|
||||
Id = userId,
|
||||
Email = email,
|
||||
NormalizedEmail = email.ToUpperInvariant(),
|
||||
UserName = email,
|
||||
NormalizedUserName = email.ToUpperInvariant(),
|
||||
Name = "Platform Reset Target",
|
||||
PrimaryRole = "platform_staff",
|
||||
RawProfile = JsonDefaults.Object()
|
||||
}.WithTestPassword(),
|
||||
new PlatformBackendRole
|
||||
{
|
||||
Id = roleId,
|
||||
Code = $"platform_reset_target_{roleId:N}",
|
||||
Name = "Platform Reset Target",
|
||||
Status = BackendRoleStatus.Active
|
||||
},
|
||||
new PlatformBackendRolePermission
|
||||
{
|
||||
RoleId = roleId,
|
||||
PermissionCode = BackendPermissions.PlatformDashboardView
|
||||
},
|
||||
new PlatformBackendUserRole
|
||||
{
|
||||
UserId = userId,
|
||||
RoleId = roleId
|
||||
});
|
||||
return (userId, email);
|
||||
}
|
||||
|
||||
private static async Task<(Guid UserId, string Email)> SeedPlatformUserAsync(
|
||||
ApiTestFactory factory,
|
||||
IEnumerable<string> platformPermissions)
|
||||
|
||||
Reference in New Issue
Block a user