diff --git a/Jenkinsfile b/Jenkinsfile index 258cfa2497436f696c9e9e7216286f18ca3af206..6956b9f9ee4a811d6e629efc774eccb46fd3bdbb 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -213,22 +213,23 @@ pipeline { } } - stage ('OWASP Dependency-Check Vulnerabilities') { + stage ('Deploy SBOM to DependencyTrack') { steps { - dependencyCheck additionalArguments: ''' - -o "./" - -s "./" - -f "ALL" - -d /dependency-check-data - --suppression dependency-check-supressions.xml - --disableKnownExploited - --noupdate - --disableArchive - --prettyPrint''', odcInstallation: 'dependency-check-owasp' - - dependencyCheckPublisher pattern: 'dependency-check-report.xml' + script { + IMAGE_TAG = generateImageTag() + + configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) { + withCredentials([string(credentialsId: 'dependency-track-api-key', variable: 'API_KEY')]) { + + catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { + sh "mvn --no-transfer-progress -s $MAVEN_SETTINGS io.github.pmckeown:dependency-track-maven-plugin:upload-bom -Ddependency-track.apiKey=$API_KEY -Ddependency-track.projectVersion=${IMAGE_TAG} -Ddependency-track.dependencyTrackBaseUrl=https://dependency-track.ozg-sh.de" + } + } + } + } } } + } post { failure { diff --git a/common/src/test/java/de/ozgcloud/eingang/common/formdata/IncomingFileGroupTestFactory.java b/common/src/test/java/de/ozgcloud/eingang/common/formdata/IncomingFileGroupTestFactory.java index bdc37befd95752882bb96a2d809725d2259527ba..cc2845a31a5edcb9d0a459db0cb4e8db30043e40 100644 --- a/common/src/test/java/de/ozgcloud/eingang/common/formdata/IncomingFileGroupTestFactory.java +++ b/common/src/test/java/de/ozgcloud/eingang/common/formdata/IncomingFileGroupTestFactory.java @@ -26,6 +26,13 @@ package de.ozgcloud.eingang.common.formdata; import java.util.List; public class IncomingFileGroupTestFactory { + public static final String XDOMEA_XML_NAME = "xdomea.xml"; + public static final String REPR_XML_NAME = "repr.xml"; + public static final String REPR_PDF_NAME = "repr.pdf"; + public static final String ATTATCHMENT_XML_NAME = "att.xml"; + public static final String ATTATCHMENT_PNG_NAME = "att.png"; + public static final String ATTATCHMENT_PDF_NAME = "att.pdf"; + public static final String INCOMING_FILE_ID = "xxx"; public static final String ID = "id"; public static final String FILE_REF1 = "FileRef1"; diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapper.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapper.java index 3e0ed8c3336fe365c2f8779cf1d6ecf98d37719f..29e2c0834d9a05e11519f371cdd2686faa549ed4 100644 --- a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapper.java +++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapper.java @@ -51,7 +51,10 @@ public class MantelantragZustaendigeStelleMapper implements FormBasedMapper { List<String> getIdentifierList() { return Binder.get(environment) .bind("ozgcloud.xta.identifiers", Bindable.listOf(String.class)) - .orElseGet(Collections::emptyList); + .orElseGet(Collections::emptyList) + .stream() + .map(String::toLowerCase) + .toList(); } @Override @@ -143,7 +146,7 @@ public class MantelantragZustaendigeStelleMapper implements FormBasedMapper { } private String getXtaIdentifierOfSlot(Map<String, Object> fieldMap, int slotIndex) { - return getFieldByKeyOrEmpty(fieldMap, getNameForSlotIndex(ZUSTELLUNG_NACHRICHTENBROKER_FIELD, slotIndex)); + return getFieldByKeyOrEmpty(fieldMap, getNameForSlotIndex(ZUSTELLUNG_NACHRICHTENBROKER_FIELD, slotIndex)).toLowerCase(); } String getNameForSlotIndex(String name, int slotIndex) { diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapperTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapperTest.java index 2cad108d2ae30f76782b0c9ddfdd934becb9be37..ffc88cabe17fb7e087abab038e13dfff3b8b14d1 100644 --- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapperTest.java +++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapperTest.java @@ -31,9 +31,10 @@ import de.ozgcloud.eingang.common.formdata.FormHeaderTestFactory; import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle; class MantelantragZustaendigeStelleMapperTest { - private final static String TARGET_OEID = "123456"; + private static final String TARGET_OEID = "123456"; private static final String IDENTIFIER = "gea:test"; private static final String IDENTIFIER2 = "dfad:test"; + private static final String IDENTIFIER2UPPERCASE = "dfad:Test"; private static final List<String> IDENTIFIERS = List.of(IDENTIFIER, IDENTIFIER2, "aa:other"); @Spy @@ -315,6 +316,17 @@ class MantelantragZustaendigeStelleMapperTest { assertThat(resultSlotIndex).isEqualTo(slotIndex); } + @DisplayName("should return matching slot with upper-/lowercase difference in identifiers") + @ParameterizedTest + @ValueSource(ints = { 0, 1, 2 }) + void shouldReturnMatchingSlotWithUppercaseIdentifier(int slotIndex) { + fieldMap.put(getZustaendigeStelleName(slotIndex), IDENTIFIER2UPPERCASE); + + var resultSlotIndex = mapper.findSlotIndex(fieldMap); + + assertThat(resultSlotIndex).isEqualTo(slotIndex); + } + private String getZustaendigeStelleName(int slotIndex) { return mapper.getNameForSlotIndex(ZUSTELLUNG_NACHRICHTENBROKER_FIELD, slotIndex); } diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapper.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapper.java index 918de441398cb8e34af14340063760b6c1cd640f..6457a44999996af0d349119bcc365724f0541bb7 100644 --- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapper.java +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapper.java @@ -27,11 +27,36 @@ public class XdomeaMessageDataMapper { public RepresentationsAttachmentsPair mapIncomingFilesToRepresentationsAttachmentsPair(List<IncomingFile> incomingFileList) { var xdomeaMessageData = mapIncomingFilesToXdomeaMessageData(incomingFileList); return RepresentationsAttachmentsPair.builder() - .representations(getPairRepresentations(xdomeaMessageData)) - .attachments(xdomeaMessageData.attachments()) + .representations(removeUuidPrefixFromIncomingFiles(getPairRepresentations(xdomeaMessageData))) + .attachments(removeUuidPrefixFromIncomingFileGroups(xdomeaMessageData.attachments())) .build(); } + private List<IncomingFileGroup> removeUuidPrefixFromIncomingFileGroups(List<IncomingFileGroup> incomingFileGroups) { + return incomingFileGroups.stream() + .map(group -> group.toBuilder() + .clearFiles() + .files(removeUuidPrefixFromIncomingFiles(group.getFiles())) + .build()) + .toList(); + } + + private List<IncomingFile> removeUuidPrefixFromIncomingFiles(List<IncomingFile> incomingFiles) { + return incomingFiles.stream() + .map(this::removeUuidPrefixFromIncomingFile) + .toList(); + } + + private IncomingFile removeUuidPrefixFromIncomingFile(IncomingFile incomingFile) { + return incomingFile.toBuilder() + .name(removeUuidPrefix(incomingFile.getName())) + .build(); + } + + private String removeUuidPrefix(String name) { + return name.replaceFirst("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}_", ""); + } + private List<IncomingFile> getPairRepresentations(XdomeaMessageData xdomeaMessageData) { return Stream.concat( Stream.of(xdomeaMessageData.metadataFile()), diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java index d3951cc43e48b420f69ec145aeb6ad0a9e0c405a..8041810ed8fbc3222fd10c06a4e64a6a760e9bf4 100644 --- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java @@ -79,26 +79,4 @@ class XtaIncomingFilesMapper { return Stream.of(incomingFile); } } - - RepresentationsAttachmentsPair removeLeadingUUIDsFromNames(RepresentationsAttachmentsPair representationsAttachmentsPair) { - var representations = representationsAttachmentsPair.representations().stream().map(this::removeLeadingUUID).toList(); - var attachments = representationsAttachmentsPair.attachments().stream().map(this::removeLeadingUUIDs).toList(); - return new RepresentationsAttachmentsPair( - representations, - attachments - ); - } - - private IncomingFileGroup removeLeadingUUIDs(IncomingFileGroup incomingFileGroup) { - var incomingFilesWithoutUuid = incomingFileGroup.getFiles().stream().map(this::removeLeadingUUID).toList(); - return incomingFileGroup.toBuilder().clearFiles().files(incomingFilesWithoutUuid).build(); - } - - private IncomingFile removeLeadingUUID(IncomingFile incomingFile) { - return incomingFile.toBuilder().name(removeLeadingUUID(incomingFile.getName())).build(); - } - - private String removeLeadingUUID(String name) { - return name.replaceAll("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}_", ""); - } } diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java index b793efc1230781d491b1436b04ccefad6d68698b..d5a8d537c84074c7a8bd5849fd744b320eeb3820 100644 --- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java +++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java @@ -70,9 +70,8 @@ class XtaService { var msg = remoteService.getMessage(metaData.getMessageId()); var incomingFiles = xtaIncomingFilesMapper.toIncomingFiles(msg.getMessageFiles()); var representationsAttachmentsPair = getRepresentationsAttachmentsPair(metaData, incomingFiles); - var representationsAttachmentsPairsWithoutUUIDs = xtaIncomingFilesMapper.removeLeadingUUIDsFromNames(representationsAttachmentsPair); - var formData = mapper.toFormData(representationsAttachmentsPairsWithoutUUIDs, metaData, vorgangNummerSupplier); + var formData = mapper.toFormData(representationsAttachmentsPair, metaData, vorgangNummerSupplier); return addAttachments(msg, formData); } diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapperTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapperTest.java index 94f24a83b05a8f49b26ad434438311cb8368f9fe..11942226183afeda3ceba1e5d8bebd59ce173728 100644 --- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapperTest.java +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapperTest.java @@ -1,10 +1,12 @@ package de.ozgcloud.eingang.xdomea; +import static de.ozgcloud.eingang.common.formdata.IncomingFileGroupTestFactory.*; import static de.ozgcloud.eingang.xdomea.XdomeaMessageDataMapper.*; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; +import java.util.Collection; import java.util.List; import java.util.stream.Stream; @@ -12,12 +14,15 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import de.ozgcloud.eingang.common.errorhandling.TechnicalException; import de.ozgcloud.eingang.common.formdata.IncomingFile; +import de.ozgcloud.eingang.common.formdata.IncomingFileGroup; import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory; class XdomeaMessageDataMapperTest { @@ -29,6 +34,47 @@ class XdomeaMessageDataMapperTest { @Mock private XdomeaXMLValueReader valueReader; + @DisplayName("map incoming files to representations attachments pair") + @Nested + class TestMapIncomingFilesToRepresentationsAttachmentsPair { + + @Mock + private List<IncomingFile> incomingFileList; + + @DisplayName("should map representations") + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void shouldMapRepresentations(boolean useUuidPrefix) { + mockXdomeaMessageData(useUuidPrefix); + + var pair = fileClassifier.mapIncomingFilesToRepresentationsAttachmentsPair(incomingFileList); + + var representationFilenames = pair.representations().stream().map(IncomingFile::getName).toList(); + assertThat(representationFilenames).containsExactly(XDOMEA_XML_NAME, REPR_XML_NAME, REPR_PDF_NAME); + } + + @DisplayName("should map attachments") + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void shouldMapAttachments(boolean useUuidPrefix) { + mockXdomeaMessageData(useUuidPrefix); + + var pair = fileClassifier.mapIncomingFilesToRepresentationsAttachmentsPair(incomingFileList); + + var attachmentFilenames = pair.attachments().stream() + .map(IncomingFileGroup::getFiles) + .flatMap(Collection::stream) + .map(IncomingFile::getName) + .toList(); + assertThat(attachmentFilenames).containsExactly(ATTATCHMENT_XML_NAME, ATTATCHMENT_PNG_NAME, ATTATCHMENT_PDF_NAME); + } + + private void mockXdomeaMessageData(boolean useUuidPrefix) { + doReturn(XdomeaMessageDataTestFactory.create(useUuidPrefix)).when(fileClassifier).mapIncomingFilesToXdomeaMessageData(incomingFileList); + } + + } + @DisplayName("find Xdomea XML file") @Nested class TestFindXdomeaXmlFile { @@ -92,13 +138,6 @@ class XdomeaMessageDataMapperTest { @Nested class TestClassifyAttachmentsAndRepresentations { - private static final String XDOMEA_XML_NAME = "xdomea.xml"; - private static final String REPR_XML_NAME = "repr.xml"; - private static final String REPR_PDF_NAME = "repr.pdf"; - private static final String ATTATCHMENT_XML_NAME = "att.xml"; - private static final String ATTATCHMENT_PNG_NAME = "att.png"; - private static final String ATTATCHMENT_PDF_NAME = "att.pdf"; - @Mock private IncomingFile xdomeaXMLFile; @@ -131,7 +170,6 @@ class XdomeaMessageDataMapperTest { var classification = doClassify(); var primaryDocument = classification.metadataFile(); - assertThat(primaryDocument.getName()).isEqualTo(XDOMEA_XML_NAME); } diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataTestFactory.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataTestFactory.java index 90a659b8ddddb9cbef12e8c54da9f33ee213ab74..c9064a930eebc2837fa562b2070634886a03ad4e 100644 --- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataTestFactory.java +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataTestFactory.java @@ -1,19 +1,45 @@ package de.ozgcloud.eingang.xdomea; -import java.util.List; +import static de.ozgcloud.eingang.common.formdata.IncomingFileGroupTestFactory.*; + +import java.util.UUID; +import java.util.stream.Stream; import de.ozgcloud.eingang.common.formdata.IncomingFileGroup; import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory; public class XdomeaMessageDataTestFactory { - public static XdomeaMessageData create() { - return createBuilder().build(); + public static XdomeaMessageData create(boolean useUuidPrefix) { + return createBuilder(useUuidPrefix).build(); } - public static XdomeaMessageData.XdomeaMessageDataBuilder createBuilder() { + public static XdomeaMessageData.XdomeaMessageDataBuilder createBuilder(boolean useUuidPrefix) { + var incomingFiles = Stream.of( + XDOMEA_XML_NAME, + REPR_XML_NAME, + REPR_PDF_NAME, + ATTATCHMENT_XML_NAME, + ATTATCHMENT_PNG_NAME, + ATTATCHMENT_PDF_NAME + ) + .map(name -> useUuidPrefix ? withUUIDPrefix(name) : name) + .map(name -> IncomingFileTestFactory.createBuilder().name(name).build()) + .toList(); + return XdomeaMessageData.builder() - .metadataFile(IncomingFileTestFactory.createBuilder().name("xdomea-primary-document.xml").build()) - .representations(List.of(IncomingFileTestFactory.create())) - .attachment(IncomingFileGroup.builder().file(IncomingFileTestFactory.create()).build()); + .metadataFile(incomingFiles.getFirst()) + .representations(incomingFiles.subList(1, 3)) + .attachments(incomingFiles.subList(3, 6).stream() + .map(incomingFile -> IncomingFileGroup.builder() + .name("group-name") + .file(incomingFile) + .build()) + .toList() + ); } + + private static String withUUIDPrefix(String name) { + return UUID.randomUUID() + "_" + name; + } + } diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java index 26409741a512760ce774bdfa8d7a6be3489767f2..1ae7d692986e14c57e983b2af836c8b637c33c92 100644 --- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java @@ -151,31 +151,4 @@ class XtaIncomingFilesMapperTest { .isTrue(); } - @Nested - class TestRemoveLeadingUUIDsFromNames { - - @Test - void shouldRemoveLeadingUUIDFromName() { - String nameWithLeadingUUID = UUID.randomUUID() + "_" + XtaFileTestFactory.NAME; - var xtaFile1 = XtaFileTestFactory.createBuilder().name(nameWithLeadingUUID).contentType("text/plain").build(); - var xtaFile2 = XtaFileTestFactory.createBuilder().contentType("text/plain").build(); - - var representationsAttachmentsPair = RepresentationsAttachmentsPairTestFactory.createBuilder() - .representations(List.of(mapper.toIncomingFile(xtaFile1), mapper.toIncomingFile(xtaFile2))) - .attachments(List.of(IncomingFileGroup.builder().files(List.of(mapper.toIncomingFile(xtaFile1), mapper.toIncomingFile(xtaFile2))).build())) - .build(); - - var mappedPair = mapper.removeLeadingUUIDsFromNames(representationsAttachmentsPair); - - assertThat(mappedPair.representations()).hasSize(2); - assertThat(mappedPair.representations().getFirst().getName()).isEqualTo(XtaFileTestFactory.NAME); - assertThat(mappedPair.representations().getLast().getName()).isEqualTo(XtaFileTestFactory.NAME); - - assertThat(mappedPair.attachments()).hasSize(1); - var attachments = mappedPair.attachments().getFirst().getFiles(); - assertThat(attachments).hasSize(2); - assertThat(attachments.getFirst().getName()).isEqualTo(XtaFileTestFactory.NAME); - assertThat(attachments.getLast().getName()).isEqualTo(XtaFileTestFactory.NAME); - } - } } diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java index 0e6caeb198b0fe96b74eff93af61546035fd0295..374d71632023fb10b42f1698b4b7c44d1e462445 100644 --- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java +++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java @@ -152,7 +152,6 @@ class XtaServiceTest { var incomingFiles = List.of(IncomingFileTestFactory.create(), IncomingFileTestFactory.create()); when(incomingFilesMapper.toIncomingFiles(message.getMessageFiles())).thenReturn(incomingFiles); doReturn(classification).when(service).getRepresentationsAttachmentsPair(messageMetaData, incomingFiles); - when(incomingFilesMapper.removeLeadingUUIDsFromNames(classification)).thenReturn(classification); } @BeforeEach