resolved conflict

This commit is contained in:
nisha
2024-09-25 21:43:36 +05:30
24 changed files with 412 additions and 150 deletions

View File

@@ -4,23 +4,21 @@ import java.io.IOException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import net.gepafin.tendermanagement.entities.SamlResponseLogEntity;
import net.gepafin.tendermanagement.repositories.SamlResponseLogRepository;
@Component @Component
public class SamlFailureHandler implements AuthenticationFailureHandler { public class SamlFailureHandler implements AuthenticationFailureHandler {
private final Logger logger = LoggerFactory.getLogger(SamlSuccessHandler.class); private final Logger logger = LoggerFactory.getLogger(SamlSuccessHandler.class);
@Autowired @Value("fe.base.url")
private SamlResponseLogRepository samlResponseLogRepository; private String feBaseUrl;
@Override @Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
@@ -28,15 +26,7 @@ public class SamlFailureHandler implements AuthenticationFailureHandler {
try { try {
logger.error("SAML login failed: " + exception.getMessage()); logger.error("SAML login failed: " + exception.getMessage());
// Log the failure details to the database (Optional) response.sendRedirect(feBaseUrl + "/login");
SamlResponseLogEntity samlResponseLogEntity = new SamlResponseLogEntity();
samlResponseLogEntity.setRequest(request.toString());
samlResponseLogEntity.setResponse(response.toString());
samlResponseLogEntity.setExceptionObject(exception.toString());
samlResponseLogRepository.save(samlResponseLogEntity);
// Handle failure redirection
response.sendRedirect("http://gepafin-staging-fe.s3-website.eu-central-1.amazonaws.com/login");
} catch (Exception e) { } catch (Exception e) {
logger.error("Error processing SAML failure handler", e); logger.error("Error processing SAML failure handler", e);
} }

View File

@@ -7,6 +7,7 @@ import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal; import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication; import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
@@ -17,48 +18,80 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import net.gepafin.tendermanagement.entities.SamlResponseLogEntity; import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.repositories.SamlResponseLogRepository; import net.gepafin.tendermanagement.entities.SamlResponseEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.repositories.SamlResponseRepository;
import net.gepafin.tendermanagement.repositories.UserRepository;
import net.gepafin.tendermanagement.util.Utils;
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
@Component @Component
public class SamlSuccessHandler implements AuthenticationSuccessHandler{ public class SamlSuccessHandler implements AuthenticationSuccessHandler {
private final Logger logger = LoggerFactory.getLogger(SamlSuccessHandler.class); private final Logger logger = LoggerFactory.getLogger(SamlSuccessHandler.class);
@Autowired
private SamlResponseLogRepository samlResponseLogRepository;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException {
try {
// Cast the authentication object to Saml2Authentication
Saml2Authentication samlAuth = (Saml2Authentication) authentication;
Saml2AuthenticatedPrincipal principal = (Saml2AuthenticatedPrincipal) samlAuth.getPrincipal();
// Extract the user attributes from the principal @Autowired
Map<String, List<Object>> userAttributes = principal.getAttributes(); private SamlResponseRepository samlResponseLogRepository;
// Log the user attributes for debugging purposes @Autowired
logger.info("SAML User Attributes: " + userAttributes); private UserRepository userRepository;
// Save the authentication details in the database (Optional) @Value("${fe.base.url}")
SamlResponseLogEntity samlResponseLogEntity = new SamlResponseLogEntity(); private String feBaseUrl;
samlResponseLogEntity.setAuthenticationObject(authentication.toString());
// Convert user attributes to JSON and save in DB @Override
ObjectMapper objectMapper = new ObjectMapper(); public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
String userAttributesJson = objectMapper.writeValueAsString(userAttributes); Authentication authentication) throws IOException {
samlResponseLogEntity.setAuthenticationObject(userAttributesJson); try {
samlResponseLogRepository.save(samlResponseLogEntity); Saml2Authentication samlAuth = (Saml2Authentication) authentication;
Saml2AuthenticatedPrincipal principal = (Saml2AuthenticatedPrincipal) samlAuth.getPrincipal();
// Successful login logic Map<String, List<Object>> userAttributes = principal.getAttributes();
logger.info("SAML login successful for user: " + principal.getName()); String token = Utils.generateSecureToken();
response.sendRedirect("http://gepafin-staging-fe.s3-website.eu-central-1.amazonaws.com/login"); logger.info("SAML User Attributes: " + userAttributes);
} catch (Exception e) {
logger.error("Error processing SAML success handler", e); SamlResponseEntity samlResponseLogEntity = new SamlResponseEntity();
} samlResponseLogEntity.setAuthenticationObject(authentication.toString());
}
ObjectMapper objectMapper = new ObjectMapper();
String userAttributesJson = objectMapper.writeValueAsString(userAttributes);
samlResponseLogEntity.setAuthenticationObject(userAttributesJson);
samlResponseLogEntity.setToken(token);
samlResponseLogRepository.save(samlResponseLogEntity);
String redirectUrl = feBaseUrl;
logger.info("SAML login successful for user: " + principal.getName());
String cf = userAttributes.get("CodiceFiscale").get(0).toString();
UserEntity userEntity = userRepository.findByCodiceFiscale(cf).orElse(null);
if (userEntity == null) {
redirectUrl += "/registration?temp_token=" + token;
} else {
redirectUrl += "/login?temp_token=" + token;
}
response.sendRedirect(redirectUrl);
logger.info("SAML redirect Url: " + redirectUrl);
} catch (Exception e) {
logger.error("Error processing SAML success handler", e);
}
}
public void validateToken(String token, String codiceFiscale) {
SamlResponseEntity samlResponseLogEntity = samlResponseLogRepository.findByToken(token);
if (samlResponseLogEntity == null) {
throw new CustomValidationException(Status.VALIDATION_ERROR,
Translator.toLocale(GepafinConstant.INVALID_TOKEN_MSG));
}
Map<String, List<Object>> userAttributes = Utils
.convertStringIntoMap(samlResponseLogEntity.getAuthenticationObject());
String cf = userAttributes.get("CodiceFiscale").get(0).toString();
if (codiceFiscale == null || Boolean.FALSE.equals(codiceFiscale.equals(cf))) {
throw new CustomValidationException(Status.VALIDATION_ERROR,
Translator.toLocale(GepafinConstant.INVALID_TOKEN_MSG));
}
samlResponseLogRepository.delete(samlResponseLogEntity);
}
} }

View File

@@ -99,6 +99,9 @@ public class SecurityConfig {
http.csrf(AbstractHttpConfigurer::disable).authorizeHttpRequests(auth -> auth http.csrf(AbstractHttpConfigurer::disable).authorizeHttpRequests(auth -> auth
// Allow public access to the login endpoints // Allow public access to the login endpoints
.requestMatchers("/v1/user/login").permitAll() // JWT-based login .requestMatchers("/v1/user/login").permitAll() // JWT-based login
.requestMatchers("/v1/user").permitAll() // User registration
.requestMatchers("/v1/user/sso/validate/existing-user/{token}").permitAll()
.requestMatchers("/v1/user/sso/validate/new-user/{token}").permitAll()
.requestMatchers("/v1/saml/**").permitAll() // JWT-based login .requestMatchers("/v1/saml/**").permitAll() // JWT-based login
.requestMatchers("/saml2/**").permitAll() // SAML login initiation .requestMatchers("/saml2/**").permitAll() // SAML login initiation
.requestMatchers("/swagger-ui/**").permitAll() // Swagger docs .requestMatchers("/swagger-ui/**").permitAll() // Swagger docs

View File

@@ -82,10 +82,11 @@ public class TokenProvider {
log.info("JWT Secret Key initialized."); log.info("JWT Secret Key initialized.");
} }
public String createToken(Authentication authentication, Boolean rememberMe, UserEntity user) { public String createToken(Boolean rememberMe, UserEntity user) {
String authorities = authentication.getAuthorities().stream() // String authorities = authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority) // .map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(",")); // .collect(Collectors.joining(","));
String authorities = user.getRoleEntity().getRoleType();
Long now; Long now;
Date validity; Date validity;
@@ -99,7 +100,7 @@ public class TokenProvider {
log.info("Creating token with standard validity of {} seconds.", this.tokenValidityInSeconds); log.info("Creating token with standard validity of {} seconds.", this.tokenValidityInSeconds);
} }
String payload = authentication.getName(); String payload = user.getEmail();
if(user != null) { if(user != null) {
payload += ":"+user.getId(); payload += ":"+user.getId();
} }

View File

@@ -156,6 +156,10 @@ public class GepafinConstant {
public static final String IS_CODICE_FISCALE="isCodiceFiscale"; public static final String IS_CODICE_FISCALE="isCodiceFiscale";
public static final String IS_PIVA="isPIVA"; public static final String IS_PIVA="isPIVA";
public static final String FAILED_RETAIN_FIELD="failed.retain.field"; public static final String FAILED_RETAIN_FIELD="failed.retain.field";
public static final String USER_ALREADY_EXIST_MSG = "user.already.exist.msg";
public static final String TOKEN_VALIDATE_SUCCESS_MSE = "token.validate.success";
public static final String INVALID_REQUEST = "invalid.request";
public static final String CODICE_FISCALE_EXISTS = "codice.fiscale.exists";
public static final String TOTAL_STEPS_NOT_BE_ZERO="total.steps.not.zero"; public static final String TOTAL_STEPS_NOT_BE_ZERO="total.steps.not.zero";
public static final String COMPLETED_STEPS_NOT_VALID="completed.steps.not.valid"; public static final String COMPLETED_STEPS_NOT_VALID="completed.steps.not.valid";
public static final String FIELD_ID_NOT_FOUND="field.id.not.found"; public static final String FIELD_ID_NOT_FOUND="field.id.not.found";

View File

@@ -9,20 +9,22 @@ import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum;
import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.request.*;
import net.gepafin.tendermanagement.model.response.RoleResponseBean; 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.response.UserResponseBean;
import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.model.util.JWTToken;
import net.gepafin.tendermanagement.repositories.UserRepository; import net.gepafin.tendermanagement.repositories.UserRepository;
import net.gepafin.tendermanagement.service.impl.AuthenticationService; 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.CustomValidationException;
import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException;
import net.gepafin.tendermanagement.web.rest.api.errors.Status; import net.gepafin.tendermanagement.web.rest.api.errors.Status;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.security.SecureRandom;
import java.util.Base64;
import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated;
@@ -43,24 +45,32 @@ public class UserDao {
@Autowired @Autowired
private RoleDao roleDao; private RoleDao roleDao;
public UserResponseBean createUser(UserReq userReq) { public JWTToken createUser(HttpServletRequest request, String tempToken, UserReq userReq) {
log.info("Creating user with email: {}", userReq.getEmail()); log.info("Creating user with email: {}", userReq.getEmail());
if (userRepository.existsByEmailIgnoreCase(userReq.getEmail())) { if (userRepository.existsByEmailIgnoreCase(userReq.getEmail())) {
log.error("User creation failed: Email {} already exists", userReq.getEmail()); log.error("User creation failed: Email {} already exists", userReq.getEmail());
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.EMAIL_ALREADY_EXISTS)); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.EMAIL_ALREADY_EXISTS));
} }
if (!userReq.getPassword().equals(userReq.getConfPassword())) { if (Boolean.FALSE.equals(StringUtils.isEmpty(userReq.getCodiceFiscale())) && userRepository.existsByCodiceFiscale(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 && (StringUtils.isEmpty(userReq.getPassword()) || StringUtils.isEmpty(userReq.getConfPassword()))) {
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_REQUEST));
}
if (tempToken == null && !userReq.getPassword().equals(userReq.getConfPassword())) {
log.error("User creation failed: Passwords do not match for email {}", userReq.getEmail()); log.error("User creation failed: Passwords do not match for email {}", userReq.getEmail());
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_DOESNT_MATCH)); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_DOESNT_MATCH));
} }
if (userReq.getPassword().length() < 8) { if (tempToken == null && userReq.getPassword().length() < 8) {
log.error("User creation failed: Password length is less than 8 characters for email {}", userReq.getEmail()); log.error("User creation failed: Password length is less than 8 characters for email {}", userReq.getEmail());
throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_MIN_LEN)); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.PASSWORD_MIN_LEN));
} }
UserEntity userEntity = convertUserRequestToUserEntity(userReq); UserEntity userEntity = convertUserRequestToUserEntity(userReq);
userEntity = userRepository.save(userEntity); userEntity = userRepository.save(userEntity);
log.info("User created with ID: {}", userEntity.getId()); log.info("User created with ID: {}", userEntity.getId());
return convertUserEntityToUserResponse(userEntity); return authService.getJWTTokenBean(userEntity, Boolean.TRUE);
} }
public UserResponseBean updateUser(Long userId, UpdateUserReq userReq) { public UserResponseBean updateUser(Long userId, UpdateUserReq userReq) {
@@ -88,15 +98,18 @@ public class UserDao {
private UserEntity convertUserRequestToUserEntity(UserReq userReq) { private UserEntity convertUserRequestToUserEntity(UserReq userReq) {
UserEntity userEntity = new UserEntity(); UserEntity userEntity = new UserEntity();
userEntity.setPassword(passwordEncoder.encode(userReq.getPassword())); if(Boolean.FALSE.equals(StringUtils.isEmpty(userReq.getPassword()))) {
userEntity.setPassword(passwordEncoder.encode(userReq.getPassword()));
}
userEntity.setEmail(userReq.getEmail()); userEntity.setEmail(userReq.getEmail());
userEntity.setFirstName(userReq.getFirstName()); userEntity.setFirstName(userReq.getFirstName());
userEntity.setStatus(UserStatusEnum.PENDING_VERIFICATION.getValue()); userEntity.setStatus(UserStatusEnum.ACTIVE.getValue());
userEntity.setLastName(userReq.getLastName()); userEntity.setLastName(userReq.getLastName());
userEntity.setOrganization(userReq.getOrganization()); userEntity.setOrganization(userReq.getOrganization());
userEntity.setAddress(userReq.getAddress()); userEntity.setAddress(userReq.getAddress());
userEntity.setPhoneNumber(userReq.getPhoneNumber()); userEntity.setPhoneNumber(userReq.getPhoneNumber());
userEntity.setRoleEntity(roleDao.validateRole(userReq.getRoleId())); userEntity.setRoleEntity(roleDao.validateRole(userReq.getRoleId()));
userEntity.setCodiceFiscale(userReq.getCodiceFiscale());
return userEntity; return userEntity;
} }
@@ -150,14 +163,6 @@ public class UserDao {
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)));
} }
public String generateSecureToken() {
SecureRandom secureRandom = new SecureRandom();
byte[] tokenBytes = new byte[24];
secureRandom.nextBytes(tokenBytes);
String token = Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes);
log.debug("Generated secure token: {}", token);
return token;
}
public String initiatePasswordReset(InitiatePasswordResetReq resetReq) { public String initiatePasswordReset(InitiatePasswordResetReq resetReq) {
UserEntity user = userRepository.findByEmail(resetReq.getEmail()); UserEntity user = userRepository.findByEmail(resetReq.getEmail());
@@ -165,7 +170,7 @@ public class UserDao {
log.info("Password reset attempt for non-existent user: {}", resetReq.getEmail()); log.info("Password reset attempt for non-existent user: {}", resetReq.getEmail());
throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG));
} }
String token = generateSecureToken(); String token = Utils.generateSecureToken();
user.setResetPasswordToken(token); user.setResetPasswordToken(token);
userRepository.save(user); userRepository.save(user);
log.info("Password reset token generated for user: {}", resetReq.getEmail()); log.info("Password reset token generated for user: {}", resetReq.getEmail());
@@ -227,4 +232,12 @@ public class UserDao {
return convertUserEntityToUserResponse(userEntity); return convertUserEntityToUserResponse(userEntity);
} }
public JWTToken validateExistingUserToken(String token) {
return authService.validateExistingUserToken(token);
}
public UserSamlResponse validateNewUserToken(String token) {
return authService.validateNewUserToken(token);
}
} }

View File

@@ -6,21 +6,15 @@ import jakarta.persistence.Table;
import lombok.Data; import lombok.Data;
@Entity @Entity
@Table(name = "SAML_RESPONSE_LOG") @Table(name = "SAML_RESPONSE")
@Data @Data
public class SamlResponseLogEntity extends BaseEntity{ public class SamlResponseEntity extends BaseEntity{
@Column(name = "REQUEST")
private String request;
@Column(name = "RESPONSE")
private String response;
@Column(name = "AUTHENTICATION_OBJECT") @Column(name = "AUTHENTICATION_OBJECT")
private String authenticationObject; private String authenticationObject;
@Column(name = "EXCEPTION_OBJECT") @Column(name = "TOKEN")
private String exceptionObject; private String token;
} }

View File

@@ -1,6 +1,5 @@
package net.gepafin.tendermanagement.entities; package net.gepafin.tendermanagement.entities;
import com.fasterxml.jackson.annotation.JsonValue;
import jakarta.persistence.*; import jakarta.persistence.*;
import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Email;
@@ -17,7 +16,7 @@ import java.time.LocalDateTime;
@Setter @Setter
public class UserEntity extends BaseEntity { public class UserEntity extends BaseEntity {
@Column(name = "PASSWORD", columnDefinition = "TEXT",nullable = false) @Column(name = "PASSWORD", columnDefinition = "TEXT",nullable = true)
@JsonIgnore @JsonIgnore
private String password; private String password;
@@ -29,8 +28,7 @@ public class UserEntity extends BaseEntity {
@JoinColumn(name = "ROLE_ID") @JoinColumn(name = "ROLE_ID")
@JsonIgnore @JsonIgnore
private RoleEntity roleEntity; private RoleEntity roleEntity;
@Column(name = "LAST_LOGIN") @Column(name = "LAST_LOGIN")
private LocalDateTime lastLogin; private LocalDateTime lastLogin;
@@ -60,4 +58,7 @@ public class UserEntity extends BaseEntity {
@Column(name = "RESET_PASSWORD_TOKEN", length = 255, nullable = true) @Column(name = "RESET_PASSWORD_TOKEN", length = 255, nullable = true)
private String resetPasswordToken; private String resetPasswordToken;
@Column(name = "CODICE_FISCALE")
private String codiceFiscale;
} }

View File

@@ -2,7 +2,6 @@ package net.gepafin.tendermanagement.model.request;
import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
@@ -12,9 +11,9 @@ public class UserReq {
@NotBlank @NotBlank
@Email @Email
private String email; private String email;
@NotEmpty
private String password; private String password;
@NotEmpty
private String confPassword; private String confPassword;
private String firstName; private String firstName;
@@ -32,5 +31,7 @@ public class UserReq {
private String city; private String city;
private String country; private String country;
private String codiceFiscale;
} }

View File

@@ -0,0 +1,13 @@
package net.gepafin.tendermanagement.model.response;
import lombok.Data;
@Data
public class UserSamlResponse {
private String codiceFiscale;
private String firstName;
private String lastName;
}

View File

@@ -1,11 +0,0 @@
package net.gepafin.tendermanagement.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import net.gepafin.tendermanagement.entities.SamlResponseLogEntity;
@Repository
public interface SamlResponseLogRepository extends JpaRepository<SamlResponseLogEntity, Long> {
}

View File

@@ -0,0 +1,13 @@
package net.gepafin.tendermanagement.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import net.gepafin.tendermanagement.entities.SamlResponseEntity;
@Repository
public interface SamlResponseRepository extends JpaRepository<SamlResponseEntity, Long> {
SamlResponseEntity findByToken(String token);
}

View File

@@ -6,7 +6,14 @@ import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional; import java.util.Optional;
public interface UserRepository extends JpaRepository<UserEntity, Long> { public interface UserRepository extends JpaRepository<UserEntity, Long> {
Optional<UserEntity> findByEmailIgnoreCase(String email); Optional<UserEntity> findByEmailIgnoreCase(String email);
boolean existsByEmailIgnoreCase(String email); boolean existsByEmailIgnoreCase(String email);
UserEntity findByEmail(String email); UserEntity findByEmail(String email);
Optional<UserEntity> findByCodiceFiscale(String cf);
boolean existsByCodiceFiscale(String codiceFiscale);
} }

View File

@@ -8,11 +8,12 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum;
import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.request.*;
import net.gepafin.tendermanagement.model.response.UserSamlResponse;
import net.gepafin.tendermanagement.model.response.UserResponseBean; import net.gepafin.tendermanagement.model.response.UserResponseBean;
import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.model.util.JWTToken;
public interface UserService { public interface UserService {
UserResponseBean createUser(UserReq userReq); JWTToken createUser(HttpServletRequest request, String tempToken, UserReq userReq);
UserResponseBean updateUser(Long userId, UpdateUserReq userReq); UserResponseBean updateUser(Long userId, UpdateUserReq userReq);
@@ -35,4 +36,8 @@ public interface UserService {
UserResponseBean updateUserStatus(Long userId, UserStatusEnum statusReq); UserResponseBean updateUserStatus(Long userId, UserStatusEnum statusReq);
UserResponseBean getValidUser(HttpServletRequest request); UserResponseBean getValidUser(HttpServletRequest request);
JWTToken validateExistingUserToken(HttpServletRequest request, String token);
UserSamlResponse validateNewUserToken(HttpServletRequest request, String token);
} }

View File

@@ -6,15 +6,20 @@ import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.config.jwt.TokenProvider; import net.gepafin.tendermanagement.config.jwt.TokenProvider;
import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.dao.RoleDao; import net.gepafin.tendermanagement.dao.RoleDao;
import net.gepafin.tendermanagement.entities.SamlResponseEntity;
import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum;
import net.gepafin.tendermanagement.model.request.LoginReq; import net.gepafin.tendermanagement.model.request.LoginReq;
import net.gepafin.tendermanagement.model.response.LoginResponse; import net.gepafin.tendermanagement.model.response.LoginResponse;
import net.gepafin.tendermanagement.model.response.RoleResponseBean; 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.model.util.JWTToken;
import net.gepafin.tendermanagement.repositories.SamlResponseRepository;
import net.gepafin.tendermanagement.repositories.UserRepository; import net.gepafin.tendermanagement.repositories.UserRepository;
import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.DateTimeUtil;
import net.gepafin.tendermanagement.util.Utils;
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; 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 net.gepafin.tendermanagement.web.rest.api.errors.Status;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -27,6 +32,8 @@ import org.springframework.security.web.authentication.logout.SecurityContextLog
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Service @Service
public class AuthenticationService { public class AuthenticationService {
@@ -41,6 +48,9 @@ public class AuthenticationService {
@Autowired @Autowired
private RoleDao roleDao; private RoleDao roleDao;
@Autowired
private SamlResponseRepository samlResponseLogRepository;
@Autowired @Autowired
public AuthenticationService(TokenProvider tokenProvider, AuthenticationManager authenticationManager) { public AuthenticationService(TokenProvider tokenProvider, AuthenticationManager authenticationManager) {
@@ -55,27 +65,32 @@ public class AuthenticationService {
Authentication authentication = this.authenticationManager.authenticate(authenticationToken); Authentication authentication = this.authenticationManager.authenticate(authenticationToken);
SecurityContextHolder.getContext().setAuthentication(authentication); SecurityContextHolder.getContext().setAuthentication(authentication);
log.info("Authentication successful for email: {}", loginReq.getEmail()); log.info("Authentication successful for email: {}", loginReq.getEmail());
UserEntity user = userRepository.findByEmailIgnoreCase(loginReq.getEmail()).orElseThrow(()-> new CustomValidationException(Status.NOT_FOUND, UserEntity user = userRepository.findByEmailIgnoreCase(loginReq.getEmail())
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG))); .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
if (Boolean.FALSE.equals(UserStatusEnum.ACTIVE.getValue().equals(user.getStatus()))) { Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)));
throw new CustomValidationException(Status.NOT_FOUND, if (Boolean.FALSE.equals(UserStatusEnum.ACTIVE.getValue().equals(user.getStatus()))) {
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)); throw new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG));
} }
return getJWTTokenBean(user, loginReq.getRememberMe());
}
public JWTToken getJWTTokenBean(UserEntity user, Boolean rememberMe) {
user.setLastLogin(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); user.setLastLogin(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
userRepository.save(user); userRepository.save(user);
String token = tokenProvider.createToken(authentication, loginReq.getRememberMe(), user); String token = tokenProvider.createToken(rememberMe, user);
log.info("JWT token generated for email: {}", loginReq.getEmail()); log.info("JWT token generated for email: {}", user.getEmail());
RoleResponseBean roleResponseBean = roleDao.convertRoleEntityToRoleResponse(user.getRoleEntity()); RoleResponseBean roleResponseBean = roleDao.convertRoleEntityToRoleResponse(user.getRoleEntity());
LoginResponse loginResponse = getLoginResponse(user, roleResponseBean); LoginResponse loginResponse = getLoginResponse(user, roleResponseBean);
JWTToken jwtToken = new JWTToken(token, loginResponse); JWTToken jwtToken = new JWTToken(token, loginResponse);
log.info("Login successful for email: {}", loginReq.getEmail()); log.info("Login successful for email: {}", user.getEmail());
return jwtToken; return jwtToken;
} }
private static LoginResponse getLoginResponse(UserEntity user, RoleResponseBean roleResponseBean) { private static LoginResponse getLoginResponse(UserEntity user, RoleResponseBean roleResponseBean) {
LoginResponse loginResponse = new LoginResponse(); LoginResponse loginResponse = new LoginResponse();
loginResponse.setId(user.getId()); loginResponse.setId(user.getId());
loginResponse.setEmail(user.getEmail()); loginResponse.setEmail(user.getEmail());
@@ -93,8 +108,8 @@ public class AuthenticationService {
loginResponse.setUpdatedDate(user.getUpdatedDate()); loginResponse.setUpdatedDate(user.getUpdatedDate());
return loginResponse; return loginResponse;
} }
public void logout(HttpServletRequest request, HttpServletResponse response) public void logout(HttpServletRequest request, HttpServletResponse response) {
{ Authentication auth = SecurityContextHolder.getContext().getAuthentication(); Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) { if (auth != null) {
String token = tokenProvider.extractTokenFromRequest(request); String token = tokenProvider.extractTokenFromRequest(request);
tokenProvider.invalidateToken(token); tokenProvider.invalidateToken(token);
@@ -102,6 +117,53 @@ public class AuthenticationService {
} }
SecurityContextHolder.getContext().setAuthentication(null); SecurityContextHolder.getContext().setAuthentication(null);
SecurityContextHolder.clearContext(); SecurityContextHolder.clearContext();
} }
public JWTToken validateExistingUserToken(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));
}
Map<String, List<Object>> userAttributes = Utils
.convertStringIntoMap(samlResponseLogEntity.getAuthenticationObject());
String cf = userAttributes.get("CodiceFiscale").get(0).toString();
UserEntity userEntity = userRepository.findByCodiceFiscale(cf)
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.USER_NOT_FOUND_MSG)));
samlResponseLogRepository.delete(samlResponseLogEntity);
return getJWTTokenBean(userEntity, Boolean.TRUE);
}
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));
}
Map<String, List<Object>> userAttributes = Utils
.convertStringIntoMap(samlResponseLogEntity.getAuthenticationObject());
String cf = userAttributes.get("CodiceFiscale").get(0).toString();
if (userRepository.findByCodiceFiscale(cf).isPresent()) {
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());
}
userSamlResponse.setCodiceFiscale(cf);
return userSamlResponse;
}
} }

View File

@@ -2,22 +2,25 @@ package net.gepafin.tendermanagement.service.impl;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import net.gepafin.tendermanagement.config.jwt.TokenProvider; import net.gepafin.tendermanagement.config.SamlSuccessHandler;
import net.gepafin.tendermanagement.dao.UserDao; import net.gepafin.tendermanagement.dao.UserDao;
import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.model.request.LoginReq; import net.gepafin.tendermanagement.model.request.LoginReq;
import net.gepafin.tendermanagement.model.request.UpdateUserReq; import net.gepafin.tendermanagement.model.request.UpdateUserReq;
import net.gepafin.tendermanagement.model.request.UserReq; import net.gepafin.tendermanagement.model.request.UserReq;
import net.gepafin.tendermanagement.enums.RoleStatusEnum;
import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum;
import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.request.*;
import net.gepafin.tendermanagement.model.response.UserSamlResponse;
import net.gepafin.tendermanagement.model.response.UserResponseBean; import net.gepafin.tendermanagement.model.response.UserResponseBean;
import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.model.util.JWTToken;
import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.service.UserService;
import net.gepafin.tendermanagement.util.Validator;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Map;
@Service @Service
@@ -25,12 +28,21 @@ public class UserServiceImpl implements UserService {
@Autowired @Autowired
private UserDao userDao; private UserDao userDao;
@Autowired @Autowired
private TokenProvider tokenProvider; private Validator validator;
@Autowired
private SamlSuccessHandler samlSuccessHandler;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public UserResponseBean createUser(UserReq userReq) { public JWTToken createUser(HttpServletRequest request, String tempToken, UserReq userReq) {
return userDao.createUser(userReq); if (tempToken == null) {
validator.validateRequest(request,RoleStatusEnum.ROLE_SUPER_ADMIN);
}else {
samlSuccessHandler.validateToken(tempToken, userReq.getCodiceFiscale());
}
return userDao.createUser(request, tempToken, userReq);
} }
@@ -89,8 +101,17 @@ public class UserServiceImpl implements UserService {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public UserResponseBean getValidUser(HttpServletRequest request) { public UserResponseBean getValidUser(HttpServletRequest request) {
Map<String, Object> userInfo= tokenProvider.getUserInfoAndUserIdFromToken(request); UserEntity user=validator.validateUser(request);
UserEntity user=tokenProvider.validateUser(userInfo);
return userDao.getUserById(user.getId()); return userDao.getUserById(user.getId());
} }
@Override
@Transactional(rollbackFor = Exception.class)
public JWTToken validateExistingUserToken(HttpServletRequest request, String token) {
return userDao.validateExistingUserToken(token);
}
@Override
public UserSamlResponse validateNewUserToken(HttpServletRequest request, String token) {
return userDao.validateNewUserToken(token);
}
} }

