From ab08009c6482c80e8829dd12af958619c1832018 Mon Sep 17 00:00:00 2001 From: RIHTARSIC Joze <joze.rihtarsic@ext.ec.europa.eu> Date: Thu, 10 Oct 2024 09:54:08 +0200 Subject: [PATCH] [EDELIVERY-14110] fix document property validation for non string types --- .../config/init/SMPExtensionInitializer.java | 14 +++-- .../edelivery/smp/data/dao/DocumentDao.java | 10 +++- .../data/model/doc/DBDocumentProperty.java | 2 +- .../resource/AbstractResourceHandler.java | 55 +++++++++++-------- .../services/resource/ResourceStorage.java | 22 ++++---- .../mysql5innoDb-5.0_to_5.1.sql | 4 +- .../oracle10g-5.0_to_5.1.sql | 4 +- .../database-scripts/mysql5innodb-drop.ddl | 2 +- .../database-scripts/mysql5innodb.ddl | 6 +- .../database-scripts/oracle10g-drop.ddl | 2 +- .../smp-setup/database-scripts/oracle10g.ddl | 6 +- .../src/main/smp-setup/smp.config.properties | 8 ++- 12 files changed, 81 insertions(+), 54 deletions(-) diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/init/SMPExtensionInitializer.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/init/SMPExtensionInitializer.java index f11b4db06..10614dd85 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/init/SMPExtensionInitializer.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/config/init/SMPExtensionInitializer.java @@ -180,8 +180,12 @@ public class SMPExtensionInitializer implements InitializingBean { resourceDef.setName(resourceDefinitionSpi.name()); resourceDef.setDescription(resourceDefinitionSpi.description()); resourceDef.setMimeType(resourceDefinitionSpi.mimeType()); - resourceDef.setUrlSegment(resourceDefinitionSpi.defaultUrlSegment()); + //resourceDef.setUrlSegment(resourceDefinitionSpi.defaultUrlSegment()); resourceDef.setHandlerImplementationName(getHandlerSPIName(resourceDefinitionSpi.getResourceHandler())); + // update only if new subresource + if (resourceDef.getId() == null) { + resourceDef.setUrlSegment(resourceDefinitionSpi.defaultUrlSegment()); + } resourceDefinitionSpi.getSubresourceSpiList().forEach( subresourceDefinitionSpi -> validateSubresourceDefinition(subresourceDefinitionSpi, resourceDef) ); @@ -207,13 +211,13 @@ public class SMPExtensionInitializer implements InitializingBean { subresourceDef.setName(subresourceDefinitionSpi.name()); subresourceDef.setDescription(subresourceDefinitionSpi.description()); subresourceDef.setMimeType(subresourceDefinitionSpi.mimeType()); - subresourceDef.setUrlSegment(subresourceDefinitionSpi.urlSegment()); subresourceDef.setHandlerImplementationName(getHandlerSPIName(subresourceDefinitionSpi.getResourceHandler())); - + // update only if new subresource + if (subresourceDef.getId() == null) { + subresourceDef.setUrlSegment(subresourceDefinitionSpi.urlSegment()); + } } - - public void updateExtension(String extensionName, ExtensionInfo extensionInfo, DBExtension extension) { LOG.debug("Update extension for implementationName [{}]", extensionInfo); extension.setName(extensionInfo.name()); diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DocumentDao.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DocumentDao.java index 10606a7de..f9dcd82d4 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DocumentDao.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/dao/DocumentDao.java @@ -55,6 +55,10 @@ public class DocumentDao extends BaseDao<DBDocument> { * @return document for the resource or empty if not found */ public Optional<DBDocument> getDocumentForResource(DBResource dbResource) { + if (dbResource == null || dbResource.getId() == null) { + LOG.debug("Can not get document for resource, because resource is not persisted to the database"); + return Optional.empty(); + } try { // expected is only one domain, TypedQuery<DBDocument> query = memEManager.createNamedQuery(QUERY_DOCUMENT_FOR_RESOURCE, DBDocument.class); @@ -74,6 +78,10 @@ public class DocumentDao extends BaseDao<DBDocument> { * @return document for the resource or empty if not found */ public Optional<DBDocument> getDocumentForSubresource(DBSubresource dbSubresource) { + if (dbSubresource == null|| dbSubresource.getId() == null) { + LOG.debug("Can not get document for subresource, because resource is not persisted to the database"); + return Optional.empty(); + } try { // expected is only one domain, TypedQuery<DBDocument> query = memEManager.createNamedQuery(QUERY_DOCUMENT_FOR_SUBRESOURCE, DBDocument.class); @@ -192,7 +200,7 @@ public class DocumentDao extends BaseDao<DBDocument> { public long getDocumentReviewListForUserCount(Long dbUserId) { TypedQuery<Long> query = createDocumentReviewListForUserQuery(Long.class, dbUserId); - return query.getSingleResult().longValue(); + return query.getSingleResult(); } /** diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBDocumentProperty.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBDocumentProperty.java index 7ba6f77a6..c9ae91b85 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBDocumentProperty.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/model/doc/DBDocumentProperty.java @@ -59,7 +59,7 @@ public class DBDocumentProperty extends BaseEntity { @Column(name = "PROPERTY_NAME") protected String property; - @Column(name = "PROPERTY_VALUE", length = CommonColumnsLengths.MAX_MEDIUM_TEXT_LENGTH) + @Column(name = "PROPERTY_VALUE", length = CommonColumnsLengths.MAX_FREE_TEXT_LENGTH) private String value; @Column(name = "DESCRIPTION", length = CommonColumnsLengths.MAX_FREE_TEXT_LENGTH) diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/AbstractResourceHandler.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/AbstractResourceHandler.java index e5cf4f68b..3dcb64787 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/AbstractResourceHandler.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/AbstractResourceHandler.java @@ -115,26 +115,31 @@ public class AbstractResourceHandler { if (content == null || content.length == 0) { throw new SMPRuntimeException(ErrorCode.RESOURCE_DOCUMENT_MISSING, resource.getIdentifierValue(), resource.getIdentifierScheme()); } - // read and replace properties - Map<String, String> docProp = resourceStorage.getResourceProperties(resource); + return buildRequestDataForResource(domain, resource, new ByteArrayInputStream(content)); + } + public RequestData buildRequestDataForResource(DBDomain domain, DBResource resource, InputStream inputStream) { + Map<String, String> docProp = resourceStorage.getResourceProperties(resource); try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { - StringNamedSubstitutor.resolve(new ByteArrayInputStream(content), docProp, baos, EXPECTED_RESOURCE_CHARSET); - ByteArrayInputStream inputStream = new ByteArrayInputStream(baos.toByteArray()); - return buildRequestDataForResource(domain, - resource, - inputStream); + if (inputStream != null && inputStream.available() != 0) { + StringNamedSubstitutor.resolve(inputStream, docProp, baos, EXPECTED_RESOURCE_CHARSET); + } + return new SpiRequestData(domain.getDomainCode(), + SPIUtils.toUrlIdentifier(resource), + new ByteArrayInputStream(baos.toByteArray())); } catch (IOException e) { throw new SMPRuntimeException(ErrorCode.RESOURCE_DOCUMENT_MISSING, resource.getIdentifierValue(), resource.getIdentifierScheme()); } } - public RequestData buildRequestDataForResource(DBDomain domain, DBResource resource, InputStream inputStream) { - return new SpiRequestData(domain.getDomainCode(), - SPIUtils.toUrlIdentifier(resource), - inputStream); - } - + /** + * Build handler RequestData and add resource from the database for the subresource + * It reads the content of the subresource from the database and replaces the properties in the document. + * @param domain + * @param resource + * @param subresource + * @return + */ public RequestData buildRequestDataForSubResource(DBDomain domain, DBResource resource, DBSubresource subresource) { byte[] content = resourceStorage.getDocumentContentForSubresource(subresource); @@ -143,11 +148,24 @@ public class AbstractResourceHandler { subresource.getIdentifierValue(), subresource.getIdentifierScheme(), resource.getIdentifierValue(), resource.getIdentifierScheme()); } + return buildRequestDataForSubResource(domain, resource, subresource, new ByteArrayInputStream(content)); + } + /** + * Build handler RequestData and add resource from the database. The input stream is used to replace the properties + * in the document and the new bytearrays is used as stream to create the RequestData. + * @param domain of the resource + * @param resource the parent resource of the subresource + * @param subresource an entity with the subresource data + * @param inputStream the input stream to replace the properties in the document + * @return request data for the subresource + */ + public RequestData buildRequestDataForSubResource(DBDomain domain, DBResource resource, DBSubresource subresource, InputStream inputStream) { Map<String, String> docProp = resourceStorage.getSubresourceProperties(resource, subresource); - try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { - StringNamedSubstitutor.resolve(new ByteArrayInputStream(content), docProp, baos, EXPECTED_RESOURCE_CHARSET); + if (inputStream != null && inputStream.available() != 0) { + StringNamedSubstitutor.resolve(inputStream, docProp, baos, EXPECTED_RESOURCE_CHARSET); + } return new SpiRequestData(domain.getDomainCode(), SPIUtils.toUrlIdentifier(resource), SPIUtils.toUrlIdentifier(subresource), @@ -157,13 +175,6 @@ public class AbstractResourceHandler { } } - public RequestData buildRequestDataForSubResource(DBDomain domain, DBResource resource, DBSubresource subresource, InputStream inputStream) { - return new SpiRequestData(domain.getDomainCode(), - SPIUtils.toUrlIdentifier(resource), - SPIUtils.toUrlIdentifier(subresource), - inputStream); - } - public void handleReadResource(ResourceHandlerSpi handlerSpi, RequestData requestData, ResponseData responseData, ResourceResponse resourceResponse) { try { handlerSpi.readResource(requestData, responseData); diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/ResourceStorage.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/ResourceStorage.java index 6d762d33a..52348dfad 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/ResourceStorage.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/resource/ResourceStorage.java @@ -73,8 +73,8 @@ public class ResourceStorage { @Transactional public byte[] getDocumentContentForResource(DBResource dbResource) { LOG.debug("getDocumentContentForResource: [{}]", dbResource); - DBDocument document = documentDao.getDocumentForResource(dbResource).orElseGet(null); - return getDocumentContent(document, true); + Optional<DBDocument> document = documentDao.getDocumentForResource(dbResource); + return document.isPresent() ? getDocumentContent(document.get(), true) : null; } public byte[] getDocumentContent(DBDocument document, boolean followReference) { @@ -93,23 +93,23 @@ public class ResourceStorage { LOG.debug("getDocumentContent: [{}]", document); Optional<DBDocumentVersion> documentVersion = documentDao.getCurrentDocumentVersionForDocument(document); - return documentVersion.isPresent() ? documentVersion.get().getContent() : null; + return documentVersion.map(DBDocumentVersion::getContent).orElse(null); } public byte[] getDocumentContentForSubresource(DBSubresource subresource) { LOG.debug("getDocumentContentForSubresource: [{}]", subresource); - DBDocument document = documentDao.getDocumentForSubresource(subresource).orElseGet(null); - return getDocumentContent(document, true); + Optional<DBDocument> document = documentDao.getDocumentForSubresource(subresource); + return document.isPresent() ? getDocumentContent(document.get(), true) : null; } @Transactional public Map<String, String> getResourceProperties(DBResource resource) { - DBDocument document = documentDao.getDocumentForResource(resource).orElseGet(null); - if (document == null) { + Optional<DBDocument> optDocument = documentDao.getDocumentForResource(resource); + if (!optDocument.isPresent()) { LOG.debug("Document not found for resource [{}]", resource); return Collections.emptyMap(); } - Map<String, String> documentProperties = getDocumentProperties(document, true); + Map<String, String> documentProperties = getDocumentProperties(optDocument.get(), true); // then overwrite with document properties documentProperties.put(TransientDocumentPropertyType.RESOURCE_IDENTIFIER_VALUE.getPropertyName(), resource.getIdentifierValue()); if (resource.getIdentifierScheme() != null) { @@ -121,13 +121,13 @@ public class ResourceStorage { @Transactional public Map<String, String> getSubresourceProperties(DBResource resource, DBSubresource subresource) { - DBDocument document = documentDao.getDocumentForSubresource(subresource).orElseGet(null); - if (document == null) { + Optional<DBDocument> optDocument = documentDao.getDocumentForSubresource(subresource); + if (!optDocument.isPresent()) { LOG.debug("Document not found for subresource [{}]", resource); return Collections.emptyMap(); } - Map<String, String> documentProperties = getDocumentProperties(document, true); + Map<String, String> documentProperties = getDocumentProperties(optDocument.get(), true); // add resource and subresource properties documentProperties.put(TransientDocumentPropertyType.RESOURCE_IDENTIFIER_VALUE.getPropertyName(), resource.getIdentifierValue()); if (resource.getIdentifierScheme() != null) { diff --git a/smp-webapp/src/main/smp-setup/database-scripts/migration from 5.0 to 5.1/mysql5innoDb-5.0_to_5.1.sql b/smp-webapp/src/main/smp-setup/database-scripts/migration from 5.0 to 5.1/mysql5innoDb-5.0_to_5.1.sql index b5b9a64f7..2bfc820fb 100644 --- a/smp-webapp/src/main/smp-setup/database-scripts/migration from 5.0 to 5.1/mysql5innoDb-5.0_to_5.1.sql +++ b/smp-webapp/src/main/smp-setup/database-scripts/migration from 5.0 to 5.1/mysql5innoDb-5.0_to_5.1.sql @@ -41,7 +41,7 @@ create table SMP_DOCUMENT_PROPERTY ( DESCRIPTION varchar(4000) CHARACTER SET utf8 COLLATE utf8_bin comment 'Property description', PROPERTY_NAME varchar(255) CHARACTER SET utf8 COLLATE utf8_bin, PROPERTY_TYPE varchar(64) CHARACTER SET utf8 COLLATE utf8_bin, - PROPERTY_VALUE varchar(1024) CHARACTER SET utf8 COLLATE utf8_bin, + PROPERTY_VALUE varchar(4000) CHARACTER SET utf8 COLLATE utf8_bin, FK_DOCUMENT_ID bigint, primary key (ID) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -55,7 +55,7 @@ create table SMP_DOCUMENT_PROPERTY_AUD ( DESCRIPTION varchar(4000) CHARACTER SET utf8 COLLATE utf8_bin, PROPERTY_NAME varchar(255) CHARACTER SET utf8 COLLATE utf8_bin, PROPERTY_TYPE varchar(64) CHARACTER SET utf8 COLLATE utf8_bin, - PROPERTY_VALUE varchar(1024) CHARACTER SET utf8 COLLATE utf8_bin, + PROPERTY_VALUE varchar(4000) CHARACTER SET utf8 COLLATE utf8_bin, FK_DOCUMENT_ID bigint, primary key (ID, REV) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/smp-webapp/src/main/smp-setup/database-scripts/migration from 5.0 to 5.1/oracle10g-5.0_to_5.1.sql b/smp-webapp/src/main/smp-setup/database-scripts/migration from 5.0 to 5.1/oracle10g-5.0_to_5.1.sql index 1d8cc9923..d7119644e 100644 --- a/smp-webapp/src/main/smp-setup/database-scripts/migration from 5.0 to 5.1/oracle10g-5.0_to_5.1.sql +++ b/smp-webapp/src/main/smp-setup/database-scripts/migration from 5.0 to 5.1/oracle10g-5.0_to_5.1.sql @@ -35,7 +35,7 @@ create table SMP_DOCUMENT_PROPERTY ( DESCRIPTION varchar2(4000 char), PROPERTY_NAME varchar2(255 char), PROPERTY_TYPE varchar2(64 char), - PROPERTY_VALUE varchar2(1024 char), + PROPERTY_VALUE varchar2(4000 char), FK_DOCUMENT_ID number(19,0), primary key (ID) ); @@ -55,7 +55,7 @@ create table SMP_DOCUMENT_PROPERTY_AUD ( DESCRIPTION varchar2(4000 char), PROPERTY_NAME varchar2(255 char), PROPERTY_TYPE varchar2(64 char), - PROPERTY_VALUE varchar2(1024 char), + PROPERTY_VALUE varchar2(4000 char), FK_DOCUMENT_ID number(19,0), primary key (ID, REV) ); diff --git a/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb-drop.ddl b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb-drop.ddl index dec99d490..4b38709ce 100644 --- a/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb-drop.ddl +++ b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb-drop.ddl @@ -1,5 +1,5 @@ -- ------------------------------------------------------------------------ --- This file was generated by hibernate for SMP version 5.1-SNAPSHOT. +-- This file was generated by hibernate for SMP version 5.1-RC2-SNAPSHOT. -- ------------------------------------------------------------------------ diff --git a/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb.ddl b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb.ddl index 711c1f2e4..ea557b3d5 100644 --- a/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb.ddl +++ b/smp-webapp/src/main/smp-setup/database-scripts/mysql5innodb.ddl @@ -1,5 +1,5 @@ -- ------------------------------------------------------------------------ --- This file was generated by hibernate for SMP version 5.1-SNAPSHOT. +-- This file was generated by hibernate for SMP version 5.1-RC2-SNAPSHOT. -- ------------------------------------------------------------------------ @@ -192,7 +192,7 @@ DESCRIPTION varchar(4000) CHARACTER SET utf8 COLLATE utf8_bin comment 'Property description', PROPERTY_NAME varchar(255) CHARACTER SET utf8 COLLATE utf8_bin, PROPERTY_TYPE varchar(64) CHARACTER SET utf8 COLLATE utf8_bin, - PROPERTY_VALUE varchar(1024) CHARACTER SET utf8 COLLATE utf8_bin, + PROPERTY_VALUE varchar(4000) CHARACTER SET utf8 COLLATE utf8_bin, FK_DOCUMENT_ID bigint, primary key (ID) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -206,7 +206,7 @@ DESCRIPTION varchar(4000) CHARACTER SET utf8 COLLATE utf8_bin, PROPERTY_NAME varchar(255) CHARACTER SET utf8 COLLATE utf8_bin, PROPERTY_TYPE varchar(64) CHARACTER SET utf8 COLLATE utf8_bin, - PROPERTY_VALUE varchar(1024) CHARACTER SET utf8 COLLATE utf8_bin, + PROPERTY_VALUE varchar(4000) CHARACTER SET utf8 COLLATE utf8_bin, FK_DOCUMENT_ID bigint, primary key (ID, REV) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/smp-webapp/src/main/smp-setup/database-scripts/oracle10g-drop.ddl b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g-drop.ddl index 58c36e490..e68000749 100644 --- a/smp-webapp/src/main/smp-setup/database-scripts/oracle10g-drop.ddl +++ b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g-drop.ddl @@ -1,5 +1,5 @@ -- ------------------------------------------------------------------------ --- This file was generated by hibernate for SMP version 5.1-SNAPSHOT. +-- This file was generated by hibernate for SMP version 5.1-RC2-SNAPSHOT. -- ------------------------------------------------------------------------ diff --git a/smp-webapp/src/main/smp-setup/database-scripts/oracle10g.ddl b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g.ddl index 0db20288a..ef87df4d3 100644 --- a/smp-webapp/src/main/smp-setup/database-scripts/oracle10g.ddl +++ b/smp-webapp/src/main/smp-setup/database-scripts/oracle10g.ddl @@ -1,5 +1,5 @@ -- ------------------------------------------------------------------------ --- This file was generated by hibernate for SMP version 5.1-SNAPSHOT. +-- This file was generated by hibernate for SMP version 5.1-RC2-SNAPSHOT. -- ------------------------------------------------------------------------ create sequence SMP_ALERT_PROP_SEQ start with 1 increment by 1; @@ -318,7 +318,7 @@ create sequence SMP_USER_SEQ start with 1 increment by 1; DESCRIPTION varchar2(4000 char), PROPERTY_NAME varchar2(255 char), PROPERTY_TYPE varchar2(64 char), - PROPERTY_VALUE varchar2(1024 char), + PROPERTY_VALUE varchar2(4000 char), FK_DOCUMENT_ID number(19,0), primary key (ID) ); @@ -338,7 +338,7 @@ create sequence SMP_USER_SEQ start with 1 increment by 1; DESCRIPTION varchar2(4000 char), PROPERTY_NAME varchar2(255 char), PROPERTY_TYPE varchar2(64 char), - PROPERTY_VALUE varchar2(1024 char), + PROPERTY_VALUE varchar2(4000 char), FK_DOCUMENT_ID number(19,0), primary key (ID, REV) ); diff --git a/smp-webapp/src/main/smp-setup/smp.config.properties b/smp-webapp/src/main/smp-setup/smp.config.properties index 29e87fa26..157bcec8f 100644 --- a/smp-webapp/src/main/smp-setup/smp.config.properties +++ b/smp-webapp/src/main/smp-setup/smp.config.properties @@ -37,7 +37,7 @@ smp.jdbc.password=secret123 #smp.jdbc.driver = oracle.jdbc.driver.OracleDriver #smp.jdbc.url=jdbc:oracle:thin:@localhost:1521/xe #smp.jdbc.user=smp -#smp.jdbc.password=secret123 +#smp.jdbc.password=**** # ********************************* @@ -48,6 +48,10 @@ smp.jdbc.password=secret123 # tomcat datasource JNDI example # smp.datasource.jndi=java:comp/env/jdbc/eDeliverySmpDs +# ********************************* +# security folder +# ********************************* +# smp.security.folder=./smp/ # ********************************* # Logging properties @@ -69,4 +73,4 @@ smp.jdbc.password=secret123 # Locale folder # ********************************* # The locale folder contains the translations for the SMP web application. -# smp.libraries.folder=/data/smp/locales +# smp.locale.folder=/data/smp/locales -- GitLab