using AutoMapper; using Microsoft.EntityFrameworkCore; using Serilog; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WorkFlowCheck.Common.DTO; using WorkFlowCheck.BL.Services.Interfaces; using WorkFlowCheck.DL; using WorkFlowCheck.Common.Security; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using WorkFlowCheck.DL.Entities; using Microsoft.Extensions.Configuration; using Microsoft.AspNetCore.Identity; using WorkFlowCheck.BL.Static; using System.Reflection; namespace WorkFlowCheck.BL.Services { public class UserService : BaseService, IUserService { private IConfiguration _configuration; private IMessageService _messageService; public UserService(AppDbContext dbContext, IMapper mapper, IConfiguration configuration, IMessageService messageService) : base(dbContext, mapper) { _configuration = configuration; _messageService = messageService; } public async Task GetUserAsync(int Id) { var retVal = new UserDTO() { RoleDTO = new List() }; try { var user = await _dbContext.Users .Include(i => i.UserRoles) .ThenInclude(i => i.Role) .Where(w => w.Id == Id).FirstOrDefaultAsync(); if (user != null) { retVal = _mapper.Map(user); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task> GetAllUserAsync() { var retVal = new List { new UserDTO { RoleDTO = new List() } }; try { var users = await _dbContext.Users .Include(i => i.UserRoles) .ThenInclude(i => i.Role) .ToListAsync(); if (users != null) { retVal = _mapper.Map>(users); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task DeleteUserAsync(int id) { return await DeleteEntityByIdAsync(id); } public async Task Authenticate(string userName, string password) { var retVal = new UserDTO() { RoleDTO = new List() }; try { var user = await _dbContext.Users .Include(i => i.UserRoles) .ThenInclude(i => i.Role) .Where(w => w.UserName == userName && w.Active != false) .FirstOrDefaultAsync(); if (user != null && PasswordHasher.VerifyPassword(user.PasswordHash, password)) { var userDTO = new UserDTO() { Id = user.Id, UserName = user.UserName, RoleDTO = new List(), }; foreach (var item in user.UserRoles) { userDTO.RoleDTO.Add(new RoleDTO() { Id = item.Role.Id, RoleName = item.Role.RoleName, }); } user.JwtToken = GenerateJwtToken(userDTO); await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(user); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task Authenticate2F1(string userName, string password) { var retVal = ""; try { Log.ForContext("TAG", "AuditFlow").Information($"Bejelentkezési kísérlet: {userName}"); var user = await _dbContext.Users .Include(i => i.UserRoles) .ThenInclude(i => i.Role) .Where(w => w.UserName == userName) .FirstOrDefaultAsync(); if (user != null && PasswordHasher.VerifyPassword(user.PasswordHash, password)) { var canUseWebAdmin = false; foreach (var userRole in user.UserRoles) { if (userRole.Role.CanUseWebAdmin) { canUseWebAdmin = true; break; } } if (!string.IsNullOrEmpty(user.Email) && canUseWebAdmin) { var code = CodeGenerator2F.GenerateSixDigitCode(); await _messageService.SendMailAsync(new List() { user.Email, }, "Bejelentkezés megerősítése", Get2FConfirmationMessageBody(code)); Log.ForContext("TAG", "AuditFlow").Information($"Bejelentkezési kísérlet, email küldés: {user.Email}"); retVal = CodeGenerator2F.GenerateToken2F(userName, password, code); return retVal; } else { Log.ForContext("TAG", "AuditFlow").Information($"A WEB felület NEM használható!: {userName}"); } } else { Log.ForContext("TAG", "AuditFlow").Error($"Sikertelen bejelentkezési kísérlet: {userName}"); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task Authenticate2F2(string userName, string password, string code, string token2FA) { var retVal = new UserDTO() { RoleDTO = new List() }; try { var user = await _dbContext.Users .Include(i => i.UserRoles) .ThenInclude(i => i.Role) .Where(w => w.UserName == userName && w.Active != false) .FirstOrDefaultAsync(); if (user != null && PasswordHasher.VerifyPassword(user.PasswordHash, password)) { if (CodeGenerator2F.ValidateToken2F(token2FA, userName, password, code)) { var userDTO = new UserDTO() { Id = user.Id, UserName = user.UserName, RoleDTO = new List(), }; foreach (var item in user.UserRoles) { userDTO.RoleDTO.Add(new RoleDTO() { Id = item.Role.Id, RoleName = item.Role.RoleName, }); } user.JwtToken = GenerateJwtToken(userDTO); await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(user); Log.ForContext("TAG", "AuditFlow").Information($"Sikeres 2FA azonosítás!: {userName}"); return retVal; } } else { Log.ForContext("TAG", "AuditFlow").Error($"Sikertelen 2FA bejelentkezési kísérlet: {userName}"); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task Authenticate2F2ChangePassword(string userName, string oldPassword, string newPassword, string code, string token2FA) { var retVal = new UserDTO() { RoleDTO = new List() }; try { var user = await _dbContext.Users .Include(i => i.UserRoles) .ThenInclude(i => i.Role) .Where(w => w.UserName == userName && w.Active != false) .FirstOrDefaultAsync(); if (user != null && PasswordHasher.VerifyPassword(user.PasswordHash, oldPassword)) { if (CodeGenerator2F.ValidateToken2F(token2FA, userName, oldPassword, code)) { user.PasswordHash = PasswordHasher.HashPassword(newPassword); var userDTO = new UserDTO() { Id = user.Id, UserName = user.UserName, RoleDTO = new List(), }; foreach (var item in user.UserRoles) { userDTO.RoleDTO.Add(new RoleDTO() { Id = item.Role.Id, RoleName = item.Role.RoleName, }); } user.PasswordHash = PasswordHasher.HashPassword(newPassword); user.JwtToken = GenerateJwtToken(userDTO); await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(user); Log.ForContext("TAG", "AuditFlow").Information($"Sikeres jelszó módosítás: {userName}"); return retVal; } } else { Log.ForContext("TAG", "AuditFlow").Error($"Sikertelen jelszó módosítási kísérlet: {userName}"); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task AuthenticateNFC(string NFCCode) { var retVal = new UserDTO() { RoleDTO = new List() }; try { var user = await _dbContext.Users .Include(i => i.UserRoles) .ThenInclude(i => i.Role) .Where(w => w.NFCCode == NFCCode && w.NFCActive == true) .FirstOrDefaultAsync(); if (user != null) { var userDTO = new UserDTO() { Id = user.Id, UserName = user.UserName, RoleDTO = new List(), }; foreach (var item in user.UserRoles) { userDTO.RoleDTO.Add(new RoleDTO() { Id = item.Role.Id, RoleName = item.Role.RoleName, }); } user.JwtToken = GenerateJwtToken(userDTO); await _dbContext.SaveChangesAsync(); Log.ForContext("TAG", "AuditFlow").Information($"Sikeres NFC kártya azonosítás kísérlet: {user.UserName}"); retVal = _mapper.Map(user); } else { Log.ForContext("TAG", "AuditFlow").Error($"Sikertelen NFC kártya azonosítás: {NFCCode}"); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public string GenerateJwtToken(UserDTO userDTO) { var jwtSettings = _configuration.GetSection("Jwt"); var secretKey = jwtSettings["SecretKey"]; var issuer = jwtSettings["Issuer"]; var audience = jwtSettings["Audience"]; var tokenLifetime = int.Parse(jwtSettings["TokenLifetimeMinutes"]); var claims = new List { new Claim(ClaimTypes.Name, userDTO.UserName), new Claim(ClaimTypes.NameIdentifier, userDTO.Id.ToString()) }; foreach (var role in userDTO.RoleDTO) { claims.Add(new Claim(ClaimTypes.Role, role.RoleName)); } var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( issuer: issuer, audience: audience, claims: claims, expires: DateTime.UtcNow.AddMinutes(tokenLifetime), signingCredentials: creds); return new JwtSecurityTokenHandler().WriteToken(token); } public async Task UpdateUserAsync(UserDTO userDTO) { var retVal = new UserDTO() { RoleDTO = new List() }; try { if (userDTO.Id == 0) { var user = new User(); user.UserName = userDTO.UserName; user.FirstName = userDTO.FirstName; user.LastName = userDTO.LastName; user.Email = userDTO.Email; user.NFCActive = userDTO.NFCActive; user.NFCCode = userDTO.NFCCode; user.JwtToken = ""; user.Token2FA = ""; user.IsDeleted = false; user.Active = userDTO.Active; user.PasswordHash = PasswordHasher.HashPassword(userDTO.Password); _dbContext.Users.Add(user); await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(user); } else { var user = await _dbContext.Users.Where(w => w.Id == userDTO.Id).FirstOrDefaultAsync(); if (user != null) { user.UserName = userDTO.UserName; user.FirstName = userDTO.FirstName; user.LastName = userDTO.LastName; user.Email = userDTO.Email; user.Active = userDTO.Active; user.NFCActive = userDTO.NFCActive; user.NFCCode = userDTO.NFCCode; await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(user); } } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } private string Get2FConfirmationMessageBody(string token2F) { var assembly = Assembly.GetExecutingAssembly(); var resourceName = "WorkFlowCheck.BL.HtmlTemplates.Token2FBody.html"; using var stream = assembly.GetManifestResourceStream(resourceName); if (stream == null) throw new FileNotFoundException($"Nem található a beágyazott erőforrás: {resourceName}"); using var reader = new StreamReader(stream); var html = reader.ReadToEnd(); return html.Replace("#token2F#", token2F); } public async Task GetRoleAsync(int Id) { var retVal = new RoleDTO(); try { var user = await _dbContext.Roles.Where(w => w.Id == Id).FirstOrDefaultAsync(); if (user != null) { retVal = _mapper.Map(user); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task> GetAllRoleAsync() { var retVal = new List(); try { var roles = await _dbContext.Roles.ToListAsync(); if (roles != null) { retVal = _mapper.Map>(roles); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task DeleteRoleAsync(int id) { return await DeleteEntityByIdAsync(id); } public async Task UpdateRoleAsync(RoleDTO roleDTO) { var retVal = new RoleDTO(); try { if (roleDTO.Id == 0) { var role = new Role(); role.RoleName = roleDTO.RoleName; if (roleDTO.ParentId > 0) { role.ParentId = roleDTO.ParentId; } role.IsAdmin = roleDTO.IsAdmin; role.CanDownloadAPK = roleDTO.CanDownloadAPK; role.CanEnableBlocked = roleDTO.CanEnableBlocked; role.CanUseWebAdmin = roleDTO.CanUseWebAdmin; role.CanUseMobilApp = roleDTO.CanUseMobilApp; _dbContext.Roles.Add(role); await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(role); } else { var role = await _dbContext.Roles.Where(w => w.Id == roleDTO.Id).FirstOrDefaultAsync(); if (role != null) { role.RoleName = roleDTO.RoleName; if (roleDTO.ParentId > 0) { role.ParentId = roleDTO.ParentId; } role.IsAdmin = roleDTO.IsAdmin; role.CanDownloadAPK = roleDTO.CanDownloadAPK; role.CanEnableBlocked = roleDTO.CanEnableBlocked; role.CanUseWebAdmin = roleDTO.CanUseWebAdmin; role.CanUseMobilApp = roleDTO.CanUseMobilApp; await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(role); } } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task GetUserRoleAsync(int Id) { var retVal = new UserRoleDTO(); try { var userRole = await _dbContext.UserRoles.Where(w => w.Id == Id).FirstOrDefaultAsync(); if (userRole != null) { retVal = _mapper.Map(userRole); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task> GetAllUserRoleAsync() { var retVal = new List(); try { var userRoles = await _dbContext.UserRoles .Include(i => i.User) .Include(i => i.Role) .AsNoTracking() .ToListAsync(); if (userRoles != null) { retVal = _mapper.Map>(userRoles); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task DeleteUserRoleAsync(int id) { return await DeleteEntityByIdAsync(id); } public async Task UpdateUserRoleAsync(UserRoleDTO userRoleDTO) { var retVal = new UserRoleDTO(); try { if (userRoleDTO.Id == 0) { var userRole = new UserRole(); userRole.UserId = userRoleDTO.UserId; userRole.RoleId = userRoleDTO.RoleId; _dbContext.UserRoles.Add(userRole); await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(userRole); } else { var userRole = await _dbContext.UserRoles.Where(w => w.Id == userRoleDTO.Id).FirstOrDefaultAsync(); if (userRole != null) { userRole.UserId = userRoleDTO.UserId; userRole.RoleId = userRoleDTO.RoleId; await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(userRole); } } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task GetRoleCheckListTemplateHeaderAsync(int Id) { var retVal = new RoleCheckListTemplateHeaderDTO(); try { var userRole = await _dbContext.RoleCheckListTemplateHeaders.Where(w => w.Id == Id).FirstOrDefaultAsync(); if (userRole != null) { retVal = _mapper.Map(userRole); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task> GetAllRoleCheckListTemplateHeadersAsync() { var retVal = new List(); try { var results = await _dbContext.RoleCheckListTemplateHeaders .Include(i => i.CheckListTemplateHeader) .Include(i => i.Role) .AsNoTracking() .ToListAsync(); if (results != null) { retVal = _mapper.Map>(results); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task DeleteRoleCheckListTemplateHeaderAsync(int id) { return await DeleteEntityByIdAsync(id); } public async Task UpdateRoleCheckListTemplateHeaderAsync(RoleCheckListTemplateHeaderDTO roleCheckListTemplateHeaderDTO) { var retVal = new RoleCheckListTemplateHeaderDTO(); try { if (roleCheckListTemplateHeaderDTO.Id == 0) { var roleCheckListTemplateHeader_Exists = await _dbContext.RoleCheckListTemplateHeaders .Where(w => w.RoleId == roleCheckListTemplateHeaderDTO.RoleId && w.CheckListTemplateHeaderId == roleCheckListTemplateHeaderDTO.CheckListTemplateHeaderId) .FirstOrDefaultAsync(); if (roleCheckListTemplateHeader_Exists == null) { var roleCheckListTemplateHeader = new RoleCheckListTemplateHeader(); roleCheckListTemplateHeader.CheckListTemplateHeaderId = roleCheckListTemplateHeaderDTO.CheckListTemplateHeaderId; roleCheckListTemplateHeader.RoleId = roleCheckListTemplateHeaderDTO.RoleId; roleCheckListTemplateHeader.Enabled = roleCheckListTemplateHeaderDTO.Enabled; _dbContext.RoleCheckListTemplateHeaders.Add(roleCheckListTemplateHeader); await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(roleCheckListTemplateHeader); } else { retVal = _mapper.Map(roleCheckListTemplateHeader_Exists); } } else { var roleCheckListTemplateHeader = await _dbContext.RoleCheckListTemplateHeaders.Where(w => w.Id == roleCheckListTemplateHeaderDTO.Id).FirstOrDefaultAsync(); if (roleCheckListTemplateHeader != null) { roleCheckListTemplateHeader.CheckListTemplateHeaderId = roleCheckListTemplateHeaderDTO.CheckListTemplateHeaderId; roleCheckListTemplateHeader.RoleId = roleCheckListTemplateHeaderDTO.RoleId; roleCheckListTemplateHeader.Enabled = roleCheckListTemplateHeaderDTO.Enabled; await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(roleCheckListTemplateHeader); } } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task GetRoleCheckPointAsync(int Id) { var retVal = new RoleCheckPointDTO(); try { var userRole = await _dbContext.RoleCheckPoints.Where(w => w.Id == Id).FirstOrDefaultAsync(); if (userRole != null) { retVal = _mapper.Map(userRole); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task> GetAllRoleCheckPointsAsync() { var retVal = new List(); try { var results = await _dbContext.RoleCheckPoints .Include(i => i.CheckPoint) .Include(i => i.Role) .AsNoTracking() .ToListAsync(); if (results != null) { retVal = _mapper.Map>(results); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task DeleteRoleCheckPointAsync(int id) { return await DeleteEntityByIdAsync(id); } public async Task UpdateRoleCheckPointAsync(RoleCheckPointDTO roleCheckPointDTO) { var retVal = new RoleCheckPointDTO(); try { if (roleCheckPointDTO.Id == 0) { var roleCheckPoint_Exists = await _dbContext.RoleCheckPoints .Where(w => w.RoleId == roleCheckPointDTO.RoleId && w.CheckPointId == roleCheckPointDTO.CheckPointId) .FirstOrDefaultAsync(); if (roleCheckPoint_Exists == null) { var roleCheckPoint = new RoleCheckPoint(); roleCheckPoint.CheckPointId = roleCheckPointDTO.CheckPointId; roleCheckPoint.RoleId = roleCheckPointDTO.RoleId; roleCheckPoint.Enabled = roleCheckPointDTO.Enabled; _dbContext.RoleCheckPoints.Add(roleCheckPoint); await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(roleCheckPoint); } else { retVal = _mapper.Map(roleCheckPoint_Exists); } } else { var roleCheckPoint = await _dbContext.RoleCheckPoints.Where(w => w.Id == roleCheckPointDTO.Id).FirstOrDefaultAsync(); if (roleCheckPoint != null) { roleCheckPoint.CheckPointId = roleCheckPointDTO.CheckPointId; roleCheckPoint.RoleId = roleCheckPointDTO.RoleId; roleCheckPoint.Enabled = roleCheckPointDTO.Enabled; await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(roleCheckPoint); } } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } } }