http-api/src/Application/Identity/Accounts/Commands/UpdateAccount/UpdateAccountCommandHandler.cs
2025-05-28 15:40:30 +03:00

110 lines
3.5 KiB
C#

using MediatR;
using cuqmbr.TravelGuide.Application.Common.Persistence;
using AutoMapper;
using cuqmbr.TravelGuide.Application.Common.Exceptions;
using System.Security.Cryptography;
using System.Text;
using cuqmbr.TravelGuide.Application.Common.Services;
using cuqmbr.TravelGuide.Domain.Entities;
namespace cuqmbr.TravelGuide.Application
.Identity.Accounts.Commands.UpdateAccount;
public class UpdateAccountCommandHandler :
IRequestHandler<UpdateAccountCommand, AccountDto>
{
private readonly UnitOfWork _unitOfWork;
private readonly IMapper _mapper;
private readonly PasswordHasherService _passwordHasher;
public UpdateAccountCommandHandler(UnitOfWork unitOfWork,
IMapper mapper, PasswordHasherService passwordHasher)
{
_unitOfWork = unitOfWork;
_mapper = mapper;
_passwordHasher = passwordHasher;
}
public async Task<AccountDto> Handle(
UpdateAccountCommand request,
CancellationToken cancellationToken)
{
var account = await _unitOfWork.AccountRepository
.GetOneAsync(e => e.Guid == request.Guid,
e => e.AccountRoles, cancellationToken);
if (account == null)
{
throw new NotFoundException();
}
account.Username = request.Username ?? account.Username;
account.Email = request.Email ?? account.Email;
if (request.Password != null)
{
var salt = RandomNumberGenerator.GetBytes(128 / 8);
var hash = await _passwordHasher.HashAsync(
Encoding.UTF8.GetBytes(request.Password),
salt, cancellationToken);
var saltBase64 = Convert.ToBase64String(salt);
var hashBase64 = Convert.ToBase64String(hash);
account.PasswordHash = hashBase64;
account.PasswordSalt = saltBase64;
}
if (request.Roles != null)
{
var requestRoleIds = (await _unitOfWork.RoleRepository
.GetPageAsync(
r => request.Roles.Contains(r.Value),
1, request.Roles.Count, cancellationToken))
.Items
.Select(r => r.Id);
var accountRoles = account.AccountRoles;
var accountRoleIds = accountRoles.Select(ar => ar.RoleId);
var commonRoleIds = requestRoleIds.Intersect(accountRoleIds);
var newRoleIds = requestRoleIds.Except(accountRoleIds);
var combinedRoleIds = commonRoleIds.Union(newRoleIds);
account.AccountRoles = combinedRoleIds.Select(rId =>
new AccountRole()
{
Id = accountRoles.FirstOrDefault(ar =>
ar.RoleId == rId)?.Id ?? default,
RoleId = rId
})
.ToList();
}
else
{
var accountRoleIds = account.AccountRoles.Select(ar => ar.RoleId);
var accountRoles = (await _unitOfWork.AccountRoleRepository
.GetPageAsync(
ar => accountRoleIds.Contains(ar.RoleId),
ar => ar.Role,
1, accountRoleIds.Count(), cancellationToken))
.Items;
account.AccountRoles = accountRoles.ToList();
}
account = await _unitOfWork.AccountRepository.UpdateOneAsync(
account, cancellationToken);
await _unitOfWork.SaveAsync(cancellationToken);
_unitOfWork.Dispose();
return _mapper.Map<AccountDto>(account);
}
}