diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/ServiceMetadataConverter.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/ServiceMetadataConverter.java index ba80b5245c5af3b26175e1ca7aa2f8a21a904b6c..fc40483895d58faef37c613d41a0bf301b04227a 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/ServiceMetadataConverter.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/conversion/ServiceMetadataConverter.java @@ -99,22 +99,6 @@ public class ServiceMetadataConverter { try { Document serviceMetadataDoc = parse(serviceMetadataXml); ServiceMetadata serviceMetadata = getUnmarshaller().unmarshal(serviceMetadataDoc, ServiceMetadata.class).getValue(); -/* - if (serviceMetadata!=null - && serviceMetadata.getServiceInformation()!=null - && serviceMetadata.getServiceInformation().getParticipantIdentifier()!=null - && StringUtils.isBlank(serviceMetadata.getServiceInformation().getParticipantIdentifier().getScheme()) - && StringUtils.startsWithAny(serviceMetadata.getServiceInformation().getParticipantIdentifier().getValue(), - Identifiers.EBCORE_IDENTIFIER_PREFIX, - "::"+Identifiers.EBCORE_IDENTIFIER_PREFIX)){ - // normalize participant identifier - LOG.info("Normalize ebCore identifier: " + serviceMetadata.getServiceInformation().getParticipantIdentifier().getValue()); - ParticipantIdentifierType participantIdentifierType = Identifiers.asParticipantId( - serviceMetadata.getServiceInformation().getParticipantIdentifier().getValue(),allowEmptyParticipantScheme); - - serviceMetadata.getServiceInformation().setParticipantIdentifier(participantIdentifierType); - }*/ - return serviceMetadata; } catch (SAXException | IOException | ParserConfigurationException | JAXBException ex) { throw new SMPRuntimeException(INVALID_SMD_XML, ex, ExceptionUtils.getRootCauseMessage(ex)); diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/exceptions/ErrorCode.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/exceptions/ErrorCode.java index 2f8a9356e4690ab8be8abd50f842c08b36b8973d..a15f4ce7bd2ce66a26a91dcc86ed08371d0250b2 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/exceptions/ErrorCode.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/exceptions/ErrorCode.java @@ -44,7 +44,7 @@ public enum ErrorCode { ILLEGAL_STATE_SMD_MULTIPLE_ENTRY (500,"SMP:140",ErrorBusinessCode.TECHNICAL,"More than one service metadata ( doc. id: %s, doc. sch.: '%s') for participant ( part. id %s, part. sch. : '%s') is defined in database!"), METADATA_NOT_EXISTS(404,"SMP:141",ErrorBusinessCode.NOT_FOUND,"ServiceMetadata not found (part. id: '%s', part. sch.: '%s',doc. id: '%s', doc. sch.: '%s')!"), SMD_NOT_EXISTS_FOR_DOMAIN(404,"SMP:142",ErrorBusinessCode.NOT_FOUND,"ServiceMetadata not found for domain (domain: %s, part. id: '%s', part. sch.: '%s')!"), - INVALID_SMD_XML (400,"SMP:143",ErrorBusinessCode.XSD_INVALID,"Invalid service metada. Error: %s"), + INVALID_SMD_XML (400,"SMP:143",ErrorBusinessCode.XSD_INVALID,"Invalid service metadata. Error: %s"), INVALID_SMD_DOCUMENT_DATA(400,"SMP:143",ErrorBusinessCode.INVALID_INPUT_DATA,"XML serviceMetadata document (doc. id: '%s', doc. sch.: '%s') " + "do not match metadata request (doc. id: '%s', doc. sch.: '%s')."), ILLEGAL_STATE_SMD_ON_MULTIPLE_SGD (500,"SMP:144",ErrorBusinessCode.TECHNICAL,"Found than one service group domain for metadata id [%s] and user id [%s]!"), diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java index 0b02b8eb6b2506631fe948a90956f92992e2f3f5..f07fe43e857318c5099133cffd5fd4802d3e2583 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java @@ -18,6 +18,7 @@ import eu.europa.ec.edelivery.smp.services.SMLIntegrationService; import eu.europa.ec.edelivery.smp.services.ui.filters.ServiceGroupFilter; import eu.europa.ec.edelivery.smp.utils.SessionSecurityUtils; import eu.europa.ec.smp.api.exceptions.XmlInvalidAgainstSchemaException; +import eu.europa.ec.smp.api.validators.BdxSmpOasisValidator; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.oasis_open.docs.bdxr.ns.smp._2016._05.DocumentIdentifier; @@ -519,15 +520,24 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service } catch (UnsupportedEncodingException e) { throw new SMPRuntimeException(INVALID_ENCODING, "UTF-8"); } + try { + BdxSmpOasisValidator.validateXSD(buff); + } catch (XmlInvalidAgainstSchemaException e) { + throw new SMPRuntimeException(INVALID_SMD_XML, ExceptionUtils.getRootCauseMessage(e)); + } + ServiceMetadata smd = ServiceMetadataConverter.unmarshal(buff); - DocumentIdentifier di = caseSensitivityNormalizer.normalize(smd.getServiceInformation().getDocumentIdentifier()); - if (Objects.equals(di.getScheme(), serviceMetadataRO.getDocumentIdentifierScheme()) - && Objects.equals(di.getValue(), serviceMetadataRO.getDocumentIdentifier())) { - return buff; - } else { - throw new SMPRuntimeException(INVALID_SMD_DOCUMENT_DATA, di.getValue(), di.getScheme(), - serviceMetadataRO.getDocumentIdentifier(), serviceMetadataRO.getDocumentIdentifierScheme()); + if (smd.getServiceInformation()!=null) { + DocumentIdentifier di = caseSensitivityNormalizer.normalize(smd.getServiceInformation().getDocumentIdentifier()); + if (Objects.equals(di.getScheme(), serviceMetadataRO.getDocumentIdentifierScheme()) + && Objects.equals(di.getValue(), serviceMetadataRO.getDocumentIdentifier())) { + + } else { + throw new SMPRuntimeException(INVALID_SMD_DOCUMENT_DATA, di.getValue(), di.getScheme(), + serviceMetadataRO.getDocumentIdentifier(), serviceMetadataRO.getDocumentIdentifierScheme()); + } } + return buff; } @@ -640,7 +650,6 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service } // if new check if service group already exist if (serviceGroup.getStatusAction() == EntityROStatus.NEW.getStatusNumber()){ - ParticipantIdentifierType normalizedParticipant = caseSensitivityNormalizer.normalizeParticipantIdentifier( serviceGroup.getParticipantScheme(), serviceGroup.getParticipantIdentifier()); diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataService.java index e058b221bca5650a36c2c2a97759b4cc2fc9e5e6..e3742cdab3c78014edebcd84df95d249db4a1f19 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataService.java @@ -20,7 +20,6 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import org.oasis_open.docs.bdxr.ns.smp._2016._05.DocumentIdentifier; import org.oasis_open.docs.bdxr.ns.smp._2016._05.ParticipantIdentifierType; import org.oasis_open.docs.bdxr.ns.smp._2016._05.ServiceMetadata; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -37,19 +36,17 @@ import static eu.europa.ec.edelivery.smp.exceptions.ErrorCode.INVALID_REQUEST; public class UIServiceMetadataService extends UIServiceBase<DBServiceMetadata, ServiceMetadataRO> { private static final SMPLogger LOG = SMPLoggerFactory.getLogger(UIServiceMetadataService.class); - @Autowired - DomainDao domainDao; - - @Autowired - ServiceMetadataDao serviceMetadataDao; - - - @Autowired - UserDao userDao; - - @Autowired - private CaseSensitivityNormalizer caseSensitivityNormalizer; + protected final DomainDao domainDao; + protected final ServiceMetadataDao serviceMetadataDao; + protected final UserDao userDao; + protected final CaseSensitivityNormalizer caseSensitivityNormalizer; + public UIServiceMetadataService(DomainDao domainDao, ServiceMetadataDao serviceMetadataDao, UserDao userDao, CaseSensitivityNormalizer caseSensitivityNormalizer) { + this.domainDao = domainDao; + this.serviceMetadataDao = serviceMetadataDao; + this.userDao = userDao; + this.caseSensitivityNormalizer = caseSensitivityNormalizer; + } @Override protected BaseDao<DBServiceMetadata> getDatabaseDao() { @@ -65,11 +62,11 @@ public class UIServiceMetadataService extends UIServiceBase<DBServiceMetadata, S serviceMetadataRO.setId(dbServiceMetadata.getId()); serviceMetadataRO.setDocumentIdentifier(dbServiceMetadata.getDocumentIdentifier()); serviceMetadataRO.setDocumentIdentifierScheme(dbServiceMetadata.getDocumentIdentifierScheme()); - serviceMetadataRO.setXmlContent(getConvertServiceMetadataToString( serviceMetadataId, dbServiceMetadata.getXmlContent())); + serviceMetadataRO.setXmlContent(getConvertServiceMetadataToString(serviceMetadataId, dbServiceMetadata.getXmlContent())); return serviceMetadataRO; } - private String getConvertServiceMetadataToString(Long id, byte[] extension){ + private String getConvertServiceMetadataToString(Long id, byte[] extension) { try { return new String(extension, "UTF-8"); } catch (UnsupportedEncodingException e) { @@ -106,6 +103,15 @@ public class UIServiceMetadataService extends UIServiceBase<DBServiceMetadata, S return serviceMetadataRO; } + + DocumentIdentifier headerDI = caseSensitivityNormalizer.normalizeDocumentIdentifier( + serviceMetadataRO.getDocumentIdentifierScheme(), + serviceMetadataRO.getDocumentIdentifier()); + ParticipantIdentifierType headerPI = caseSensitivityNormalizer.normalizeParticipantIdentifier( + serviceMetadataRO.getParticipantScheme(), + serviceMetadataRO.getParticipantIdentifier()); + + // validate by schema try { BdxSmpOasisValidator.validateXSD(buff); @@ -116,34 +122,37 @@ public class UIServiceMetadataService extends UIServiceBase<DBServiceMetadata, S // validate data ServiceMetadata smd = ServiceMetadataConverter.unmarshal(buff); - DocumentIdentifier xmlDI = caseSensitivityNormalizer.normalize(smd.getServiceInformation().getDocumentIdentifier()); - DocumentIdentifier headerDI = caseSensitivityNormalizer.normalizeDocumentIdentifier(serviceMetadataRO.getDocumentIdentifierScheme(), - serviceMetadataRO.getDocumentIdentifier()); - ParticipantIdentifierType xmlPI = caseSensitivityNormalizer.normalize(smd.getServiceInformation().getParticipantIdentifier()); - ParticipantIdentifierType headerPI = caseSensitivityNormalizer.normalizeParticipantIdentifier( - serviceMetadataRO.getParticipantScheme(), - serviceMetadataRO.getParticipantIdentifier()); + if (smd.getRedirect() != null) { + if (StringUtils.isBlank(smd.getRedirect().getHref())) { + serviceMetadataRO.setErrorMessage("Redirect URL must must be empty!"); + return serviceMetadataRO; + } + } + if (smd.getServiceInformation() != null) { + DocumentIdentifier xmlDI = caseSensitivityNormalizer.normalize(smd.getServiceInformation().getDocumentIdentifier()); + ParticipantIdentifierType xmlPI = caseSensitivityNormalizer.normalize(smd.getServiceInformation().getParticipantIdentifier()); + if (!xmlDI.equals(headerDI)) { + serviceMetadataRO.setErrorMessage("Document identifier and scheme do not match!"); + return serviceMetadataRO; + } - if (serviceMetadataRO.getStatusAction() == EntityROStatus.NEW.getStatusNumber()){ + if (!xmlPI.equals(headerPI)) { + serviceMetadataRO.setErrorMessage("Participant identifier and scheme do not match!"); + return serviceMetadataRO; + } + } + + if (serviceMetadataRO.getStatusAction() == EntityROStatus.NEW.getStatusNumber()) { // check if service metadata already exists Optional<DBServiceMetadata> exists = serviceMetadataDao.findServiceMetadata(headerPI.getValue(), headerPI.getScheme(), headerDI.getValue(), headerDI.getScheme()); - if (exists.isPresent()){ + if (exists.isPresent()) { serviceMetadataRO.setErrorMessage("Document identifier and scheme already exist in database!"); return serviceMetadataRO; } } - if (!xmlDI.equals(headerDI)) { - serviceMetadataRO.setErrorMessage("Document identifier and scheme do not match!"); - return serviceMetadataRO; - } - - if (!xmlPI.equals(headerPI)) { - serviceMetadataRO.setErrorMessage("Participant identifier and scheme do not match!"); - return serviceMetadataRO; - } } return serviceMetadataRO; } diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/conversion/ServiceMetadataConverterTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/conversion/ServiceMetadataConverterTest.java index 8ef7b5df499c5cefc344b6080af59509a681af24..cbd27b79bce14d8d3ec08c6d4dff25e418030fad 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/conversion/ServiceMetadataConverterTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/conversion/ServiceMetadataConverterTest.java @@ -105,7 +105,7 @@ public class ServiceMetadataConverterTest { public void testUnmarshalMalformedInput() throws ParserConfigurationException, IOException, SAXException, JAXBException { expectedExeption.expect(SMPRuntimeException.class); - expectedExeption.expectMessage(Matchers.startsWith("Invalid service metada. Error")); + expectedExeption.expectMessage(Matchers.startsWith("Invalid service metadata. Error")); //when ServiceMetadataConverter.unmarshal("this is malformed XML body".getBytes()); } @@ -148,7 +148,7 @@ public class ServiceMetadataConverterTest { public void testToSignedServiceMetadataDocumentMalformedInput() throws ParserConfigurationException, IOException, SAXException, JAXBException { expectedExeption.expect(SMPRuntimeException.class); - expectedExeption.expectMessage(Matchers.startsWith("Invalid service metada. Error:")); + expectedExeption.expectMessage(Matchers.startsWith("Invalid service metadata. Error:")); //when ServiceMetadataConverter.toSignedServiceMetadataDocument("this is malformed XML body".getBytes()); } diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataServiceTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataServiceTest.java index c39be2288445bdf48dda44415d56fa3ac04620bd..7ec4adeacda723fd21a38b70cd399e5bee1aae31 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataServiceTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceMetadataServiceTest.java @@ -56,6 +56,38 @@ public class UIServiceMetadataServiceTest extends AbstractServiceIntegrationTest assertNull(smv.getErrorMessage()); } + @Test + public void validateServiceMetadataRedirectValid() { + DBServiceMetadata md = TestDBUtils.createDBServiceMetadataRedirect("docId", "docSch", "http://10.1.1.10:1027/test-service-data"); + + ServiceMetadataValidationRO smv = new ServiceMetadataValidationRO(); + smv.setDocumentIdentifier(md.getDocumentIdentifier()); + smv.setDocumentIdentifierScheme(md.getDocumentIdentifierScheme()); + smv.setParticipantIdentifier("partId"); + smv.setParticipantScheme("partSch"); + smv.setXmlContent(new String(md.getXmlContent())); + + smv = testInstance.validateServiceMetadata(smv); + assertNull(smv.getErrorMessage()); + } + + @Test + public void validateServiceMetadataRedirectInvalid() { + DBServiceMetadata md = TestDBUtils.createDBServiceMetadataRedirect("docId", "docSch", ""); + + ServiceMetadataValidationRO smv = new ServiceMetadataValidationRO(); + smv.setDocumentIdentifier(md.getDocumentIdentifier()); + smv.setDocumentIdentifierScheme(md.getDocumentIdentifierScheme()); + smv.setParticipantIdentifier("partId"); + smv.setParticipantScheme("partSch"); + smv.setXmlContent(new String(md.getXmlContent())); + + smv = testInstance.validateServiceMetadata(smv); + assertNotNull(smv.getErrorMessage()); + assertEquals("Redirect URL must must be empty!", smv.getErrorMessage()); + } + + @Test public void validateServiceMetadataParticipantNotMatch() { DBServiceMetadata md = TestDBUtils.createDBServiceMetadata("partId", "partSch"); diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java index c67dbbd7e990001f5d901918bc044544bd5f6c52..1b5f3d9f1f868dcffd8fdbf2fb0f4f9318e01a19 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestConstants.java @@ -58,10 +58,16 @@ public class TestConstants { public static final String CERT_USER="CN=common name,O=org,C=BE:0000000000000066"; public static final String CERT_USER_ENCODED="CN%3Dcommon%20name%2CO%3Dorg%2CC%3DBE%3A0000000000000066"; - // parameter: custom string as conntent + // parameter: custom string as content public static final String SIMPLE_EXTENSION_XML ="<Extension xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\"><ex:dummynode xmlns:ex=\"http://test.eu\">Sample not mandatory extension: %s</ex:dummynode></Extension>"; //5 parameters: ParticipantScheme, ParticipantIdentifier, DocumentScheme, DocumentIdentifier, custom value public static final String SIMPLE_DOCUMENT_XML ="<ServiceMetadata xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\"><ServiceInformation><ParticipantIdentifier scheme=\"%s\">%s</ParticipantIdentifier><DocumentIdentifier scheme=\"%s\">%s</DocumentIdentifier><ProcessList><Process><ProcessIdentifier scheme=\"cenbii-procid-ubl\">urn:www.cenbii.eu:profile:bii04:ver1.0</ProcessIdentifier><ServiceEndpointList><Endpoint transportProfile=\"bdxr-transport-ebms3-as4-v1p0\"><EndpointURI>http://localhost:8080/domibus-weblogic/services/msh</EndpointURI><RequireBusinessLevelSignature>true</RequireBusinessLevelSignature><ServiceActivationDate>2003-01-01T00:00:00</ServiceActivationDate><ServiceExpirationDate>2099-05-01T00:00:00</ServiceExpirationDate>" + "<Certificate>VGhpcyBpcyB0ZXN0IGNlcnRpZmljYXRlIGlzIHlvdSBiZWxpZXZlIG9yIG5vdC4=</Certificate><ServiceDescription>Sample description of %s</ServiceDescription><TechnicalContactUrl>https://example.com</TechnicalContactUrl></Endpoint></ServiceEndpointList></Process></ProcessList></ServiceInformation></ServiceMetadata>"; + public static final String SIMPLE_REDIRECT_DOCUMENT_XML ="<ServiceMetadata xmlns=\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\">" + + " <Redirect href=\"%s\">" + + " <CertificateUID>smptest</CertificateUID>" + + " </Redirect>" + + "</ServiceMetadata>"; + } diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java index 4e0bbf18f20dc605717c9800d8780d46ad0db5a2..0ba18573bcf0992ecc7e49abaec8d8a16a52f620 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/testutil/TestDBUtils.java @@ -8,8 +8,7 @@ import eu.europa.ec.edelivery.smp.data.ui.enums.AlertTypeEnum; import java.time.OffsetDateTime; import java.util.UUID; -import static eu.europa.ec.edelivery.smp.testutil.TestConstants.SIMPLE_DOCUMENT_XML; -import static eu.europa.ec.edelivery.smp.testutil.TestConstants.SIMPLE_EXTENSION_XML; +import static eu.europa.ec.edelivery.smp.testutil.TestConstants.*; public class TestDBUtils { @@ -49,6 +48,14 @@ public class TestDBUtils { return grp; } + public static DBServiceMetadata createDBServiceMetadataRedirect(String docId, String docSch, String url) { + DBServiceMetadata grp = new DBServiceMetadata(); + grp.setDocumentIdentifier(docId); + grp.setDocumentIdentifierScheme(docSch); + grp.setXmlContent(generateRedirectDocumentSample(url)); + return grp; + } + public static byte[] generateDocumentSample(String partcId, String partcSch, String docId, String docSch, String desc) { return String.format(SIMPLE_DOCUMENT_XML, partcSch, partcId, docSch, docId, desc).getBytes(); } @@ -57,6 +64,11 @@ public class TestDBUtils { return String.format(SIMPLE_EXTENSION_XML, UUID.randomUUID().toString()).getBytes(); } + public static byte[] generateRedirectDocumentSample(String url) { + return String.format(SIMPLE_REDIRECT_DOCUMENT_XML, url).getBytes(); + + } + public static DBServiceGroup createDBServiceGroup(String id, String sch) { return createDBServiceGroup(id, sch, true); }