View File

@@ -15,6 +15,7 @@ import org.slf4j.LoggerFactory;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64; import java.util.Base64;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -161,4 +162,32 @@ public class Utils {
} }
} }
} }
public static String encodeData(String data) {
return Base64.getEncoder().encodeToString(data.getBytes(StandardCharsets.UTF_8));
}
public static String decodeData(String token) {
byte[] decodedBytes = Base64.getDecoder().decode(token);
return new String(decodedBytes, StandardCharsets.UTF_8);
}
public static String generateSecureToken() {
SecureRandom secureRandom = new SecureRandom();
byte[] tokenBytes = new byte[24];
secureRandom.nextBytes(tokenBytes);
String token = Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes);
log.debug("Generated secure token: {}", token);
return token;
}
public static Map<String, List<Object>> convertStringIntoMap(String jsonString) {
try {
return mapper.readValue(jsonString, new TypeReference<Map<String, List<Object>>>() {
});
} catch (Exception e) {
log.error("Error converting object: " + e.getMessage(), e);
return null;
}
}
} }

View File

@@ -1,11 +1,19 @@
package net.gepafin.tendermanagement.util; package net.gepafin.tendermanagement.util;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.config.jwt.TokenProvider; import net.gepafin.tendermanagement.config.jwt.TokenProvider;
import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.enums.RoleStatusEnum;
import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.service.UserService;
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
import net.gepafin.tendermanagement.web.rest.api.errors.UnauthorizedAccessException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Map; import java.util.Map;
@@ -28,4 +36,24 @@ public class Validator {
return userService.validateUser(Long.parseLong(userInfo.get("userId").toString())); return userService.validateUser(Long.parseLong(userInfo.get("userId").toString()));
} }
public Boolean checkIsSuperAdmin(HttpServletRequest request) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
// Check if the user has the ROLE_SUPER_ADMIN authority
for (GrantedAuthority authority : authentication.getAuthorities()) {
if (RoleStatusEnum.ROLE_SUPER_ADMIN.getValue().equals(authority.getAuthority())) {
return true;
}
}
}
return false;
}
public void validateRequest(HttpServletRequest request,RoleStatusEnum role) {
if (RoleStatusEnum.ROLE_SUPER_ADMIN.equals(role) && Boolean.FALSE.equals(checkIsSuperAdmin(request))) {
throw new UnauthorizedAccessException(Status.UNAUTHORIZED, Translator.toLocale(GepafinConstant.INVALID_USER));
}
}
} }

