diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
new file mode 100644
index 0000000..913f8c1
--- /dev/null
+++ b/.github/workflows/maven.yml
@@ -0,0 +1,75 @@
+# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
+# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
+
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
+name: Java CI with Maven
+
+on:
+ push:
+ branches: [ "main" ]
+ tags:
+ - '*' # Trigger per tutti i tag
+ pull_request:
+ branches: [ "main" ]
+
+permissions:
+ contents: write
+ id-token: write
+ actions: write
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set timezone to Europe/Rome
+ run: sudo timedatectl set-timezone Europe/Rome
+ - name: Set up JDK 21
+ uses: actions/setup-java@v4
+ with:
+ java-version: '21'
+ distribution: 'temurin'
+ cache: maven
+ - name: Build with Maven
+ run: mvn clean install -P jar -DskipTests -Ddependency-check.skip=true
+
+ - name: Upload artifact to GitHub
+ uses: actions/upload-artifact@v4.6.0
+ with:
+ name: govpay-gde-api
+ path: target/govpay-gde-api.war
+
+ release:
+ runs-on: ubuntu-latest
+ needs: build
+ if: startsWith(github.ref, 'refs/tags/') # Esegui solo per i tag
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Download artifact from build job
+ uses: actions/download-artifact@v4
+ with:
+ name: govpay-gde-api
+ path: target/ # Assicurati che il file venga scaricato nella cartella target
+
+ - name: Rename the artifact file to include the tag
+ run: cp target/govpay-gde-api.war target/govpay-gde-api-${{ github.ref_name }}.war # Rinominare il file
+
+ - name: List files in target directory
+ run: ls -l target/
+
+ - name: Create GitHub release
+ id: create_release
+ uses: softprops/action-gh-release@v2.2.1
+ with:
+ files: target/govpay-gde-api-${{ github.ref_name }}.war # Specifica l'artefatto da caricare
+ env:
+ GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
diff --git a/pom.xml b/pom.xml
index 0076838..91420d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.7.17
+ 3.4.1
it.govpay.gde
@@ -17,7 +17,7 @@
GovPay Modulo per la registrazione degli eventi
- 11
+ 21
${java.version}
${java.version}
${java.version}
@@ -31,10 +31,10 @@
1.6.0
- 2.11.0
+ 2.18.0
- 6.2.1
+ 6.6.0
0.2.1
@@ -43,7 +43,6 @@
1.3.2
- 2.1.2
1.6.2
@@ -52,11 +51,25 @@
1.5.1.Final
- 0.8.8
+ 0.8.12
3.5.3
- 1.6.4
-
+ 1.8.0
+ 5.18.2
+
+ 1.3.2
+
+ src/main/resources/owasp/falsePositives
+
+ verify
+ 11.1.1
+ true
+ false
+ 5
+
+ 1.5.16
+
+ 2.3.232
@@ -111,101 +124,33 @@
org.springframework.boot
spring-boot-starter-logging
-
- org.slf4j
- slf4j-api
-
-
- org.slf4j
- jcl-over-slf4j
-
-
- org.slf4j
- jul-to-slf4j
-
-
- org.slf4j
- log4j-over-slf4j
-
-
- org.hibernate
- hibernate-validator
-
-
- ch.qos.logback
- logback-classicr
-
-
+
org.springframework.boot
- spring-boot-starter-data-jpa
+ spring-boot-starter-logging
-
- org.springframework.boot
- spring-boot-starter-logging
-
-
- org.slf4j
- slf4j-api
-
-
- org.slf4j
- jcl-over-slf4j
-
-
- org.slf4j
- jul-to-slf4j
-
-
- org.slf4j
- log4j-over-slf4j
-
-
- org.hibernate
- hibernate-validator
-
ch.qos.logback
- logback-classicr
+ logback-classic
+
+
+ ch.qos.logback
+ logback-classic
+
org.springframework.boot
spring-boot-starter-actuator
-
-
- org.springframework.boot
- spring-boot-starter-logging
-
-
- org.slf4j
- slf4j-api
-
-
- org.slf4j
- jcl-over-slf4j
-
-
- org.slf4j
- jul-to-slf4j
-
-
- org.slf4j
- log4j-over-slf4j
-
-
- org.hibernate
- hibernate-validator
-
-
- ch.qos.logback
- logback-classicr
-
-
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
@@ -242,6 +187,7 @@
javax.annotation
javax.annotation-api
+ ${javax.annotation-api.version}
@@ -278,33 +224,18 @@
commons-lang3
-
- org.slf4j
- slf4j-api
-
-
- org.apache.logging.log4j
- log4j-api
-
-
- org.apache.logging.log4j
- log4j-core
-
-
- org.apache.logging.log4j
- log4j-1.2-api
-
-
-
- org.apache.logging.log4j
- log4j-slf4j-impl
-
org.springdoc
springdoc-openapi-ui
${springdoc.version}
+
+
+ org.webjars
+ swagger-ui
+
+
org.springdoc
@@ -315,6 +246,11 @@
org.springframework.boot
spring-boot-starter-hateoas
+
+ org.webjars
+ swagger-ui
+ ${swagger-ui.version}
+
@@ -327,6 +263,7 @@
hamcrest-core
test
+
jakarta.json
jakarta.json-api
@@ -334,10 +271,16 @@
org.glassfish
- javax.json
- 1.1.4
+ jakarta.json
+ 2.0.1
test
+
+ org.eclipse.parsson
+ parsson
+ 1.0.0
+ test
+
@@ -345,6 +288,7 @@
src/main/resources
+ true
govpay-gde-api
@@ -404,6 +348,7 @@
true
true
true
+ true
false
@@ -433,6 +378,44 @@
+
+ org.owasp
+ dependency-check-maven
+ ${owasp.plugin.version}
+
+
+ check owasp
+ ${owasp}
+
+ ${owasp.plugin.autoUpdate}
+ ${owasp.plugin.failBuildOnAnyVulnerability}
+ ALL
+
+ ${owasp.falsePositives.dir}/CVE-2018-14335.xml
+
+ 120000
+ 3
+
+
+ aggregate
+
+
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+ 4.8.6.0
+
+
+
+ com.h3xstream.findsecbugs
+ findsecbugs-plugin
+ 1.12.0
+
+
+
+
diff --git a/src/main/java/it/govpay/gde/config/WebConfig.java b/src/main/java/it/govpay/gde/config/WebConfig.java
new file mode 100644
index 0000000..3099cbb
--- /dev/null
+++ b/src/main/java/it/govpay/gde/config/WebConfig.java
@@ -0,0 +1,43 @@
+package it.govpay.gde.config;
+
+import java.text.SimpleDateFormat;
+import java.time.OffsetDateTime;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+
+import it.govpay.gde.costanti.Costanti;
+import it.govpay.gde.utils.OffsetDateTimeDeserializer;
+import it.govpay.gde.utils.OffsetDateTimeSerializer;
+
+
+@Configuration
+public class WebConfig {
+
+ @Bean
+ public ObjectMapper objectMapper() {
+ // Crea un ObjectMapper con configurazioni personalizzate
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ // Imposta il formato delle date
+ objectMapper.setDateFormat(new SimpleDateFormat(Costanti.PATTERN_TIMESTAMP_3_YYYY_MM_DD_T_HH_MM_SS_SSSXXX));
+
+ objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
+ objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
+ objectMapper.enable(SerializationFeature.WRITE_DATES_WITH_ZONE_ID);
+ objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+
+ // Aggiungi moduli personalizzati se necessario
+ JavaTimeModule javaTimeModule = new JavaTimeModule();
+ javaTimeModule.addSerializer(OffsetDateTime.class, new OffsetDateTimeSerializer());
+ javaTimeModule.addDeserializer(OffsetDateTime.class, new OffsetDateTimeDeserializer());
+ objectMapper.registerModule(javaTimeModule);
+
+ return objectMapper;
+ }
+}
diff --git a/src/main/java/it/govpay/gde/controller/GdeController.java b/src/main/java/it/govpay/gde/controller/GdeController.java
index 70934c1..e9e1a2a 100644
--- a/src/main/java/it/govpay/gde/controller/GdeController.java
+++ b/src/main/java/it/govpay/gde/controller/GdeController.java
@@ -2,11 +2,8 @@
import java.time.OffsetDateTime;
-import javax.servlet.http.HttpServletRequest;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpHeaders;
@@ -24,6 +21,7 @@
import it.govpay.gde.beans.Evento;
import it.govpay.gde.beans.ListaEventi;
import it.govpay.gde.beans.NuovoEvento;
+import it.govpay.gde.beans.PageInfo;
import it.govpay.gde.beans.RuoloEvento;
import it.govpay.gde.entity.EventoEntity;
import it.govpay.gde.exception.ResourceNotFoundException;
@@ -33,24 +31,28 @@
import it.govpay.gde.repository.EventoRepository;
import it.govpay.gde.repository.LimitOffsetPageRequest;
import it.govpay.gde.utils.ListaUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.Valid;
@Controller
-//@RequestMapping("/api/v1")
public class GdeController implements EventiApi{
private Logger logger = LoggerFactory.getLogger(GdeController.class);
- @Autowired
private EventoRepository eventoRepository;
- @Autowired
- NuovoEventoMapperImpl nuovoEventoMapperImpl;
+ private NuovoEventoMapperImpl nuovoEventoMapperImpl;
+
+ private EventoMapperImpl eventoMapperImpl;
- @Autowired
- EventoMapperImpl eventoMapperImpl;
+ public GdeController(EventoRepository eventoRepository, NuovoEventoMapperImpl nuovoEventoMapperImpl, EventoMapperImpl eventoMapperImpl) {
+ this.eventoRepository = eventoRepository;
+ this.nuovoEventoMapperImpl = nuovoEventoMapperImpl;
+ this.eventoMapperImpl = eventoMapperImpl;
+ }
@Override
- public ResponseEntity addEvento(NuovoEvento nuovoEvento) {
+ public ResponseEntity addEvento(@Valid NuovoEvento nuovoEvento) {
this.logger.debug("Salvataggio evento: {}", nuovoEvento);
EventoEntity entity = this.nuovoEventoMapperImpl.nuovoEventoToEventoEntity(nuovoEvento);
@@ -65,7 +67,7 @@ public ResponseEntity addEvento(NuovoEvento nuovoEvento) {
headers.add("Location", ListaUtils.createLocation(curRequest, entity.getId()));
- return new ResponseEntity(headers, HttpStatus.CREATED);
+ return new ResponseEntity<>(headers, HttpStatus.CREATED);
}
@Override
@@ -78,8 +80,13 @@ public ResponseEntity findEventi(Long offset,
this.logger.debug("Ricerca eventi...");
- Specification spec = creaFiltriDiRicerca(dataDa, dataA, idDominio, iuv, ccp, idA2A, idPendenza,
- categoriaEvento, esito, ruolo, sottotipoEvento, tipoEvento, componente, severitaDa, severitaA);
+ Specification spec = creaFiltriDiRicercaDate(dataDa, dataA);
+
+ spec = creaFiltriDiRicercaEvento(spec, categoriaEvento, esito, ruolo, sottotipoEvento, tipoEvento, componente);
+
+ spec = creaFiltriDiRicercaDatiPendenza(spec, idDominio, iuv, ccp, idA2A, idPendenza);
+
+ spec = creaFiltriDiRicercaSeverita(spec, severitaDa, severitaA);
LimitOffsetPageRequest pageRequest = new LimitOffsetPageRequest(offset, limit, EventoFilters.sort());
@@ -87,7 +94,10 @@ public ResponseEntity findEventi(Long offset,
HttpServletRequest curRequest = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
- ListaEventi ret = ListaUtils.buildPaginatedList(eventi, pageRequest.limit, curRequest, new ListaEventi());
+ PageInfo pageInfo = new PageInfo(offset,limit);
+ pageInfo.setTotal(eventi.getTotalElements());
+
+ ListaEventi ret = ListaUtils.buildPaginatedList(eventi, pageRequest.limit, curRequest, new ListaEventi(pageInfo, null));
for (EventoEntity user : eventi) {
ret.addItemsItem(this.eventoMapperImpl.eventoEntityToEvento(user));
@@ -97,11 +107,8 @@ public ResponseEntity findEventi(Long offset,
return ResponseEntity.ok(ret);
}
-
- private Specification creaFiltriDiRicerca(OffsetDateTime dataDa, OffsetDateTime dataA, String idDominio,
- String iuv, String ccp, String idA2A, String idPendenza, CategoriaEvento categoriaEvento, EsitoEvento esito,
- RuoloEvento ruolo, String sottotipoEvento, String tipoEvento, ComponenteEvento componente,
- Integer severitaDa, Integer severitaA) {
+
+ private Specification creaFiltriDiRicercaDate(OffsetDateTime dataDa, OffsetDateTime dataA) {
Specification spec = EventoFilters.empty();
if(dataDa != null) {
@@ -110,6 +117,43 @@ private Specification creaFiltriDiRicerca(OffsetDateTime dataDa, O
if(dataA != null) {
spec = spec.and(EventoFilters.byDataA(dataA));
}
+ return spec;
+ }
+
+ private Specification creaFiltriDiRicercaEvento(Specification spec, CategoriaEvento categoriaEvento, EsitoEvento esito,
+ RuoloEvento ruolo, String sottotipoEvento, String tipoEvento, ComponenteEvento componente) {
+
+ if (spec == null) {
+ spec = EventoFilters.empty();
+ }
+
+ if(tipoEvento != null) {
+ spec = spec.and(EventoFilters.byTipoEvento(tipoEvento));
+ }
+ if(sottotipoEvento != null) {
+ spec = spec.and(EventoFilters.bySottotipoEvento(sottotipoEvento));
+ }
+ if(componente != null) {
+ spec = spec.and(EventoFilters.byComponenteEvento(componente));
+ }
+ if(categoriaEvento != null) {
+ spec = spec.and(EventoFilters.byCategoriaEvento(categoriaEvento));
+ }
+ if(esito != null) {
+ spec = spec.and(EventoFilters.byEsitoEvento(esito));
+ }
+ if(ruolo != null) {
+ spec = spec.and(EventoFilters.byRuoloEvento(ruolo));
+ }
+ return spec;
+ }
+
+ private Specification creaFiltriDiRicercaDatiPendenza(Specification spec, String idDominio,
+ String iuv, String ccp, String idA2A, String idPendenza) {
+ if (spec == null) {
+ spec = EventoFilters.empty();
+ }
+
if(idDominio != null) {
spec = spec.and(EventoFilters.byIdDominio(idDominio));
}
@@ -125,30 +169,21 @@ private Specification creaFiltriDiRicerca(OffsetDateTime dataDa, O
if(idPendenza != null) {
spec = spec.and(EventoFilters.byIdPendenza(idPendenza));
}
+ return spec;
+ }
+
+ private Specification creaFiltriDiRicercaSeverita(Specification spec, Integer severitaDa, Integer severitaA) {
+
+ if (spec == null) {
+ spec = EventoFilters.empty();
+ }
+
if(severitaDa != null) {
spec = spec.and(EventoFilters.bySeveritaDa(severitaDa));
}
if(severitaA != null) {
spec = spec.and(EventoFilters.bySeveritaA(severitaA));
}
- if(tipoEvento != null) {
- spec = spec.and(EventoFilters.byTipoEvento(tipoEvento));
- }
- if(sottotipoEvento != null) {
- spec = spec.and(EventoFilters.bySottotipoEvento(sottotipoEvento));
- }
- if(componente != null) {
- spec = spec.and(EventoFilters.byComponenteEvento(componente));
- }
- if(categoriaEvento != null) {
- spec = spec.and(EventoFilters.byCategoriaEvento(categoriaEvento));
- }
- if(esito != null) {
- spec = spec.and(EventoFilters.byEsitoEvento(esito));
- }
- if(ruolo != null) {
- spec = spec.and(EventoFilters.byRuoloEvento(ruolo));
- }
return spec;
}
@@ -158,7 +193,7 @@ public ResponseEntity getEventoById(Long id) {
ResponseEntity res = this.eventoRepository.findById(id).map(this.eventoMapperImpl::eventoEntityToEvento)
.map(ResponseEntity::ok)
- .orElseThrow(() -> new ResourceNotFoundException());
+ .orElseThrow(ResourceNotFoundException::new);
this.logger.debug("Lettura evento completata.");
return res;
diff --git a/src/main/java/it/govpay/gde/costanti/Costanti.java b/src/main/java/it/govpay/gde/costanti/Costanti.java
new file mode 100644
index 0000000..a9b0a80
--- /dev/null
+++ b/src/main/java/it/govpay/gde/costanti/Costanti.java
@@ -0,0 +1,12 @@
+package it.govpay.gde.costanti;
+
+public class Costanti {
+
+ private Costanti() {
+ //donothing
+ }
+
+ public static final String PATTERN_YYYY_MM_DD_T_HH_MM_SS_MILLIS_VARIABILI_XXX = "yyyy-MM-dd'T'HH:mm:ss[.[SSSSSSSSS][SSSSSSSS][SSSSSSS][SSSSSS][SSSSS][SSSS][SSS][SS][S]XXX]";
+
+ public static final String PATTERN_TIMESTAMP_3_YYYY_MM_DD_T_HH_MM_SS_SSSXXX = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
+}
diff --git a/src/main/java/it/govpay/gde/entity/EventoEntity.java b/src/main/java/it/govpay/gde/entity/EventoEntity.java
index b9058c7..bafdd1c 100644
--- a/src/main/java/it/govpay/gde/entity/EventoEntity.java
+++ b/src/main/java/it/govpay/gde/entity/EventoEntity.java
@@ -1,21 +1,21 @@
package it.govpay.gde.entity;
+import java.sql.Types;
import java.time.OffsetDateTime;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Index;
-import javax.persistence.Lob;
-import javax.persistence.SequenceGenerator;
-import javax.persistence.Table;
-
-import org.hibernate.annotations.Type;
+import org.hibernate.annotations.JdbcTypeCode;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.Index;
+import jakarta.persistence.Lob;
+import jakarta.persistence.SequenceGenerator;
+import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -88,8 +88,8 @@ public enum EsitoEvento { OK, KO, FAIL }
// @Lob
// @Convert(converter = DatiPagoPAConverter.class)
- @Type(type = "org.hibernate.type.TextType")
-// private String descrizione;
+// @Type(value = "org.hibernate.type.TextType")
+ @JdbcTypeCode(Types.LONGVARCHAR)
@Column(name = "dati_pago_pa")
private String datiPagoPA;
@@ -130,14 +130,16 @@ public enum EsitoEvento { OK, KO, FAIL }
private String transactionId;
@Lob
- @Type(type="org.hibernate.type.BinaryType")
+// @Type(type="org.hibernate.type.BinaryType")
// @Convert(converter = DettaglioRichiestaConverter.class)
+ @JdbcTypeCode(Types.VARBINARY)
@Column(name = "parametri_richiesta")
private byte[] parametriRichiesta;
@Lob
- @Type(type="org.hibernate.type.BinaryType")
+// @Type(type="org.hibernate.type.BinaryType")
// @Convert(converter = DettaglioRispostaConverter.class)
+ @JdbcTypeCode(Types.VARBINARY)
@Column(name = "parametri_risposta")
private byte[] parametriRisposta;
diff --git a/src/main/java/it/govpay/gde/exception/handlers/RestResponseEntityExceptionHandler.java b/src/main/java/it/govpay/gde/exception/handlers/RestResponseEntityExceptionHandler.java
index c1dea8f..ae204ab 100644
--- a/src/main/java/it/govpay/gde/exception/handlers/RestResponseEntityExceptionHandler.java
+++ b/src/main/java/it/govpay/gde/exception/handlers/RestResponseEntityExceptionHandler.java
@@ -11,6 +11,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
+import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
@@ -99,15 +100,14 @@ public final ResponseEntity