Files
tiku-backend.net/Tiku.Infrastructure/Auth/AuthAdministrationService.cs
xiong 33375a38d7
Some checks failed
ci / release-gate (push) Has been cancelled
refactor(architecture): harden module boundaries
2026-08-04 12:10:36 +08:00

62 lines
2.7 KiB
C#

using System.Text.Json;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Tiku.Application.Auth;
using Tiku.Domain.Identity;
using Tiku.Domain.Operations;
using Tiku.Domain.Tenancy;
using Tiku.Infrastructure.Persistence;
namespace Tiku.Infrastructure.Auth;
internal sealed class AuthAdministrationService(
IIdentityPersistence identityPersistence,
IJobsOperationsPersistence jobsOperationsPersistence,
UserManager<User> userManager,
IAuthSessionStore sessionStore) : IAuthAdministrationService
{
public async Task ResetPasswordAsync(
AdministrativePasswordResetRequest request,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(request.Reason))
throw new InvalidCredentialsException("password_reset_reason_required");
var permitted = request.TenantId is { } tenantId
? await identityPersistence.TenantMemberships.AnyAsync(
item => item.TenantId == tenantId && item.UserId == request.TargetUserId &&
item.Status == MembershipStatus.Active,
cancellationToken)
: await jobsOperationsPersistence.PlatformBackendUserRoles.AnyAsync(
item => item.UserId == request.TargetUserId,
cancellationToken);
if (!permitted) throw new AuthSessionNotFoundException();
var user = await userManager.FindByIdAsync(request.TargetUserId.ToString())
?? throw new AuthSessionNotFoundException();
var token = await userManager.GeneratePasswordResetTokenAsync(user);
var reset = await userManager.ResetPasswordAsync(user, token, request.TemporaryPassword);
if (!reset.Succeeded) throw new InvalidCredentialsException("invalid_new_password");
user.ForcePasswordChange = true;
var updated = await userManager.UpdateAsync(user);
if (!updated.Succeeded)
throw new InvalidOperationException("Unable to require a password change after the administrative reset.");
await sessionStore.RevokeAllAsync(user.Id, "administrative_password_reset", cancellationToken);
jobsOperationsPersistence.AuditLogs.Add(new AuditLog
{
TenantId = request.TenantId,
ActorUserId = request.ActorUserId,
Action = "auth.password.reset_by_administrator",
TargetType = "user",
TargetId = request.TargetUserId.ToString(),
Details = JsonSerializer.SerializeToElement(new
{
request.Reason,
ForcePasswordChange = true
})
});
await identityPersistence.SaveChangesAsync(cancellationToken);
}
}