View File

@@ -10,6 +10,7 @@ import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum;
import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.request.*;
import net.gepafin.tendermanagement.model.response.UserSamlResponse;
import net.gepafin.tendermanagement.model.response.UserResponseBean; import net.gepafin.tendermanagement.model.response.UserResponseBean;
import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.model.util.JWTToken;
import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.model.util.Response;
@@ -37,10 +38,11 @@ public interface UserApi {
@RequestMapping(value = "", @RequestMapping(value = "",
produces = {"application/json"}, produces = {"application/json"},
method = RequestMethod.POST) method = RequestMethod.POST)
@PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") // @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')")
default ResponseEntity<Response<UserResponseBean>> createUser( default ResponseEntity<Response<JWTToken>> createUser(HttpServletRequest request,
@Parameter(description = "temp spid Token", required = false) @RequestParam(value = "tempToken", required = false) String tempToken,
@Parameter(description = "User request object", required = true) @Validated @RequestBody UserReq userReq) { @Parameter(description = "User request object", required = true) @Validated @RequestBody UserReq userReq) {
return new ResponseEntity<Response<UserResponseBean>>(HttpStatus.NOT_IMPLEMENTED); return new ResponseEntity<Response<JWTToken>>(HttpStatus.NOT_IMPLEMENTED);
} }
@Operation(summary = "Api to update user", @Operation(summary = "Api to update user",
@@ -174,6 +176,7 @@ public interface UserApi {
@Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) UserStatusEnum status) { @Parameter(description = "status", required = true)@RequestParam(value = "status", required = true) UserStatusEnum status) {
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
} }
@Operation(summary = "Api to get valid user from token", @Operation(summary = "Api to get valid user from token",
responses = { responses = {
@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "200", description = "OK"),
@@ -186,6 +189,38 @@ public interface UserApi {
@GetMapping(value = "/me", @GetMapping(value = "/me",
produces = { "application/json" }) produces = { "application/json" })
ResponseEntity<Response<UserResponseBean>> getValidUser(HttpServletRequest request); ResponseEntity<Response<UserResponseBean>> getValidUser(HttpServletRequest request);
@Operation(summary = "Api to validate existing user from saml token",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@GetMapping(value = "/sso/validate/existing-user/{token}",
produces = { "application/json" })
ResponseEntity<Response<JWTToken>> validateExistingUserToken(HttpServletRequest request,
@Parameter(description = "The spid token", required = true) @PathVariable("token") String token);
@Operation(summary = "Api to validate new user from saml token",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@GetMapping(value = "/sso/validate/new-user/{token}",
produces = { "application/json" })
ResponseEntity<Response<UserSamlResponse>> validateNewUserToken(HttpServletRequest request,
@Parameter(description = "The spid token", required = true) @PathVariable("token") String token);
} }

View File

@@ -7,6 +7,7 @@ import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.enums.UserStatusEnum; import net.gepafin.tendermanagement.enums.UserStatusEnum;
import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.request.*;
import net.gepafin.tendermanagement.model.response.UserSamlResponse;
import net.gepafin.tendermanagement.model.response.UserResponseBean; import net.gepafin.tendermanagement.model.response.UserResponseBean;
import net.gepafin.tendermanagement.model.util.JWTToken; import net.gepafin.tendermanagement.model.util.JWTToken;
import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.model.util.Response;
@@ -33,9 +34,9 @@ public class UserApiController implements UserApi {
private UserService userService; private UserService userService;
@Override @Override
public ResponseEntity<Response<UserResponseBean>> createUser(@RequestBody UserReq userReq) { public ResponseEntity<Response<JWTToken>> createUser(HttpServletRequest request, String tempToken, @RequestBody UserReq userReq) {
log.info("Create User with - Request Body: {}", userReq); log.info("Create User with - Request Body: {}", userReq);
UserResponseBean createdUser = userService.createUser(userReq); JWTToken createdUser = userService.createUser(request, tempToken, userReq);
return ResponseEntity.status(HttpStatus.CREATED) return ResponseEntity.status(HttpStatus.CREATED)
.body(new Response<>(createdUser, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_CREATED_SUCCESS_MSG))); .body(new Response<>(createdUser, Status.SUCCESS, Translator.toLocale(GepafinConstant.USER_CREATED_SUCCESS_MSG)));
} }
@@ -124,4 +125,19 @@ public class UserApiController implements UserApi {
.body(new Response<>(user, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_USER_SUCCESS_MSG))); .body(new Response<>(user, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_USER_SUCCESS_MSG)));
} }
@Override
public ResponseEntity<Response<JWTToken>> validateExistingUserToken(HttpServletRequest request, String token) {
log.info("User login attempt via spid token");
JWTToken data = userService.validateExistingUserToken(request, token);
return ResponseEntity.ok(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.TOKEN_VALIDATE_SUCCESS_MSE)));
}
@Override
public ResponseEntity<Response<UserSamlResponse>> validateNewUserToken(HttpServletRequest request, String token) {
log.info("User validating spid token");
UserSamlResponse data = userService.validateNewUserToken(request,token);
return ResponseEntity.ok(new Response<>(data, Status.SUCCESS, Translator.toLocale(GepafinConstant.TOKEN_VALIDATE_SUCCESS_MSE)));
}
} }

