using MediatR; using AutoMapper; using cuqmbr.TravelGuide.Application.Common.Persistence; using cuqmbr.TravelGuide.Application.Common.Exceptions; using cuqmbr.TravelGuide.Application.Common.Services; using cuqmbr.TravelGuide.Domain.Entities; using cuqmbr.TravelGuide.Domain.Enums; using System.Security.Cryptography; using System.Text; namespace cuqmbr.TravelGuide.Application.Companies.Commands.AddCompany; public class AddCompanyCommandHandler : IRequestHandler { private readonly UnitOfWork _unitOfWork; private readonly IMapper _mapper; private readonly PasswordHasherService _passwordHasher; public AddCompanyCommandHandler(UnitOfWork unitOfWork, IMapper mapper, PasswordHasherService passwordHasher) { _unitOfWork = unitOfWork; _mapper = mapper; _passwordHasher = passwordHasher; } public async Task Handle( AddCompanyCommand request, CancellationToken cancellationToken) { var entity = await _unitOfWork.CompanyRepository.GetOneAsync( e => e.Name == request.Name, cancellationToken); if (entity != null) { throw new DuplicateEntityException( "Company with given name already exists."); } // Create new account for employee var account = await _unitOfWork.AccountRepository.GetOneAsync( e => e.Email == request.Email, cancellationToken); if (account != null) { throw new DuplicateEntityException(); } var role = (await _unitOfWork.RoleRepository.GetPageAsync( 1, IdentityRole.Enumerations.Count(), cancellationToken)) .Items .First(r => r.Value.Equals(IdentityRole.CompanyOwner)); 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 = new Account() { Username = request.Username, Email = request.Email, PasswordHash = hashBase64, PasswordSalt = saltBase64, AccountRoles = new AccountRole[] { new() { RoleId = role.Id } } }; account = await _unitOfWork.AccountRepository.AddOneAsync( account, cancellationToken); entity = new Company() { Name = request.Name, LegalAddress = request.LegalAddress, ContactEmail = request.ContactEmail, ContactPhoneNumber = request.ContactPhoneNumber, Account = account }; entity = await _unitOfWork.CompanyRepository.AddOneAsync( entity, cancellationToken); await _unitOfWork.SaveAsync(cancellationToken); _unitOfWork.Dispose(); return _mapper.Map(entity); } }