diff --git a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java index 91424195..90c278d4 100644 --- a/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java +++ b/src/main/java/net/gepafin/tendermanagement/config/SecurityConfig.java @@ -24,12 +24,12 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; import org.springframework.web.servlet.handler.HandlerMappingIntrospector; - import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.servers.Server; +import jakarta.servlet.http.HttpServletResponse; import net.gepafin.tendermanagement.config.jwt.JWTFilter; import net.gepafin.tendermanagement.config.jwt.TokenProvider; @@ -107,7 +107,13 @@ public class SecurityConfig { .requestMatchers("/swagger-ui/**").permitAll() // Swagger docs .requestMatchers("/v1/api-docs/**").permitAll() // API docs .anyRequest().authenticated()) - .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)) + .exceptionHandling(exceptionHandling -> exceptionHandling + .authenticationEntryPoint((request, response, authException) -> { + // Send 403 Forbidden when there is no JWT token provided + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Forbidden: Authentication token is missing or invalid"); + }) + ) .addFilterBefore(corsFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(new JWTFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class) // Add SAML2 login configuration (for BENEFICIARI) diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 62e90058..ce35fbc4 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -201,5 +201,7 @@ public class GepafinConstant { public static final String DELEGATION_DELETE_SUCCESS = "delegation.delete.success"; public static final String HH_MM_SS = "HH:mm:ss"; + public static final String USER_NOT_AUTHORIZED_TO_CREATE_APPLICATION = "user.not.authorized.create.application"; + public static final String APPLICATION_SUBMITTED_CANNOT_CHANGE = "application.submitted.cannot.change"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index b690a3e6..bca8f0d1 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -7,12 +7,14 @@ import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEm import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.enums.RoleStatusEnum; +import net.gepafin.tendermanagement.enums.UserCompanyDelegationStatusEnum; import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; import net.gepafin.tendermanagement.model.request.ApplicationRequest; import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.CallService; +import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.DocumentService; import net.gepafin.tendermanagement.service.FormService; import net.gepafin.tendermanagement.service.SystemEmailTemplatesService; @@ -74,9 +76,14 @@ public class ApplicationDao { @Autowired private FlowDataRepository flowDataRepository; - + @Autowired + private UserWithCompanyRepository userWithCompanyRepository; + @Autowired + private UserCompanyDelegationRepository userCompanyDelegationRepository; @Autowired private Validator validator; + @Autowired + private CompanyService companyService; @Autowired private ProtocolRepository protocolRepository; @@ -108,6 +115,19 @@ public class ApplicationDao { createOrUpdateMultipleFormFields(applicationRequestBean.getFormFields(), applicationFormEntity,formEntity); return getApplicationById(applicationEntity.getId(),formEntity.getId()); } + public void validateDelegation(UserEntity user, CompanyEntity company) { + UserWithCompanyEntity userWithCompany = companyService.getUserWithCompanyEntity(user.getId(), company.getId()); + + UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository + .findByUserIdAndCompanyIdAndStatus(user.getId(), company.getId(), + UserCompanyDelegationStatusEnum.ACTIVE.getValue()); + + if (!userWithCompany.getIsLegalRepresentant() && userCompanyDelegationEntity == null) { + throw new CustomValidationException(Status.BAD_REQUEST, + Translator.toLocale(GepafinConstant.USER_NOT_AUTHORIZED_TO_CREATE_APPLICATION)); + } + } + public ApplicationFormEntity saveApplicationFormEntity(ApplicationFormEntity applicationFormEntity) { ApplicationFormEntity applicationFormEntity1 = applicationFormRepository.save(applicationFormEntity); @@ -123,6 +143,7 @@ public class ApplicationDao { } public ApplicationEntity createApplicationEntity(UserEntity user, CallEntity call, CompanyEntity companyEntity) { + validateDelegation(user,companyEntity); ApplicationEntity entity = new ApplicationEntity(); entity.setUserId(user.getId()); entity.setCompany(companyEntity); @@ -536,6 +557,9 @@ public class ApplicationDao { public ApplicationResponse updateApplicationStatus(UserEntity userEntity, Long applicationId, ApplicationStatusTypeEnum status) { ApplicationEntity applicationEntity = validateApplication(applicationId); + if (ApplicationStatusTypeEnum.SUBMIT.getValue().equals(applicationEntity.getStatus())) { + throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_SUBMITTED_CANNOT_CHANGE)); + } if(Boolean.TRUE.equals(applicationEntity.getStatus().equals(status.getValue()))){ throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_IN_PREVIOUS_STATUS)); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index 525c657a..ca58f8be 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -127,15 +127,15 @@ public class DelegationDao { placeholders.put("{{company_last_name}}", ""); placeholders.put("{{company_codice_fiscale}}", ""); placeholders.put("{{company_name}}", ""); - placeholders.put("{{company_city}}", DEFAULT_PLACEHOLDER); - placeholders.put("{{company_address}}", DEFAULT_PLACEHOLDER); - placeholders.put("{{company_province}}", DEFAULT_PLACEHOLDER); - placeholders.put("{{company_cap}}", DEFAULT_PLACEHOLDER); + placeholders.put("{{company_city}}", ""); + placeholders.put("{{company_address}}", ""); + placeholders.put("{{company_province}}", ""); + placeholders.put("{{company_cap}}", ""); placeholders.put("{{company_vat_number}}", ""); placeholders.put("{{user_first_name}}", ""); placeholders.put("{{user_last_name}}", ""); - placeholders.put("{{user_date_of_birth}}", DEFAULT_PLACEHOLDER); + placeholders.put("{{user_date_of_birth}}", ""); placeholders.put("{{user_codice_fiscale}}", ""); return placeholders; } diff --git a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java index da05c544..18b6db0c 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java @@ -39,5 +39,7 @@ public interface CompanyService { CompanyDelegationResponse getCompanyDelegation(HttpServletRequest request, Long companyId); void deleteCompanyDelegation(HttpServletRequest request, Long companyId); + UserWithCompanyEntity getUserWithCompanyEntity(Long userId,Long companyId); + } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java index 0e43265a..1f80b223 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java @@ -114,4 +114,7 @@ public class CompanyServiceImpl implements CompanyService { UserEntity userEntity =validator.validateUser(request); delegationDao.deleteCompanyDelegation(userEntity, companyId); } + public UserWithCompanyEntity getUserWithCompanyEntity(Long userId,Long companyId){ + return companyDao.getUserWithCompany(userId,companyId); + } } diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 278cae9a..0d68c6d7 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -224,5 +224,7 @@ application.already.in.provided.status=Application is already in provided status delegation.not.found=Delegation not found. user.company.relation.not.found=User with the specified company relation not found. delegation.delete.success=Delegation deleted successfully. +user.not.authorized.create.application=User must be a legal representative or have delegation. +application.submitted.cannot.change=The submitted application cannot be changed. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index e28900bd..3e665e82 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -219,5 +219,8 @@ application.already.in.provided.status=L'applicazione � gi� nello stato forn delegation.not.found=Delega non trovata. user.company.relation.not.found=Relazione utente con l'azienda specificata non trovata. delegation.delete.success=Delega eliminata con successo. +user.not.authorized.create.application=L'utente deve essere un rappresentante legale o avere una delega. +application.submitted.cannot.change=La domanda inviata non può essere modificata. +