View File

@@ -42,4 +42,5 @@ spring.main.allow-circular-references=true
isVatCheckGloballyDisabled = true isVatCheckGloballyDisabled = true
vatCheckNewToken: 66026bd891a51044e90e08c4 vatCheckNewToken: 66026bd891a51044e90e08c4
fe.base.url=http://gepafin-staging-fe.s3-website.eu-central-1.amazonaws.com

View File

@@ -712,27 +712,12 @@
</changeSet> </changeSet>
<changeSet id="23-09-2024_1" author="Rajesh Khore"> <changeSet id="23-09-2024_1" author="Rajesh Khore">
<createTable tableName="saml_response_log"> <createTable tableName="saml_response">
<column name="id" type="INTEGER" autoIncrement="true"> <column name="id" type="INTEGER" autoIncrement="true"></column>
</column> <column name="authentication_object" type="TEXT"> </column>
<column name="created_date" type="TIMESTAMP WITHOUT TIME ZONE"></column>
<column name="request" type="TEXT"> <column name="token" type="varchar(255)"></column>
</column> <column name="updated_date" type="TIMESTAMP WITHOUT TIME ZONE"></column>
<column name="response" type="TEXT">
</column>
<column name="authentication_object" type="TEXT">
</column>
<column name="exception_object" type="TEXT">
</column>
<column name="created_date" type="TIMESTAMP WITHOUT TIME ZONE">
</column>
<column name="updated_date" type="TIMESTAMP WITHOUT TIME ZONE">
</column>
</createTable> </createTable>
</changeSet> </changeSet>
@@ -742,4 +727,14 @@
<where>id = 13</where> <where>id = 13</where>
</update> </update>
</changeSet> </changeSet>
<changeSet id="25-09-2024_1" author="Rajesh Khore">
<addColumn tableName="gepafin_user">
<column name="codice_fiscale" type="varchar(255)">
<constraints nullable="true" unique="true"/>
</column>
</addColumn>
<dropNotNullConstraint tableName="gepafin_user" columnName="password"/>
</changeSet>
</databaseChangeLog> </databaseChangeLog>

