Files
bflows-bandi-be/src/main/java/net/gepafin/tendermanagement/service/impl/AuthenticationService.java

285 lines
13 KiB
Java

package net.gepafin.tendermanagement.service.impl;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.config.jwt.TokenProvider;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.dao.CompanyDao;
import net.gepafin.tendermanagement.dao.LoginAttemptDao;
import net.gepafin.tendermanagement.dao.RoleDao;
import net.gepafin.tendermanagement.entities.HubEntity;
import net.gepafin.tendermanagement.entities.LoginAttemptEntity;
import net.gepafin.tendermanagement.entities.SamlResponseEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.enums.*;
import net.gepafin.tendermanagement.model.request.LoginReq;
import net.gepafin.tendermanagement.model.request.VersionHistoryRequest;
import net.gepafin.tendermanagement.model.response.*;
import net.gepafin.tendermanagement.model.util.JWTToken;
import net.gepafin.tendermanagement.repositories.LoginAttemptRepository;
import net.gepafin.tendermanagement.repositories.SamlResponseRepository;
import net.gepafin.tendermanagement.repositories.UserRepository;
import net.gepafin.tendermanagement.service.HubService;
import net.gepafin.tendermanagement.util.DateTimeUtil;
import net.gepafin.tendermanagement.util.LoggingUtil;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Service
public class AuthenticationService {
private final Logger log = LoggerFactory.getLogger(AuthenticationService.class);
private final TokenProvider tokenProvider;
private final AuthenticationManager authenticationManager;
@Autowired
private CompanyDao companyDao;
@Autowired
private UserRepository userRepository;
@Autowired
private RoleDao roleDao;
@Autowired
private SamlResponseRepository samlResponseLogRepository;
@Autowired
private LoginAttemptDao loginAttemptDao;
@Autowired
private HubService hubService;
@Autowired
private HttpServletRequest request;
@Autowired
private LoggingUtil loggingUtil;
@Autowired
LoginAttemptRepository loginAttemptRepository;
@Autowired
public AuthenticationService(TokenProvider tokenProvider, AuthenticationManager authenticationManager) {
this.tokenProvider = tokenProvider;
this.authenticationManager = authenticationManager;
}
public JWTToken login(LoginReq loginReq, HttpServletRequest request) {
UserEntity user=null;
LoginAttemptEntity loginAttemptEntity = prepareLoginAttemptEntity(loginReq, request);
try {
log.info("Attempting login for email: {}", loginReq.getEmail());
user = userRepository.findUserExcludingRoleType(
loginReq.getEmail(),
loginReq.getHubUuid(),
RoleStatusEnum.ROLE_BENEFICIARY.getValue()
).orElseThrow(() -> new ResourceNotFoundException(
Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)
));
String emailWithHubId = loginReq.getEmail()+":"+loginReq.getHubUuid();
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
emailWithHubId, loginReq.getPassword());
Authentication authentication = this.authenticationManager.authenticate(authenticationToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
log.info("Authentication successful for email: {}", loginReq.getEmail());
loginAttemptEntity.setUserId(user.getId());
if (Boolean.FALSE.equals(UserStatusEnum.ACTIVE.getValue().equals(user.getStatus()))) {
throw new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG));
}
loginAttemptEntity.setUserId(user.getId());
createSuccessLoginAttempt(loginAttemptEntity);
} catch (Exception e) {
log.info("Authentication failed for email: {}", loginReq.getEmail());
loginAttemptEntity.setUserId(user.getId());
createFailedLoginAttempt(loginAttemptEntity, e.getMessage());
throw e;
}
return getJWTTokenBean(user, loginReq.getRememberMe(), loginAttemptEntity.getId(),null);
}
public LoginAttemptEntity prepareLoginAttemptEntity(LoginReq loginUserReq, HttpServletRequest request) {
String ipAddress = Utils.getClientIpAddress(request);
String userAgent = request.getHeader("user-agent");
LoginAttemptEntity loginAttemptEntity = new LoginAttemptEntity();
loginAttemptEntity.setType(LoginAttemptTypeEnum.LOGIN.getValue());
loginAttemptEntity.setUsername(loginUserReq.getEmail());
loginAttemptEntity.setIpAddress(ipAddress);
loginAttemptEntity.setUserAgent(userAgent);
return loginAttemptEntity;
}
public LoginAttemptEntity createSuccessLoginAttempt(LoginAttemptEntity loginAttemptEntity) {
loginAttemptEntity.setResult(LoginAttemptResultEnum.SUCCESS.getValue());
return loginAttemptDao.createLoginAttempt(loginAttemptEntity);
}
public void createFailedLoginAttempt(LoginAttemptEntity loginAttemptEntity, String errorMsg) {
loginAttemptEntity.setResult(LoginAttemptResultEnum.FAILED.getValue());
loginAttemptEntity.setErrorMsg(errorMsg);
loginAttemptDao.createLoginAttempt(loginAttemptEntity);
}
public JWTToken getJWTTokenBean(UserEntity user, Boolean rememberMe, Long loginAttemptId, List<EmailSendResponse> emailSendResponse) {
UserEntity oldUserEntity = Utils.getClonedEntityForData(user);
user.setLastLogin(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
user = userRepository.save(user);
String token = tokenProvider.createToken(rememberMe, user, loginAttemptId);
log.info("JWT token generated for email: {}", user.getEmail());
RoleResponseBean roleResponseBean = roleDao.convertRoleEntityToRoleResponse(user.getRoleEntity());
LoginResponse loginResponse = getLoginResponse(user, roleResponseBean);
JWTToken jwtToken = new JWTToken(token, loginResponse , emailSendResponse);
/** This code is responsible for adding a version history log for the "Create user Or Update user" operation. **/
loggingUtil.addVersionHistoryWithoutToken(VersionHistoryRequest.builder().request(request).oldData(oldUserEntity).newData(user).actionType(VersionActionTypeEnum.UPDATE).build());
log.info("Login successful for email: {}", user.getEmail());
return jwtToken;
}
private LoginResponse getLoginResponse(UserEntity user, RoleResponseBean roleResponseBean) {
LoginResponse loginResponse = new LoginResponse();
loginResponse.setEmail(user.getEmail());
loginResponse.setId(user.getId());
List<CompanyResponse> companyResponseBeans = companyDao.getCompanyByUserId(user.getId());
loginResponse.setCompanies(companyResponseBeans);
loginResponse.setRole(roleResponseBean);
loginResponse.setStatus(user.getStatus());
loginResponse.setLastLogin(user.getLastLogin());
loginResponse.setCreatedDate(user.getCreatedDate());
loginResponse.setUpdatedDate(user.getUpdatedDate());
if (user.getBeneficiary() == null) {
loginResponse.setFirstName(user.getFirstName());
loginResponse.setLastName(user.getLastName());
loginResponse.setPhoneNumber(user.getPhoneNumber());
loginResponse.setAddress(user.getAddress());
loginResponse.setOrganization(user.getOrganization());
loginResponse.setCountry(user.getCountry());
loginResponse.setCity(user.getCity());
loginResponse.setDateOfBirth(user.getDateOfBirth());
}else {
loginResponse.setFirstName(user.getBeneficiary().getFirstName());
loginResponse.setLastName(user.getBeneficiary().getLastName());
loginResponse.setPhoneNumber(user.getBeneficiary().getPhoneNumber());
loginResponse.setAddress(user.getBeneficiary().getAddress());
loginResponse.setOrganization(user.getBeneficiary().getOrganization());
loginResponse.setCountry(user.getBeneficiary().getCountry());
loginResponse.setCity(user.getBeneficiary().getCity());
loginResponse.setCodiceFiscale(user.getBeneficiary().getCodiceFiscale());
loginResponse.setDateOfBirth(user.getBeneficiary().getDateOfBirth());
loginResponse.setPrivacy(user.getBeneficiary().getPrivacy());
loginResponse.setMarketing(user.getBeneficiary().getMarketing());
loginResponse.setOffers(user.getBeneficiary().getOffers());
loginResponse.setTerms(user.getBeneficiary().getTerms());
loginResponse.setThirdParty(user.getBeneficiary().getThirdParty());
loginResponse.setEmailPec(user.getBeneficiary().getEmailPec());
}
return loginResponse;
}
public void logout(HttpServletRequest request, HttpServletResponse response) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
new SecurityContextLogoutHandler().logout(request, response, auth);
}
SecurityContextHolder.getContext().setAuthentication(null);
SecurityContextHolder.clearContext();
}
public JWTToken validateExistingUserToken(HttpServletRequest request,String token) {
SamlResponseEntity samlResponseLogEntity = samlResponseLogRepository.findByToken(token);
if (samlResponseLogEntity == null) {
log.info("Invalid spid login token : {}", token);
throw new CustomValidationException(Status.VALIDATION_ERROR,
Translator.toLocale(GepafinConstant.INVALID_TOKEN_MSG));
}
LoginReq loginReq=new LoginReq();
Long userId=null;
LoginAttemptEntity loginAttemptEntity =new LoginAttemptEntity();
try {
HubEntity hub = hubService.getHubByUuid(samlResponseLogEntity.getHubUuid());
Map<String, List<Object>> userAttributes = Utils
.convertStringIntoMap(samlResponseLogEntity.getAuthenticationObject());
String cf = userAttributes.get("CodiceFiscale").get(0).toString();
UserEntity userEntity = userRepository.findByBeneficiaryCodiceFiscaleAndHubId(cf, hub.getId())
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)));
userId=userEntity.getId();
//samlResponseLogRepository.delete(samlResponseLogEntity);
loginReq.setEmail(userEntity.getEmail());
loginAttemptEntity = prepareLoginAttemptEntity(loginReq, request);
loginAttemptEntity.setUserId(userEntity.getId());
LoginAttemptEntity loginAttempt = createSuccessLoginAttempt(loginAttemptEntity);
return getJWTTokenBean(userEntity, Boolean.TRUE, loginAttempt.getId(),null);
} catch (Exception e) {
log.info("Authentication login failed for email: {}",e.getMessage());
loginAttemptEntity.setUserId(userId);
createFailedLoginAttempt(loginAttemptEntity, e.getMessage());
throw e;
}
}
public UserSamlResponse validateNewUserToken(String token) {
SamlResponseEntity samlResponseLogEntity = samlResponseLogRepository.findByToken(token);
if (samlResponseLogEntity == null) {
log.info("Invalid spid login token : {}", token);
throw new CustomValidationException(Status.VALIDATION_ERROR,
Translator.toLocale(GepafinConstant.INVALID_TOKEN_MSG));
}
HubEntity hub = hubService.getHubByUuid(samlResponseLogEntity.getHubUuid());
Map<String, List<Object>> userAttributes = Utils
.convertStringIntoMap(samlResponseLogEntity.getAuthenticationObject());
String cf = userAttributes.get("CodiceFiscale").get(0).toString();
if (userRepository.existsByBeneficiaryCodiceFiscaleAndHubId(cf, hub.getId())) {
throw new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.USER_ALREADY_EXIST_MSG));
}
UserSamlResponse userSamlResponse = new UserSamlResponse();
userSamlResponse.setCodiceFiscale(cf);
if (userAttributes.containsKey("nome") && userAttributes.get("nome") != null
&& !userAttributes.get("nome").isEmpty()) {
userSamlResponse.setFirstName(userAttributes.get("nome").get(0).toString());
}
if (userAttributes.containsKey("cognome") && userAttributes.get("cognome") != null
&& !userAttributes.get("cognome").isEmpty()) {
userSamlResponse.setLastName(userAttributes.get("cognome").get(0).toString());
}
if (userAttributes.containsKey("dataNascita") && userAttributes.get("dataNascita") != null
&& !userAttributes.get("dataNascita").isEmpty()) {
String dateString =userAttributes.get("dataNascita").get(0).toString();
LocalDate dateOfBirth = LocalDate.parse(dateString);
LocalDateTime dateOfBirthWithTime = dateOfBirth.atStartOfDay();
userSamlResponse.setDateOfBirth(dateOfBirthWithTime);
}
userSamlResponse.setCodiceFiscale(cf);
return userSamlResponse;
}
}