283 lines
13 KiB
Java
283 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.LoginAttemptResultEnum;
|
|
import net.gepafin.tendermanagement.enums.LoginAttemptTypeEnum;
|
|
import net.gepafin.tendermanagement.enums.UserStatusEnum;
|
|
import net.gepafin.tendermanagement.enums.VersionActionTypeEnum;
|
|
import net.gepafin.tendermanagement.model.request.LoginReq;
|
|
import net.gepafin.tendermanagement.model.request.VersionHistoryRequest;
|
|
import net.gepafin.tendermanagement.model.response.CompanyResponse;
|
|
import net.gepafin.tendermanagement.model.response.LoginResponse;
|
|
import net.gepafin.tendermanagement.model.response.RoleResponseBean;
|
|
import net.gepafin.tendermanagement.model.response.UserSamlResponse;
|
|
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.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());
|
|
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());
|
|
user = userRepository.findByEmailIgnoreCaseAndHubUniqueUuid(loginReq.getEmail(), loginReq.getHubUuid())
|
|
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
|
|
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)));
|
|
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());
|
|
}
|
|
|
|
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) {
|
|
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);
|
|
|
|
/** 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());
|
|
} 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;
|
|
}
|
|
}
|
|
|