From e1f365955aa22cdf8e44429af2b744388ce0c05b Mon Sep 17 00:00:00 2001 From: Christof Rabensteiner Date: Tue, 28 May 2019 10:48:20 +0200 Subject: Integrate Sign.Verification and Improve Error Handling of Pipeline - Ensure proper communication of errors between pipeline and mzs service by converting MoaZSExceptions into DeliveryRequestStatus messages. - Revise MoaZSException: Add optional fields; those fields are a) helpful to construct meaningful error messages and b) optional because, depending on where an exception appears, either existent or non-existent and thus optional. Add inner-class Builder. - Integrate Signature Verification into pipeline and add Stub for SignatureVerification. - Move TNVZResponse's Mimetype check into dedicated class (Reason: separate abstration layers). - Update api changes in testcases. --- src/test/java/at/gv/egiz/moazs/MsgClientTest.java | 8 +- .../egiz/moazs/SameThreadDeliveryPipelineTest.java | 95 ++++++++++++++++------ 2 files changed, 78 insertions(+), 25 deletions(-) (limited to 'src/test/java') diff --git a/src/test/java/at/gv/egiz/moazs/MsgClientTest.java b/src/test/java/at/gv/egiz/moazs/MsgClientTest.java index 1822ff5..8cebf06 100644 --- a/src/test/java/at/gv/egiz/moazs/MsgClientTest.java +++ b/src/test/java/at/gv/egiz/moazs/MsgClientTest.java @@ -2,6 +2,7 @@ package at.gv.egiz.moazs; import at.gv.egiz.moazs.msg.MsgClient; import at.gv.egiz.moazs.msg.MsgClientFactory; +import at.gv.egiz.moazs.msg.StoreSOAPBodyBinaryInRepositoryInterceptor; import at.gv.egiz.moazs.scheme.Marshaller; import at.gv.zustellung.app2mzs.xsd.ConfigType; import at.gv.zustellung.msg.xsd.DeliveryRequestType; @@ -39,6 +40,9 @@ public class MsgClientTest { @Autowired private MsgClientFactory factory; + @Autowired + private StoreSOAPBodyBinaryInRepositoryInterceptor interceptor; + private static final ObjectFactory OF = new ObjectFactory(); @@ -49,7 +53,7 @@ public class MsgClientTest { var request = loadFromFile("validDeliveryRequest.xml"); var config = generateConfig(httpServiceUri); - var client = factory.create(request, config); + var client = factory.create(request, config, interceptor); try{ var status = client.send(); @@ -64,7 +68,7 @@ public class MsgClientTest { var request = loadFromFile("validDeliveryRequest.xml"); var config = generateConfig(sslServiceUri); - var client = factory.create(request, config); + var client = factory.create(request, config, interceptor); var status = client.send(); diff --git a/src/test/java/at/gv/egiz/moazs/SameThreadDeliveryPipelineTest.java b/src/test/java/at/gv/egiz/moazs/SameThreadDeliveryPipelineTest.java index 5e4b9b0..b0c03a2 100644 --- a/src/test/java/at/gv/egiz/moazs/SameThreadDeliveryPipelineTest.java +++ b/src/test/java/at/gv/egiz/moazs/SameThreadDeliveryPipelineTest.java @@ -2,11 +2,15 @@ package at.gv.egiz.moazs; import at.gv.egiz.moazs.msg.MsgClient; import at.gv.egiz.moazs.msg.MsgClientFactory; +import at.gv.egiz.moazs.msg.SignatureVerifier; +import at.gv.egiz.moazs.msg.StoreSOAPBodyBinaryInRepositoryInterceptor; import at.gv.egiz.moazs.pipeline.DeliveryPipeline; import at.gv.egiz.moazs.pipeline.SameThreadDeliveryPipeline; import at.gv.egiz.moazs.repository.DeliveryRepository; +import at.gv.egiz.moazs.repository.InMemoryDeliveryRepository; import at.gv.egiz.moazs.scheme.Mzs2MsgConverter; import at.gv.egiz.moazs.tnvz.TnvzClient; +import at.gv.egiz.moazs.tnvz.TnvzResultVerifier; import at.gv.zustellung.app2mzs.xsd.DeliveryRequestType; import at.gv.zustellung.msg.xsd.DeliveryRequestStatusType; import at.gv.zustellung.msg.xsd.MetaData; @@ -24,6 +28,7 @@ import static at.gv.zustellung.app2mzs.xsd.ConfigType.configTypeBuilder; import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.Payload; import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.Payload.payloadBuilder; import static at.gv.zustellung.app2mzs.xsd.DeliveryRequestType.deliveryRequestTypeBuilder; +import static at.gv.zustellung.app2mzs.xsd.ServerType.serverTypeBuilder; import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.Success.successBuilder; import static at.gv.zustellung.msg.xsd.DeliveryRequestStatusType.deliveryRequestStatusTypeBuilder; import static at.gv.zustellung.msg.xsd.ErrorInfoType.errorInfoTypeBuilder; @@ -32,16 +37,15 @@ import static at.gv.zustellung.tnvz.xsd.MimeTypeList.mimeTypeListBuilder; import static at.gv.zustellung.tnvz.xsd.PersonResultSuccessType.personResultSuccessTypeBuilder; import static at.gv.zustellung.tnvz.xsd.PersonResultType.Error.errorBuilder; import static at.gv.zustellung.tnvz.xsd.PersonResultType.personResultTypeBuilder; -import static java.util.Optional.of; import static java.util.stream.Collectors.toList; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class SameThreadDeliveryPipelineTest { - @Mock - private DeliveryRepository repository; + private DeliveryRepository repository = new InMemoryDeliveryRepository(); @Mock private TnvzClient tnvzClient; @@ -55,34 +59,46 @@ public class SameThreadDeliveryPipelineTest { @Mock private Mzs2MsgConverter converter; + @Mock + private StoreSOAPBodyBinaryInRepositoryInterceptor interceptor; + + @Mock + private SignatureVerifier verifier; + private DeliveryPipeline pipeline; @Before public void setup() { - pipeline = new SameThreadDeliveryPipeline(repository, tnvzClient, converter, msgClientFactory); + pipeline = new SameThreadDeliveryPipeline(repository, tnvzClient, new TnvzResultVerifier(), + converter,interceptor, msgClientFactory, verifier); } @Test public void executePipelineWithoutTnvzRequest() { var appDeliveryId = "no-tnvz-request"; - var status = setupMocks(appDeliveryId, false, List.of(), List.of("*/*")); + var expectedStatus = setupMocks(appDeliveryId, false, List.of(), List.of("*/*")); pipeline.processRequest(appDeliveryId); verifyZeroInteractions(tnvzClient); - verify(repository).add(status); + var actualStatus = repository.getDeliveryRequestStatus(appDeliveryId).get(); + + assertThat(actualStatus).isEqualTo(expectedStatus); } - @Test(expected = MoaZSException.class) + @Test public void rejectDeliveryWhenReceiverIsNotAddressable() { var appDeliveryId = "not-addressable"; setupMocks(appDeliveryId, true, List.of(), List.of("*/*")); - when(tnvzClient.queryPerson(any(), any())).thenReturn(setupTnvzError()); + when(tnvzClient.query(any(), any())).thenReturn(setupTnvzError("400", "Person not found.")); pipeline.processRequest(appDeliveryId); + var actualCode = repository.getDeliveryRequestStatus(appDeliveryId).get() + .getError().getErrorInfo().getCode(); - verify(tnvzClient).queryPerson(any(), any()); + verify(tnvzClient).query(any(), any()); + assertThat(actualCode).isEqualTo("400"); } @Test @@ -90,15 +106,16 @@ public class SameThreadDeliveryPipelineTest { var appDeliveryId = "wild-card-mimetype"; List acceptedTypes = List.of("*/*"); List attachedTypes = List.of("pdf", "xml", "html", "random/attachedtype"); - var status = setupMocks(appDeliveryId, true, attachedTypes, acceptedTypes); + var expectedStatus = setupMocks(appDeliveryId, true, attachedTypes, acceptedTypes); pipeline.processRequest(appDeliveryId); + var actualStatus = repository.getDeliveryRequestStatus(appDeliveryId).get(); - verify(tnvzClient).queryPerson(any(), any()); - verify(repository).add(status); + verify(tnvzClient).query(any(), any()); + assertThat(actualStatus).isEqualTo(expectedStatus); } - @Test(expected = MoaZSException.class) + @Test public void rejectMismatchedMimeTypes() { var appDeliveryId = "mismatched-mimetype"; List acceptedTypes = List.of("xml"); @@ -106,8 +123,12 @@ public class SameThreadDeliveryPipelineTest { setupMocks(appDeliveryId, true, attachedTypes, acceptedTypes); pipeline.processRequest(appDeliveryId); + var actualCode = repository.getDeliveryRequestStatus(appDeliveryId).get() + .getError().getErrorInfo().getCode(); + + verify(tnvzClient).query(any(), any()); + assertThat(actualCode).isEqualTo(MoaZSException.ERROR_MZS_MIMETYPE_MISSMATCH); - verify(tnvzClient).queryPerson(any(), any()); } @Test @@ -115,36 +136,59 @@ public class SameThreadDeliveryPipelineTest { var appDeliveryId = "specific-mimetype"; List acceptedTypes = List.of("pdf", "xml", "html"); List attachedTypes = List.of("pdf", "xml"); - var status = setupMocks(appDeliveryId, true, attachedTypes, acceptedTypes); + var expectedStatus = setupMocks(appDeliveryId, true, attachedTypes, acceptedTypes); + + pipeline.processRequest(appDeliveryId); + var actualStatus = repository.getDeliveryRequestStatus(appDeliveryId).get(); + + verify(tnvzClient).query(any(), any()); + assertThat(actualStatus).isEqualTo(expectedStatus); + } + + @Test + public void rejectInvalidSignature() { + var appDeliveryId = "invalid-signature"; + setupMocks(appDeliveryId, true, List.of(), List.of("*/*"), false); pipeline.processRequest(appDeliveryId); + var actualCode = repository.getDeliveryRequestStatus(appDeliveryId).get() + .getError().getErrorInfo().getCode(); + + assertThat(actualCode).isEqualTo(MoaZSException.ERROR_MOASP_SIGNATURE_INVALID); - verify(tnvzClient).queryPerson(any(), any()); - verify(repository).add(status); } private DeliveryRequestStatusType setupMocks(String appDeliveryId, boolean tnvzRequest, List attachedTypes, List acceptedTypes) { + return setupMocks(appDeliveryId, tnvzRequest, attachedTypes, acceptedTypes, true); + } + + private DeliveryRequestStatusType setupMocks(String appDeliveryId, boolean tnvzRequest, + List attachedTypes, List acceptedTypes, boolean isSignedStatusValid) { var mzsRequest = setupMzsRequest(appDeliveryId, tnvzRequest, attachedTypes); var msgRequest = setupMsgRequest(appDeliveryId); var status = setupStatus(appDeliveryId); - when(repository.getDeliveryRequest(appDeliveryId)).thenReturn(of(mzsRequest)); - when(tnvzClient.queryPerson(any(), any())).thenReturn(setupTnvzSuccess(acceptedTypes)); + var signedStatus = new byte[0]; + repository.add(mzsRequest); + repository.addSignedDeliveryRequestStatus(signedStatus, appDeliveryId); + + when(tnvzClient.query(any(), any())).thenReturn(setupTnvzSuccess(acceptedTypes)); when(converter.convert(eq(mzsRequest) )).thenReturn(msgRequest); when(converter.convert(eq(mzsRequest), any())).thenReturn(msgRequest); - when(msgClientFactory.create(msgRequest, mzsRequest.getConfig())).thenReturn(msgClient); + when(msgClientFactory.create(msgRequest, mzsRequest.getConfig(), interceptor)).thenReturn(msgClient); when(msgClient.send()).thenReturn(status); + when(verifier.verify(signedStatus)).thenReturn(isSignedStatusValid); return status; } - private PersonResultType setupTnvzError() { + private PersonResultType setupTnvzError(String code, String text) { var info = errorInfoTypeBuilder() - .withCode("400") - .withText("Person Not Found") + .withCode(code) + .withText(text) .build(); var error = errorBuilder() @@ -181,8 +225,13 @@ public class SameThreadDeliveryPipelineTest { private DeliveryRequestType setupMzsRequest(String appDeliveryId, boolean tnvzRequest, List mimeTypes) { + var server = serverTypeBuilder() + .withZUSEUrlID("http://zuse") + .build(); + var config = configTypeBuilder() .withPerformQueryPersonRequest(tnvzRequest) + .withServer(server) .build(); return deliveryRequestTypeBuilder() -- cgit v1.2.3