View File

@@ -8,6 +8,7 @@ delete_user_error_msg=An error occurred while deleting the user.
get_user_success_msg=User retrieved successfully. get_user_success_msg=User retrieved successfully.
get_user_error_msg=An error occurred while retrieving the user. get_user_error_msg=An error occurred while retrieving the user.
user.not.active=User is not active. Please contact support. user.not.active=User is not active. Please contact support.
user.already.exist.msg=User already exist for this codice fiscale.
# Role-related messages # Role-related messages
role.created.success=Role created successfully. role.created.success=Role created successfully.
role.updated.success=Role updated successfully. role.updated.success=Role updated successfully.
@@ -184,6 +185,9 @@ valid.vat.number=The VAT number is not valid for field {0}.
failed.retain.field=Failed to retain specific fields. failed.retain.field=Failed to retain specific fields.
application.is.incomplete = The application is incomplete. application.is.incomplete = The application is incomplete.
token.validate.success=Token validated successfully.
invalid.request=Invalid Request.
codice.fiscale.exists=This codice fiscale is already associated with another user.
total.steps.not.zero=Total steps cannot be zero. total.steps.not.zero=Total steps cannot be zero.
completed.steps.not.valid=Completed steps should be between 0 and total steps. completed.steps.not.valid=Completed steps should be between 0 and total steps.
field.id.not.found=Field ID {0} does not exist in the form structure. field.id.not.found=Field ID {0} does not exist in the form structure.

