/
softailor
/
gridient
Обзор
Документация
Войти
/
softailor
/
gridient
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
backend/Gridient.Infrastructure.Authentication.Local/Features/AuthUsers/Commands/CreateUserCommandHandler.cs
127 строк
7 KB
Jenkins
Auto add
18 фев 2026, 10:19
18 фев 2026, 10:19
1e6c4f8
Код
Авторство
О чём код?
using Gridient.Core.Models; using Gridient.Core.Options; using Gridient.Core.Services.Interfaces; using Gridient.Infrastructure.Authentication.Local.Features.AuthUsers.Commands; using Gridient.Infrastructure.Authentication.Local.Models; using Gridient.Infrastructure.Authentication.Local.Repositories; using Gridient.Infrastructure.Authentication.Local.Services; using MediatR; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace Gridient.Infrastructure.Authentication.Local.Features.AuthUsers.Commands { /// <summary> /// Обработчик команды для создания пользователя администратором /// Авторизация проверяется в AuthorizationBehavior через IRequiresSystemAuthorization /// </summary> public class CreateUserCommandHandler : IRequestHandler<CreateUserCommand, int> { private readonly IUserService _userService; private readonly IAuthUserRepository _authUserRepository; private readonly IPasswordHasher _passwordHasher; private readonly RegistrationOptions _registrationOptions; private readonly ILogger<CreateUserCommandHandler> _logger; public CreateUserCommandHandler( IUserService userService, IAuthUserRepository authUserRepository, IPasswordHasher passwordHasher, IOptions<RegistrationOptions> registrationOptions, ILogger<CreateUserCommandHandler> logger) { _userService = userService; _authUserRepository = authUserRepository; _passwordHasher = passwordHasher; _registrationOptions = registrationOptions.Value; _logger = logger; } public async Task<int> Handle(CreateUserCommand request, CancellationToken cancellationToken) { _logger.LogInformation("Начало создания пользователя. Login: {Login}, Email: {Email}, CurrentUser: {CurrentUser}", request.NewUser.Login, request.NewUser.Email, request.CurrentUserLogin); if (!_registrationOptions.EnableAdminCreation) { _logger.LogWarning("Создание пользователя отклонено: EnableAdminCreation отключен"); throw new InvalidOperationException("Создание пользователей администратором отключено"); } // Проверяем, не существует ли уже пользователь с таким логином // Проверяем в Core.User (может быть чувствительно к регистру) var existingCoreUser = await _userService.GetByLoginAsync(request.NewUser.Login, cancellationToken); if (existingCoreUser != null) { _logger.LogWarning("Пользователь с логином '{Login}' уже существует в Core.User (Id: {UserId})", request.NewUser.Login, existingCoreUser.Id); throw new InvalidOperationException($"Пользователь с логином '{request.NewUser.Login}' уже существует"); } // Если пароль передан, проверяем существование в auth_users (регистр не важен) if (!string.IsNullOrWhiteSpace(request.NewUser.Password)) { var normalizedLogin = request.NewUser.Login.ToLowerInvariant(); var existingAuthUser = await _authUserRepository.GetByLoginAsync(normalizedLogin, cancellationToken); if (existingAuthUser != null) { _logger.LogWarning("Пользователь с логином '{Login}' (нормализованный: '{NormalizedLogin}') уже существует в auth_users (Id: {AuthUserId})", request.NewUser.Login, normalizedLogin, existingAuthUser.Id); throw new InvalidOperationException($"Пользователь с логином '{request.NewUser.Login}' уже существует"); } } // Создаем Core.User через IUserService int userId = 0; try { userId = await _userService.CreateAsync(request.NewUser, cancellationToken); _logger.LogInformation("Core.User создан успешно. UserId: {UserId}, Login: {Login}", userId, request.NewUser.Login); // Если пароль передан, создаем AuthUser для локальной аутентификации if (!string.IsNullOrWhiteSpace(request.NewUser.Password)) { _logger.LogDebug("Создание AuthUser для локальной аутентификации с Core UserId: {UserId}", userId); var authUser = new AuthUser { Id = userId, // Используем Core UserId Login = request.NewUser.Login.ToLowerInvariant(), PasswordHash = _passwordHasher.HashPassword(request.NewUser.Password), Email = request.NewUser.Email?.ToLowerInvariant(), DisplayName = request.NewUser.DisplayName, CreatedAt = DateTime.UtcNow }; try { int authUserId = await _authUserRepository.CreateAsync(authUser, cancellationToken); _logger.LogInformation("AuthUser создан успешно. AuthUserId (Core UserId): {AuthUserId}, Login: {Login}", authUserId, request.NewUser.Login); } catch (Exception ex) { _logger.LogError(ex, "Ошибка при создании AuthUser. Удаляем созданного Core.User (UserId: {UserId})", userId); // Пытаемся удалить созданного Core.User try { await _userService.DeleteAsync(request.CurrentUserLogin, userId, cancellationToken); _logger.LogInformation("Core.User (UserId: {UserId}) успешно удален после ошибки создания AuthUser", userId); } catch (Exception deleteEx) { _logger.LogError(deleteEx, "Критическая ошибка: не удалось удалить Core.User (UserId: {UserId}) после ошибки создания AuthUser", userId); } throw; // Пробрасываем исходную ошибку } } _logger.LogInformation("Пользователь успешно создан. UserId: {UserId}, Login: {Login}", userId, request.NewUser.Login); return userId; } catch (Exception ex) { _logger.LogError(ex, "Ошибка при создании пользователя. Login: {Login}", request.NewUser.Login); throw; } } } }