diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerConfiguration.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerConfiguration.java index 3371e12d71808d495f9114f486f3674dea49a5bf..26f1ff18efd89ac60df5af212f5f410cbb3a1732 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerConfiguration.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/NachrichtenManagerConfiguration.java @@ -15,8 +15,12 @@ public class NachrichtenManagerConfiguration { public static final String OZG_CLOUD_COMMAND_SERVICE_NAME = "nachrichten_OzgCloudCommandService"; public static final String NACHRICHTEN_VORGANG_SERVICE = "nachrichten_vorgangService"; + public static final String NACHRICHTEN_VORGANG_REMOTE_SERVICE = "nachrichten_vorgangRemoteService"; - @GrpcClient("command-manager") + public static final String GRPC_VORGANG_MANAGER_NAME = "vorgang-manager"; + public static final String GRPC_COMMAND_MANAGER_NAME = "command-manager"; + + @GrpcClient(GRPC_COMMAND_MANAGER_NAME) private CommandServiceGrpc.CommandServiceBlockingStub commandServiceStub; @Bean(OZG_CLOUD_COMMAND_SERVICE_NAME) diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumService.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumService.java index b2780c13b36ad72a1384fc440e789f1644483139..bbb328c92b80034e5edd6897b3b4f9f49c03fab7 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumService.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/antragraum/AntragraumService.java @@ -33,11 +33,14 @@ import java.util.stream.Stream; import jakarta.annotation.PostConstruct; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.opensaml.saml.saml2.core.Response; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Service; +import de.ozgcloud.apilib.common.datatypes.GenericId; +import de.ozgcloud.apilib.common.errorhandling.NotFoundException; import de.ozgcloud.nachrichten.NachrichtenManagerConfiguration; import de.ozgcloud.nachrichten.NachrichtenManagerProperties; import de.ozgcloud.nachrichten.common.vorgang.Vorgang; @@ -136,6 +139,7 @@ public class AntragraumService { public String sendRueckfrageAnswer(String samlToken, String rueckfrageId, PostfachNachricht nachricht) { verifyToken(samlToken); + verifyPostfachId(samlToken, nachricht); return postfachNachrichtService.persistAnswer(rueckfrageId, nachricht); } @@ -153,7 +157,11 @@ public class AntragraumService { public PostfachNachricht getRueckfrage(String samlToken, String id) { verifyToken(samlToken); - return nachrichtMapper.fromMapToPostfachMail(postfachNachrichtService.getById(id)); + var nachricht = nachrichtMapper.fromMapToPostfachMail(postfachNachrichtService.getById(id)); + + verifyPostfachId(samlToken, nachricht); + + return nachricht; } void verifyToken(String token) { @@ -163,6 +171,15 @@ public class AntragraumService { } } + void verifyPostfachId(String samlToken, PostfachNachricht nachricht) { + var vorgang = vorgangService.getVorgang(nachricht.getVorgangId()); + + if (!StringUtils.equals(vorgang.getPostfachId(), getPostfachId(samlToken))) { + LOG.info("PostfachId in token is not matching postfachId in vorgang."); + throw new NotFoundException(GenericId.from(nachricht.getId()), "PostfachNachricht"); + } + } + public boolean isAccessible(String samlToken, String trustLevel) { return getTrustLevel(samlToken).getIntValue() >= TrustLevel.fromString(trustLevel).getIntValue(); } diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/NachrichtenVorgangMapper.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/NachrichtenVorgangMapper.java index 087b161af912abd75372e845e51e8b546e620937..7dabcf055fafa85da493e8a5e54b6bb2da15e446 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/NachrichtenVorgangMapper.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/NachrichtenVorgangMapper.java @@ -1,14 +1,32 @@ package de.ozgcloud.nachrichten.common.vorgang; +import org.apache.commons.lang3.StringUtils; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.ReportingPolicy; +import de.ozgcloud.vorgang.vorgang.GrpcPostfachAddress; +import de.ozgcloud.vorgang.vorgang.GrpcVorgangHead; import de.ozgcloud.vorgang.vorgang.GrpcVorgangWithEingang; @Mapper(unmappedTargetPolicy = ReportingPolicy.WARN) interface NachrichtenVorgangMapper { @Mapping(target = "trustLevel", source = "vorgangWithEingang.header.serviceKonto.trustLevel") + @Mapping(target = "postfachId", expression = "java(getPostfachId(vorgangWithEingang.getHeader()))") Vorgang fromVorgangWithEingang(GrpcVorgangWithEingang vorgangWithEingang); -} + + default String getPostfachId(GrpcVorgangHead head) { + return head.getServiceKonto().getPostfachAddressesList().stream() + .map(this::getPostfachId).findFirst() + .orElse(StringUtils.EMPTY); + } + + default String getPostfachId(GrpcPostfachAddress address) { + return address.getIdentifier().getPropertyList().stream() + .filter(prop -> Vorgang.POSTFACH_ID_FIELD.equals(prop.getName())) + .map(prop -> prop.getValue(0)) + .findFirst() + .orElse(StringUtils.EMPTY); + } +} \ No newline at end of file diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/Vorgang.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/Vorgang.java index 713f4da191b6a75fa690f42ce20984c2811dd5b3..f1358f59387cf29eb6c218f863db322082cbf48b 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/Vorgang.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/Vorgang.java @@ -7,9 +7,12 @@ import lombok.Getter; @Builder public class Vorgang { + public static final String POSTFACH_ID_FIELD = "postfachId"; + private String id; private String name; private String nummer; private String trustLevel; + private String postfachId; } \ No newline at end of file diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/VorgangRemoteService.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/VorgangRemoteService.java index 4ceb8ec414b0fb0b680c73ee7d51fffabd821d44..b6a45420c4c63df74e3ccda17b3072f56ab7ee46 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/VorgangRemoteService.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/VorgangRemoteService.java @@ -31,6 +31,7 @@ import java.util.stream.StreamSupport; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import de.ozgcloud.nachrichten.NachrichtenManagerConfiguration; import de.ozgcloud.nachrichten.common.grpc.NachrichtenCallContextAttachingInterceptor; import de.ozgcloud.nachrichten.postfach.FindVorgangIterator; import de.ozgcloud.vorgang.vorgang.GrpcFindVorgangWithEingangRequest; @@ -38,10 +39,10 @@ import de.ozgcloud.vorgang.vorgang.GrpcVorgangHeader; import de.ozgcloud.vorgang.vorgang.VorgangServiceGrpc.VorgangServiceBlockingStub; import net.devh.boot.grpc.client.inject.GrpcClient; -@Service("findVorgangRemoteService") +@Service(NachrichtenManagerConfiguration.NACHRICHTEN_VORGANG_REMOTE_SERVICE) class VorgangRemoteService { - @GrpcClient("vorgang-manager") + @GrpcClient(NachrichtenManagerConfiguration.GRPC_VORGANG_MANAGER_NAME) private VorgangServiceBlockingStub vorgangServiceStub; @Autowired diff --git a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/VorgangService.java b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/VorgangService.java index 581553577e6f8dd3259ee7416b5fcbabc9672a79..12a3c2fa9f43f47947d88fcebc33b8209b259686 100644 --- a/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/VorgangService.java +++ b/nachrichten-manager-server/src/main/java/de/ozgcloud/nachrichten/common/vorgang/VorgangService.java @@ -12,7 +12,7 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class VorgangService { - @Qualifier("findVorgangRemoteService") + @Qualifier(NachrichtenManagerConfiguration.NACHRICHTEN_VORGANG_REMOTE_SERVICE) private final VorgangRemoteService remoteService; public Stream<String> findVorgangIds(String servicekontoType, String postfachId) { diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumServiceTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumServiceTest.java index 9239d7d03256c447e132b3d3d168a3f5f78d3963..f5220ab82ed6c6dfa41fb8aba83a080aa1785837 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumServiceTest.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/antragraum/AntragraumServiceTest.java @@ -1,6 +1,7 @@ package de.ozgcloud.nachrichten.antragraum; import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -20,7 +21,9 @@ import org.mockito.Mock; import org.mockito.Spy; import org.opensaml.saml.saml2.core.Response; +import de.ozgcloud.apilib.common.errorhandling.NotFoundException; import de.ozgcloud.nachrichten.NachrichtenManagerProperties; +import de.ozgcloud.nachrichten.common.vorgang.GrpcPostfachAddressTestFactory; import de.ozgcloud.nachrichten.common.vorgang.GrpcServiceKontoTestFactory; import de.ozgcloud.nachrichten.common.vorgang.Vorgang; import de.ozgcloud.nachrichten.common.vorgang.VorgangService; @@ -29,6 +32,7 @@ import de.ozgcloud.nachrichten.postfach.PersistPostfachNachrichtService; import de.ozgcloud.nachrichten.postfach.PostfachNachricht; import de.ozgcloud.nachrichten.postfach.PostfachNachrichtMapper; import de.ozgcloud.nachrichten.postfach.PostfachNachrichtTestFactory; +import de.ozgcloud.nachrichten.postfach.osi.MessageTestFactory; class AntragraumServiceTest { @@ -301,6 +305,7 @@ class AntragraumServiceTest { @BeforeEach void mock() { doNothing().when(service).verifyToken(any()); + doNothing().when(service).verifyPostfachId(any(), any()); } @Test @@ -316,6 +321,13 @@ class AntragraumServiceTest { verify(postfachNachrichtService).persistAnswer(RUECKFRAGE_ID, NACHRICHT); } + + @Test + void shouldVerifyPostfachId() { + service.sendRueckfrageAnswer(SAML_TOKEN, RUECKFRAGE_ID, NACHRICHT); + + verify(service).verifyPostfachId(SAML_TOKEN, NACHRICHT); + } } @Nested @@ -390,6 +402,7 @@ class AntragraumServiceTest { when(nachrichtMapper.fromMapToPostfachMail(any())).thenReturn(nachricht); doNothing().when(service).verifyToken(any()); + doNothing().when(service).verifyPostfachId(any(), any()); } @Test @@ -420,11 +433,66 @@ class AntragraumServiceTest { assertThat(rueckfrage).isEqualTo(nachricht); } + @Test + void shouldCallVerifyPostfachId() { + getRueckfrage(); + + verify(service).verifyPostfachId(samlToken, nachricht); + } + private PostfachNachricht getRueckfrage() { return service.getRueckfrage(samlToken, RueckfrageHeadTestFactory.ID); } } + @DisplayName("Verify postfachId") + @Nested + class TestVerifyPostfachId { + + private static final String SAML_TOKEN = "TOKEN"; + private static final PostfachNachricht POSTFACH_NACHRICHT = PostfachNachrichtTestFactory.create(); + + @BeforeEach + void mock() { + when(vorgangService.getVorgang(any())).thenReturn(VorgangTestFactory.create()); + } + + @Test + void shouldCallVorgangService() { + doReturn(GrpcPostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE).when(service).getPostfachId(any()); + + service.verifyPostfachId(SAML_TOKEN, POSTFACH_NACHRICHT); + + verify(vorgangService).getVorgang(MessageTestFactory.VORGANG_ID); + } + + @Test + void shouldGetPostfachIdFromToken() { + doReturn(GrpcPostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE).when(service).getPostfachId(any()); + + service.verifyPostfachId(SAML_TOKEN, POSTFACH_NACHRICHT); + + verify(service).getPostfachId(SAML_TOKEN); + } + + @Test + void shouldThrowExceptionOnMismatchPostfachId() { + doReturn("not-matching-postfach-id").when(service).getPostfachId(any()); + + assertThatThrownBy(() -> service.verifyPostfachId(SAML_TOKEN, POSTFACH_NACHRICHT)) + .isInstanceOf(NotFoundException.class) + .hasMessageContaining("PostfachNachricht") + .hasMessageContaining(PostfachNachrichtTestFactory.ID); + } + + @Test + void shouldNotThrowExceptionOnMatchingPostfachId() { + doReturn(GrpcPostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE).when(service).getPostfachId(any()); + + assertDoesNotThrow(() -> service.verifyPostfachId(SAML_TOKEN, POSTFACH_NACHRICHT)); + } + } + @DisplayName("Is accessible") @Nested class TestIsAccessible { diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/GrpcPostfachAddressTestFactory.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/GrpcPostfachAddressTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..42eeab1102ce07484387d870063c59075dd54bde --- /dev/null +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/GrpcPostfachAddressTestFactory.java @@ -0,0 +1,31 @@ +package de.ozgcloud.nachrichten.common.vorgang; + +import java.util.UUID; + +import de.ozgcloud.vorgang.common.GrpcObject; +import de.ozgcloud.vorgang.common.GrpcProperty; +import de.ozgcloud.vorgang.vorgang.GrpcPostfachAddress; + +public class GrpcPostfachAddressTestFactory { + + public static final String IDENTIFIER_POSTFACH_ID_FIELD = "postfachId"; + public static final String STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE = UUID.randomUUID().toString(); + + public static GrpcPostfachAddress create() { + return createBuilder().build(); + } + + public static GrpcPostfachAddress.Builder createBuilder() { + return GrpcPostfachAddress.newBuilder() + .setIdentifier(createStringBasedIdentifier()); + } + + private static GrpcObject createStringBasedIdentifier() { + return GrpcObject.newBuilder() + .addProperty(GrpcProperty.newBuilder() + .setName(IDENTIFIER_POSTFACH_ID_FIELD) + .addValue(STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE) + .build()) + .build(); + } +} diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/GrpcServiceKontoTestFactory.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/GrpcServiceKontoTestFactory.java index 1b2291608de848908807d38f83051e942be47ae4..6437038644c6ddc484badee7dbd82e22fc8bda71 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/GrpcServiceKontoTestFactory.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/GrpcServiceKontoTestFactory.java @@ -14,6 +14,7 @@ public class GrpcServiceKontoTestFactory { public static GrpcServiceKonto.Builder createBuilder() { return GrpcServiceKonto.newBuilder() - .setTrustLevel(TRUST_LEVEL); + .setTrustLevel(TRUST_LEVEL) + .addPostfachAddresses(GrpcPostfachAddressTestFactory.create()); } -} +} \ No newline at end of file diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/NachrichtenVorgangMapperTest.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/NachrichtenVorgangMapperTest.java index e33d13aaccf419865c65e5b6dd4ee02015283ba4..70794f3049ee20bb269dff8038ce1aa20fb1c347 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/NachrichtenVorgangMapperTest.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/NachrichtenVorgangMapperTest.java @@ -21,5 +21,18 @@ class NachrichtenVorgangMapperTest { assertThat(vorgang).usingRecursiveComparison().isEqualTo(VorgangTestFactory.create()); } + + @Test + void shouldProceedIfPostfachAddressesAreMissing() { + var ohnePostfachId = GrpcVorgangWithEingangTestFactory.createBuilder().setHeader( + GrpcVorgangHeadTestFactory.createBuilder() + .setServiceKonto(GrpcServiceKontoTestFactory.createBuilder().clearPostfachAddresses().build()) + .build()) + .build(); + + var vorgang = mapper.fromVorgangWithEingang(ohnePostfachId); + + assertThat(vorgang).isNotNull(); + } } } diff --git a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/VorgangTestFactory.java b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/VorgangTestFactory.java index 087fe08faa89ec0ea7ae6cfeda68744eeb727592..ee7a52498a91f1a4b566c7887eb4af597f97b630 100644 --- a/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/VorgangTestFactory.java +++ b/nachrichten-manager-server/src/test/java/de/ozgcloud/nachrichten/common/vorgang/VorgangTestFactory.java @@ -19,6 +19,7 @@ public class VorgangTestFactory { .id(ID) .name(NAME) .nummer(NUMMER) - .trustLevel(GrpcServiceKontoTestFactory.TRUST_LEVEL); + .trustLevel(GrpcServiceKontoTestFactory.TRUST_LEVEL) + .postfachId(GrpcPostfachAddressTestFactory.STRING_BASED_IDENTIFIER_POSTFACH_ID_VALUE); } }