using API.DTO.Base; using API.DTO.Login; using API.Hashing.Interfaces; using API.Services.Interfaces; using DAL.Models; namespace API.Services { public class UserManager : IUserManager { private readonly IHashingFactory _hashingFactory; private readonly ILogger _logger; private readonly HashingType _preferredHashingType; private readonly UserService _userService; public UserManager(UserService userService, IHashingFactory hashingFactory, ILogger logger, HashingType preferredHashingType) { _userService = userService; _hashingFactory = hashingFactory; _logger = logger; _preferredHashingType = preferredHashingType; } public UserDTO? AuthenticateUser(UserLoginDTO loginDTO) { User? user = _userService.getNoAuthentication(x => x.phoneNumber.Equals(loginDTO.phoneNumber)).FirstOrDefault(); if (user == null) return null; IHashingAlgorithm? hashingAlgorithm = _hashingFactory.getAlgorithm(user.hashingType); if (hashingAlgorithm == null) { _logger.Log(LogLevel.Warning, "User id '{id}' has a hashing type '{hashingType}' that isn't recognized by factory '{factory}'. Not logging in.", user.id, user.hashingType, nameof(_hashingFactory)); return null; } string hashedPassword = hashingAlgorithm.hash(loginDTO.password, user.salt); if (!hashedPassword.Equals(user.password)) { _logger.Log(LogLevel.Information, "Failed login attempt for user id '{id}.", user.id); return null; } if (user.hashingType != _preferredHashingType) { // todo The user is logged in at this point. Their hashing type needs to be updated, we need to rehash & salt the password and save it now. } UserDTO dto = new UserDTO(); dto.adaptFromModel(user); return dto; } } }