View File

@@ -8,6 +8,7 @@ delete_user_error_msg=Si <20> verificato un errore durante l'eliminazione dell'ut
get_user_success_msg=Utente recuperato con successo. get_user_success_msg=Utente recuperato con successo.
get_user_error_msg=Si <20> verificato un errore durante il recupero dell'utente. get_user_error_msg=Si <20> verificato un errore durante il recupero dell'utente.
user.not.active=Utente non attivo. Si prega di contattare il supporto. user.not.active=Utente non attivo. Si prega di contattare il supporto.
user.already.exist.msg=L'utente esiste gi<67> per questo codice fiscale.
# Role-related messages # Role-related messages
role.created.success=Ruolo creato con successo. role.created.success=Ruolo creato con successo.
role.updated.success=Ruolo aggiornato con successo. role.updated.success=Ruolo aggiornato con successo.
@@ -176,7 +177,10 @@ validation.marca.da.bollo=Il campo {0} deve essere una Marca Da Bollo valida con
validation.piva=Il numero di partita IVA per {0} deve essere lungo fino a 11 cifre. validation.piva=Il numero di partita IVA per {0} deve essere lungo fino a 11 cifre.
valid.vat.number=Il numero di partita IVA non <20> valido per il campo {0}. valid.vat.number=Il numero di partita IVA non <20> valido per il campo {0}.
failed.retain.field=Impossibile conservare campi specifici. failed.retain.field=Impossibile conservare campi specifici.
token.validate.success=Token convalidato con successo.
invalid.request=Richiesta non valida.
codice.fiscale.exists=Questo codice fiscale <20> gi<67> associato ad un altro utente.
total.steps.not.zero=Il totale dei passaggi non può essere zero. total.steps.not.zero=Il totale dei passaggi non pu<EFBFBD> essere zero.
completed.steps.not.valid=I passaggi completati devono essere compresi tra 0 e il totale dei passaggi. completed.steps.not.valid=I passaggi completati devono essere compresi tra 0 e il totale dei passaggi.
field.id.not.found=L'ID campo {0} non esiste nella struttura del modulo. field.id.not.found=L'ID campo {0} non esiste nella struttura del modulo.