package net.gepafin.tendermanagement.dao; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.BeneficiaryEntity; import net.gepafin.tendermanagement.entities.RoleEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.RoleStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.CompanyResponse; import net.gepafin.tendermanagement.model.response.RoleResponseBean; import net.gepafin.tendermanagement.model.response.UserSamlResponse; import net.gepafin.tendermanagement.model.response.UserResponseBean; import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.repositories.BeneficiaryRepository; import net.gepafin.tendermanagement.repositories.UserRepository; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.impl.AuthenticationService; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; import org.springframework.stereotype.Repository; import java.util.List; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; @Component public class UserDao { private final Logger log = LoggerFactory.getLogger(UserDao.class); @Autowired private UserRepository userRepository; @Autowired private CompanyDao companyDao; @Autowired private AuthenticationService authService; @Autowired private PasswordEncoder passwordEncoder; @Autowired private RoleDao roleDao; @Autowired private BeneficiaryRepository beneficiaryRepository; public JWTToken createUser(HttpServletRequest request, String tempToken, UserReq userReq) { validateUserRequest(tempToken, userReq); validatePassword(userReq.getPassword(), userReq.getConfPassword(), tempToken); RoleEntity roleEntity = getRoleEntity(userReq.getRoleId()); BeneficiaryEntity beneficiary = createBeneficiary(roleEntity, userReq); UserEntity userEntity = convertUserRequestToUserEntity(beneficiary, roleEntity, userReq); log.info("User created with ID: {}", userEntity.getId()); return authService.getJWTTokenBean(userEntity, Boolean.TRUE); } private BeneficiaryEntity createBeneficiary(RoleEntity roleEntity, UserReq userReq) { BeneficiaryEntity beneficiaryEntity = null; if (RoleStatusEnum.ROLE_BENEFICIARY.getValue().equals(roleEntity.getRoleType())) { beneficiaryEntity = new BeneficiaryEntity(); beneficiaryEntity.setAddress(userReq.getAddress()); beneficiaryEntity.setCity(userReq.getCity()); beneficiaryEntity.setCodiceFiscale(userReq.getCodiceFiscale()); beneficiaryEntity.setCountry(userReq.getCountry()); beneficiaryEntity.setDateOfBirth(userReq.getDateOfBirth()); beneficiaryEntity.setEmail(userReq.getEmail()); beneficiaryEntity.setFirstName(userReq.getFirstName()); beneficiaryEntity.setLastName(userReq.getLastName()); beneficiaryEntity.setOrganization(userReq.getOrganization()); beneficiaryEntity.setPhoneNumber(userReq.getPhoneNumber()); beneficiaryEntity.setPrivacy(userReq.getPrivacy()); beneficiaryEntity.setTerms(userReq.getTerms()); beneficiaryEntity.setOffers(userReq.getOffers()); beneficiaryEntity.setMarketing(userReq.getMarketing()); beneficiaryEntity.setThirdParty(userReq.getThirdParty()); beneficiaryEntity.setEmailPec(userReq.getEmailPec()); beneficiaryEntity =beneficiaryRepository.save(beneficiaryEntity); } return beneficiaryEntity; } private void validateUserRequest(String tempToken, UserReq userReq) { if (Boolean.FALSE.equals(Utils.isValidEmail(userReq.getEmail()))) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATE_EMAIL)); } log.info("Creating user with email: {}", userReq.getEmail()); if (userRepository.existsByEmailIgnoreCase(userReq.getEmail())) { log.error("User creation failed: Email {} already exists", userReq.getEmail()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.EMAIL_ALREADY_EXISTS)); } if (Boolean.FALSE.equals(StringUtils.isEmpty(userReq.getCodiceFiscale())) && userRepository.existsByBeneficiaryCodiceFiscale(userReq.getCodiceFiscale())) { log.error("User creation failed: CodiceFiscale {} already exists", userReq.getCodiceFiscale()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.CODICE_FISCALE_EXISTS)); } if (tempToken == null && userReq.getRoleId() == null) { throw new ResourceNotFoundException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.ROLE_ID_MANDATORY)); } if (tempToken != null) { userReq.setRoleId(null); } } private void validatePassword(String password, String confirmPassword, String tempToken) { if (StringUtils.isEmpty(password) || StringUtils.isEmpty(confirmPassword)) { if(tempToken == null) { throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATE_PASSWORD)); }else if(Boolean.FALSE.equals(StringUtils.isEmpty(password) && StringUtils.isEmpty(confirmPassword))){ throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.VALIDATE_PASSWORD)); } } if (password != null && !password.equals(confirmPassword)) { log.error("User creation failed: Passwords do not match"); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_DOESNT_MATCH)); } if (password != null && password.length() < 8) { log.error("User creation failed: Password length is less than 8 characters"); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_MIN_LEN)); } } public UserResponseBean updateUser(Long userId, UpdateUserReq userReq) { log.info("Updating user with ID: {}", userId); UserEntity userEntity=validateUser(userId); log.info("Current user details: {}", userEntity); log.info("New user details: {}", userReq); String newStatus = userReq.getStatus() != null ? userReq.getStatus().getValue() : null; if (Boolean.FALSE.equals(userEntity.getStatus().equals(newStatus))) { userEntity.setStatus(newStatus); } setIfUpdated(userEntity::getFirstName, userEntity::setFirstName, userReq.getFirstName()); setIfUpdated(userEntity::getLastName, userEntity::setLastName, userReq.getLastName()); setIfUpdated(userEntity::getOrganization, userEntity::setOrganization, userReq.getOrganization()); setIfUpdated(userEntity::getAddress, userEntity::setAddress, userReq.getAddress()); setIfUpdated(userEntity::getPhoneNumber, userEntity::setPhoneNumber, userReq.getPhoneNumber()); setIfUpdated(userEntity::getDateOfBirth, userEntity::setDateOfBirth, userReq.getDateOfBirth()); setIfUpdated(userEntity.getBeneficiary()::getCodiceFiscale, userEntity.getBeneficiary()::setCodiceFiscale, userReq.getCodiceFiscale()); setIfUpdated(userEntity.getBeneficiary()::getMarketing, userEntity.getBeneficiary()::setMarketing, userReq.getMarketing()); setIfUpdated(userEntity.getBeneficiary()::getOffers, userEntity.getBeneficiary()::setOffers, userReq.getOffers()); setIfUpdated(userEntity.getBeneficiary()::getThirdParty, userEntity.getBeneficiary()::setThirdParty, userReq.getThirdParty()); if (userReq.getRoleId() != null) { RoleEntity roleEntity = roleDao.validateRole(userReq.getRoleId()); setIfUpdated(userEntity::getRoleEntity, userEntity::setRoleEntity, roleEntity); } setIfUpdated(userEntity.getBeneficiary()::getEmailPec, userEntity.getBeneficiary()::setEmailPec, userReq.getEmailPec()); userEntity = userRepository.save(userEntity); log.info("User updated with ID: {}", userEntity.getId()); return convertUserEntityToUserResponse(userEntity); } private UserEntity convertUserRequestToUserEntity(BeneficiaryEntity beneficiary, RoleEntity roleEntity, UserReq userReq) { UserEntity userEntity = new UserEntity(); if(Boolean.FALSE.equals(StringUtils.isEmpty(userReq.getPassword()))) { userEntity.setPassword(passwordEncoder.encode(userReq.getPassword())); } userEntity.setRoleEntity(roleEntity); userEntity.setEmail(userReq.getEmail()); userEntity.setStatus(UserStatusEnum.ACTIVE.getValue()); userEntity.setBeneficiary(beneficiary); if (Boolean.FALSE.equals(RoleStatusEnum.ROLE_BENEFICIARY.getValue().equals(roleEntity.getRoleType()))) { userEntity.setFirstName(userReq.getFirstName()); userEntity.setLastName(userReq.getLastName()); userEntity.setOrganization(userReq.getOrganization()); userEntity.setAddress(userReq.getAddress()); userEntity.setPhoneNumber(userReq.getPhoneNumber()); userEntity.setDateOfBirth(userReq.getDateOfBirth()); } return userRepository.save(userEntity); } private RoleEntity getRoleEntity(Long roleId) { if(roleId != null) { return roleDao.validateRole(roleId); } else { return roleDao.getRoleByType(RoleStatusEnum.ROLE_BENEFICIARY); } } private UserResponseBean convertUserEntityToUserResponse(UserEntity userEntity) { UserResponseBean userResponseBean = new UserResponseBean(); userResponseBean.setId(userEntity.getId()); userResponseBean.setCreatedDate(userEntity.getCreatedDate()); userResponseBean.setUpdatedDate(userEntity.getUpdatedDate()); userResponseBean.setEmail(userEntity.getEmail()); userResponseBean.setStatus(UserStatusEnum.valueOf(userEntity.getStatus())); RoleResponseBean roleResponseBean = roleDao.convertRoleEntityToRoleResponse(userEntity.getRoleEntity()); userResponseBean.setRole(roleResponseBean); userResponseBean.setLastLogin(userEntity.getLastLogin()); List companyResponseBeans = companyDao.getCompanyByUserId(userEntity.getId()); userResponseBean.setCompanies(companyResponseBeans); if (userEntity.getBeneficiary() == null) { userResponseBean.setFirstName(userEntity.getFirstName()); userResponseBean.setLastName(userEntity.getLastName()); userResponseBean.setPhoneNumber(userEntity.getPhoneNumber()); userResponseBean.setOrganization(userEntity.getOrganization()); userResponseBean.setAddress(userEntity.getAddress()); userResponseBean.setCity(userEntity.getCity()); userResponseBean.setCountry(userEntity.getCountry()); userResponseBean.setDateOfBirth(userEntity.getDateOfBirth()); } else { userResponseBean.setFirstName(userEntity.getBeneficiary().getFirstName()); userResponseBean.setLastName(userEntity.getBeneficiary().getLastName()); userResponseBean.setPhoneNumber(userEntity.getBeneficiary().getPhoneNumber()); userResponseBean.setOrganization(userEntity.getBeneficiary().getOrganization()); userResponseBean.setAddress(userEntity.getBeneficiary().getAddress()); userResponseBean.setCity(userEntity.getBeneficiary().getCity()); userResponseBean.setCountry(userEntity.getBeneficiary().getCountry()); userResponseBean.setCodiceFiscale(userEntity.getBeneficiary().getCodiceFiscale()); userResponseBean.setDateOfBirth(userEntity.getBeneficiary().getDateOfBirth()); userResponseBean.setPrivacy(userEntity.getBeneficiary().getPrivacy()); userResponseBean.setTerms(userEntity.getBeneficiary().getTerms()); userResponseBean.setOffers(userEntity.getBeneficiary().getOffers()); userResponseBean.setMarketing(userEntity.getBeneficiary().getMarketing()); userResponseBean.setThirdParty(userEntity.getBeneficiary().getThirdParty()); userResponseBean.setEmailPec(userEntity.getBeneficiary().getEmailPec()); } return userResponseBean; } public UserResponseBean getUserById(Long id) { log.info("Fetching user with ID: {}", id); UserEntity userEntity = validateUser(id); // if (!UserStatusEnum.ACTIVE.getValue().equals(userEntity.getStatus())) { // log.info("User with ID: {} is not active", id); // throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); // } log.info("User found: {}", userEntity); return convertUserEntityToUserResponse(userEntity); } public void deleteUser(Long id) { log.info("Deleting user with ID: {}", id); validateUser(id); userRepository.deleteById(id); log.info("User deleted with ID: {}", id); } public JWTToken login(LoginReq loginReq) { log.info("User login attempt for email: {}", loginReq.getEmail()); JWTToken jwtToken = authService.login(loginReq); log.info("Login successful for email: {}", loginReq.getEmail()); return jwtToken; } public UserEntity validateUser(Long userId) { return userRepository.findById(userId) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); } public String initiatePasswordReset(InitiatePasswordResetReq resetReq) { UserEntity user = userRepository.findByEmail(resetReq.getEmail()); if (user == null) { log.info("Password reset attempt for non-existent user: {}", resetReq.getEmail()); throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); } String token = Utils.generateSecureToken(); user.setResetPasswordToken(token); userRepository.save(user); log.info("Password reset token generated for user: {}", resetReq.getEmail()); return token; } public Boolean resetPassword(ResetPasswordReq resetPasswordReq) { UserEntity user = userRepository.findByEmail(resetPasswordReq.getEmail()); if (user == null) { log.info("Password reset attempt for non-existent user: {}", resetPasswordReq.getEmail()); throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); } if (!resetPasswordReq.getNewPassword().equals(resetPasswordReq.getConfirmPassword())) { log.info("User creation failed: Passwords do not match for email {}", user.getEmail()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_DOESNT_MATCH)); } String dbToken = user.getResetPasswordToken(); if (dbToken == null || !dbToken.equals(resetPasswordReq.getToken())) { log.info("Invalid password reset token for user: {}", resetPasswordReq.getEmail()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_TOKEN_MSG)); } user.setPassword(passwordEncoder.encode(resetPasswordReq.getNewPassword())); user.setResetPasswordToken(null); userRepository.save(user); log.info("Password successfully reset for user: {}", resetPasswordReq.getEmail()); return true; } public Boolean changePassword(ChangePasswordRequest request) { UserEntity user = userRepository.findByEmail(request.getEmail()); if (user == null) { log.info("Password reset attempt for non-existent user: {}", request.getEmail()); throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); } if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.CURRENT_PASSWORD_INCORRECT)); } if (!request.getNewPassword().equals(request.getConfirmPassword())) { log.info("User creation failed: Passwords do not match for email {}", user.getEmail()); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_DOESNT_MATCH)); } user.setPassword(passwordEncoder.encode(request.getNewPassword())); userRepository.save(user); return true; } public void logout(HttpServletRequest request, HttpServletResponse response) { authService.logout(request, response); log.info("User successfully logged out."); } public UserResponseBean updateUserStatus(Long userId, UserStatusEnum statusReq) { log.info("Updating status for user with ID: {}", userId); UserEntity userEntity=validateUser(userId); userEntity.setStatus(statusReq.getValue()); userEntity = userRepository.save(userEntity); log.info("User status updated to {} for user ID: {}", statusReq, userId); return convertUserEntityToUserResponse(userEntity); } public JWTToken validateExistingUserToken(String token) { return authService.validateExistingUserToken(token); } public UserSamlResponse validateNewUserToken(String token) { return authService.validateNewUserToken(token); } }