diff --git a/vorgang-manager-server/pom.xml b/vorgang-manager-server/pom.xml index c50d1b2301e66944d8a5bc355c11786a2a3921ab..0c6f535369777e48782044894c76fc00eb140673 100644 --- a/vorgang-manager-server/pom.xml +++ b/vorgang-manager-server/pom.xml @@ -32,7 +32,7 @@ <parent> <groupId>de.ozgcloud.common</groupId> <artifactId>ozgcloud-common-parent</artifactId> - <version>4.3.1</version> + <version>4.3.2</version> <relativePath /> </parent> @@ -60,7 +60,7 @@ <notification-manager.version>2.12.0-SNAPSHOT</notification-manager.version> <collaboration-manager.version>0.4.0-OZG-6944-resolve-bean-conflict-SNAPSHOT</collaboration-manager.version> - <zip.version>2.11.1</zip.version> + <zip.version>2.11.5</zip.version> <jsoup.version>1.15.3</jsoup.version> <mongock.version>5.3.4</mongock.version> <testcontainer.version>1.17.3</testcontainer.version> diff --git a/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumITCase.java b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumITCase.java index d32ceb17e036e0a53256725a3551aada94097afd..51f3cdcefce8386b38119051129a0b6e11148b90 100644 --- a/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumITCase.java +++ b/vorgang-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumITCase.java @@ -21,9 +21,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.gridfs.GridFsTemplate; +import org.springframework.security.saml2.core.Saml2Error; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.annotation.DirtiesContext; +import com.google.protobuf.ByteString; + import de.ozgcloud.apilib.common.errorhandling.NotFoundException; import de.ozgcloud.common.test.DataITCase; import de.ozgcloud.common.test.TestUtils; @@ -33,7 +37,10 @@ import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; import de.ozgcloud.nachrichten.postfach.osi.ReplyOption; import de.ozgcloud.vorgang.VorgangManagerServerApplication; import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem; +import de.ozgcloud.vorgang.attached_item.VorgangAttachedItem.VorgangAttachedItemBuilder; import de.ozgcloud.vorgang.attached_item.VorgangAttachedItemTestFactory; +import de.ozgcloud.vorgang.files.GridFsTestFactory; +import de.ozgcloud.vorgang.files.OzgFileTestFactory; import de.ozgcloud.vorgang.servicekonto.PostfachAddressTestFactory; import de.ozgcloud.vorgang.servicekonto.ServiceKonto; import de.ozgcloud.vorgang.servicekonto.ServiceKontoTestFactory; @@ -64,6 +71,8 @@ class AntragraumITCase { private AntragraumGrpcService grpcService; @Autowired private MongoOperations mongoOperations; + @Autowired + private GridFsTemplate gridFsTemplate; @MockBean private Saml2Decrypter decrypter; @@ -74,6 +83,8 @@ class AntragraumITCase { void prepareDatabase() { mongoOperations.dropCollection(Vorgang.COLLECTION_NAME); mongoOperations.dropCollection(VorgangAttachedItem.COLLECTION_NAME); + mongoOperations.dropCollection("fs.files"); + mongoOperations.dropCollection("fs.chunks"); } @DisplayName("Find rueckfragen") @@ -188,7 +199,7 @@ class AntragraumITCase { } } - @DisplayName("Ger rueckfrage") + @DisplayName("Get rueckfrage") @Nested class TestGetRueckfrage { @@ -208,7 +219,7 @@ class AntragraumITCase { VorgangAttachedItem.COLLECTION_NAME); when(verifier.verify(any())).thenReturn(Collections.emptyList()); - when(decrypter.decryptTrustLevel(any())).thenReturn("STORK-QAA-Level-1"); + when(decrypter.decryptTrustLevel(any())).thenReturn(ServiceKontoTestFactory.TRUST_LEVEL); } @Test @@ -240,6 +251,167 @@ class AntragraumITCase { } } + @Nested + class TestGetAttachmentMetadata { + + private static final String SAML_TOKEN = TestUtils.loadTextFile("SamlResponse.xml"); + + @Mock + private StreamObserver<GrpcGetAttachmentMetadataResponse> responseObserver; + + @Captor + private ArgumentCaptor<GrpcGetAttachmentMetadataResponse> captor; + + private Vorgang savedVorgang; + private VorgangAttachedItem vorgangAttachedItem; + private VorgangAttachedItem vorgangAttachedItemOtherAttachment; + private String fileId; + + @BeforeEach + void prepareDatabase() { + fileId = gridFsTemplate.store(GridFsTestFactory.createUpload()).toString(); + savedVorgang = mongoOperations.save(createVorgang(TrustLevel.LEVEL_3), Vorgang.COLLECTION_NAME); + vorgangAttachedItem = mongoOperations.save(createPostfachNachrichtVorgangAttachedItem(savedVorgang.getId(), fileId), + VorgangAttachedItem.COLLECTION_NAME); + vorgangAttachedItemOtherAttachment = mongoOperations.save(createPostfachNachrichtVorgangAttachedItem(savedVorgang.getId()), + VorgangAttachedItem.COLLECTION_NAME); + } + + @Test + void shouldSendMetadata() { + when(verifier.verify(any())).thenReturn(Collections.emptyList()); + when(decrypter.decryptTrustLevel(any())).thenReturn(TrustLevel.LEVEL_3.getValue()); + when(decrypter.decryptPostfachId(any())).thenReturn(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE); + var request = GrpcGetAttachmentMetadataRequest.newBuilder() + .setSamlToken(SAML_TOKEN) + .setNachrichtId(vorgangAttachedItem.getId()) + .setFileId(fileId) + .build(); + var expectedMetadata = GrpcFileMetadata.newBuilder() + .setContentType(OzgFileTestFactory.CONTENT_TYPE) + .setName(OzgFileTestFactory.NAME) + .setSize(OzgFileTestFactory.CONTENT.length) + .build(); + + grpcService.getAttachmentMetadata(request, responseObserver); + + verify(responseObserver, timeout(30000)).onNext(captor.capture()); + assertThat(captor.getValue().getFileMetadata()).isEqualTo(expectedMetadata); + } + + @Test + void shouldFailDueToInvalidToken() { + when(verifier.verify(any())).thenReturn(List.of(new Saml2Error("invalid_signature", "Signature missing"))); + when(decrypter.decryptTrustLevel(any())).thenReturn(TrustLevel.LEVEL_3.getValue()); + when(decrypter.decryptPostfachId(any())).thenReturn(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE); + var request = GrpcGetAttachmentMetadataRequest.newBuilder() + .setSamlToken(SAML_TOKEN) + .setNachrichtId(vorgangAttachedItem.getId()) + .setFileId(fileId) + .build(); + + assertThatThrownBy(() -> grpcService.getAttachmentMetadata(request, responseObserver)) + .isInstanceOf(SecurityException.class) + .hasMessageContaining("Signature missing") + .hasMessageContaining("invalid_signature"); + + } + + @Test + void shouldFailDueIncorrectPostfachId() { + when(verifier.verify(any())).thenReturn(Collections.emptyList()); + when(decrypter.decryptTrustLevel(any())).thenReturn(TrustLevel.LEVEL_3.getValue()); + when(decrypter.decryptPostfachId(any())).thenReturn("wrong ID"); + var request = GrpcGetAttachmentMetadataRequest.newBuilder() + .setSamlToken(SAML_TOKEN) + .setNachrichtId(vorgangAttachedItem.getId()) + .setFileId(fileId) + .build(); + + assertThatThrownBy(() -> grpcService.getAttachmentMetadata(request, responseObserver)) + .isInstanceOf(NotFoundException.class) + .hasMessageContaining("PostfachNachricht") + .hasMessageContaining(vorgangAttachedItem.getId()); + } + + @Test + void shouldFailDueToTrustLevelTooLow() { + when(verifier.verify(any())).thenReturn(Collections.emptyList()); + when(decrypter.decryptTrustLevel(any())).thenReturn(TrustLevel.LEVEL_2.getValue()); + when(decrypter.decryptPostfachId(any())).thenReturn(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE); + var request = GrpcGetAttachmentMetadataRequest.newBuilder() + .setSamlToken(SAML_TOKEN) + .setNachrichtId(vorgangAttachedItem.getId()) + .setFileId(fileId) + .build(); + + assertThatThrownBy(() -> grpcService.getAttachmentMetadata(request, responseObserver)) + .isInstanceOf(NotFoundException.class) + .hasMessageContaining("PostfachNachricht") + .hasMessageContaining(vorgangAttachedItem.getId()); + } + + @Test + void shouldFailDueToFileIdNotInPostfachNachricht() { + when(verifier.verify(any())).thenReturn(Collections.emptyList()); + when(decrypter.decryptTrustLevel(any())).thenReturn(TrustLevel.LEVEL_3.getValue()); + when(decrypter.decryptPostfachId(any())).thenReturn(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE); + var request = GrpcGetAttachmentMetadataRequest.newBuilder() + .setSamlToken(SAML_TOKEN) + .setNachrichtId(vorgangAttachedItemOtherAttachment.getId()) + .setFileId(fileId) + .build(); + + assertThatThrownBy(() -> grpcService.getAttachmentMetadata(request, responseObserver)) + .isInstanceOf(NotFoundException.class) + .hasMessageContaining("PostfachNachricht") + .hasMessageContaining(vorgangAttachedItemOtherAttachment.getId()); + } + + } + + @Nested + class TestGetAttachmentContent { + + private static final String SAML_TOKEN = TestUtils.loadTextFile("SamlResponse.xml"); + + @Mock + private StreamObserver<GrpcGetAttachmentContentResponse> responseObserver; + + @Captor + private ArgumentCaptor<GrpcGetAttachmentContentResponse> captor; + + private Vorgang savedVorgang; + private VorgangAttachedItem vorgangAttachedItem; + private String fileId; + + @BeforeEach + void prepareDatabase() { + fileId = gridFsTemplate.store(GridFsTestFactory.createUpload()).toString(); + savedVorgang = mongoOperations.save(createVorgang(TrustLevel.LEVEL_3), Vorgang.COLLECTION_NAME); + vorgangAttachedItem = mongoOperations.save(createPostfachNachrichtVorgangAttachedItem(savedVorgang.getId(), fileId), + VorgangAttachedItem.COLLECTION_NAME); + } + + @Test + void shouldSendContent() { + when(verifier.verify(any())).thenReturn(Collections.emptyList()); + when(decrypter.decryptTrustLevel(any())).thenReturn(TrustLevel.LEVEL_3.getValue()); + when(decrypter.decryptPostfachId(any())).thenReturn(PostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE); + var request = GrpcGetAttachmentContentRequest.newBuilder() + .setSamlToken(SAML_TOKEN) + .setNachrichtId(vorgangAttachedItem.getId()) + .setFileId(fileId) + .build(); + var expectedContent = ByteString.copyFrom(OzgFileTestFactory.CONTENT); + + grpcService.getAttachmentContent(request, responseObserver); + + verify(responseObserver, timeout(30000)).onNext(captor.capture()); + assertThat(captor.getValue().getFileContent()).isEqualTo(expectedContent); + } + } + private Vorgang createVorgang(TrustLevel trustLevel) { return VorgangTestFactory.createBuilder() .id(null) @@ -252,15 +424,30 @@ class AntragraumITCase { return ServiceKontoTestFactory.createBuilder().type("BAYERN_ID").trustLevel(trustLevel.getValue()).build(); } + private VorgangAttachedItem createPostfachNachrichtVorgangAttachedItem(String vorgangId, String fileId) { + return createPostfachNachrichtVorgangAttachedItemBuilder(vorgangId) + .item(createBayernIdPostfachNachrichtItem(vorgangId, fileId)) + .build(); + } + private VorgangAttachedItem createPostfachNachrichtVorgangAttachedItem(String vorgangId) { + return createPostfachNachrichtVorgangAttachedItemBuilder(vorgangId).build(); + } + + private VorgangAttachedItemBuilder createPostfachNachrichtVorgangAttachedItemBuilder(String vorgangId) { return VorgangAttachedItemTestFactory.createBuilder() .id(null) .version(0) .vorgangId(vorgangId) .itemName("PostfachMail") .client("OzgCloud_NachrichtenManager") - .item(createBayernIdPostfachNachrichtItem(vorgangId)) - .build(); + .item(createBayernIdPostfachNachrichtItem(vorgangId)); + } + + private Map<String, Object> createBayernIdPostfachNachrichtItem(String vorgangId, String fileId) { + var nachrichtItem = createBayernIdPostfachNachrichtItem(vorgangId); + nachrichtItem.put("attachments", List.of(fileId)); + return nachrichtItem; } private Map<String, Object> createBayernIdPostfachNachrichtItem(String vorgangId) {