110 lines
3.5 KiB
C#
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);
|
|
}
|
|
}
|