diff --git a/client/src/main/java/dev/fitko/fitconnect/client/subscriber/SubmissionReceiver.java b/client/src/main/java/dev/fitko/fitconnect/client/subscriber/SubmissionReceiver.java index e7703c9613cd93a5b37785bc5910774ef6b8edc0..29cf52d81b1d3c38db8d2d91e9c89505489cd4ea 100644 --- a/client/src/main/java/dev/fitko/fitconnect/client/subscriber/SubmissionReceiver.java +++ b/client/src/main/java/dev/fitko/fitconnect/client/subscriber/SubmissionReceiver.java @@ -120,23 +120,23 @@ public class SubmissionReceiver { private void validateMetadata(final Metadata metadata, final Submission submission, final AuthenticationTags authenticationTags) { final ValidationResult validationResult = subscriber.validateMetadata(metadata, submission, authenticationTags); - evaluateValidationResult(submission, validationResult, "Metadata is invalid"); + evaluateValidationResult(submission, validationResult); } private void validateAttachments(final List<AttachmentForValidation> attachmentForValidation, final Submission submission, final AuthenticationTags authenticationTags) { final ValidationResult validationResult = subscriber.validateAttachments(attachmentForValidation, authenticationTags); - evaluateValidationResult(submission, validationResult, "Attachment validation failed"); + evaluateValidationResult(submission, validationResult); } private void validateData(final Submission submission, final Metadata metadata, final byte[] decryptedData, final AuthenticationTags authenticationTags) { final ValidationResult validationResult = subscriber.validateData(decryptedData, submission, metadata, authenticationTags); - evaluateValidationResult(submission, validationResult, "Data is invalid"); + evaluateValidationResult(submission, validationResult); } - private void evaluateValidationResult(final Submission submission, final ValidationResult validationResult, final String errorMessage) throws SubmissionRequestException { + private void evaluateValidationResult(final Submission submission, final ValidationResult validationResult) throws SubmissionRequestException { if (validationResult.hasProblems()) { rejectSubmissionWithProblem(submission, validationResult.getProblems().toArray(new Problem[0])); - throw new SubmissionRequestException(validationResult.hasError() ? validationResult.getError().getMessage() : errorMessage); + throw new SubmissionRequestException(validationResult.getProblems().stream().map(Problem::getDetail).collect(Collectors.joining())); } else if (validationResult.hasError()) { LOGGER.error(validationResult.getError().getMessage(), validationResult.getError()); throw new SubmissionRequestException(validationResult.getError().getMessage(), validationResult.getError()); diff --git a/client/src/test/java/dev/fitko/fitconnect/client/SubscriberClientTest.java b/client/src/test/java/dev/fitko/fitconnect/client/SubscriberClientTest.java index a9085e2e2889c452c68a5d715282c69917ba8ffb..0c251d820da82d13db7bad1a5dca98bde19de8e1 100644 --- a/client/src/test/java/dev/fitko/fitconnect/client/SubscriberClientTest.java +++ b/client/src/test/java/dev/fitko/fitconnect/client/SubscriberClientTest.java @@ -389,7 +389,7 @@ class SubscriberClientTest { final FitConnectSubscriberException exception = assertThrows(FitConnectSubscriberException.class, () -> underTest.requestSubmission(submissionId)); // Then - assertThat(exception.getCause().getMessage(), containsString("Metadata is invalid")); + assertThat(exception.getCause().getMessage(), containsString("The authentication tag for the metadata is invalid")); verify(subscriberMock, times(1)).rejectSubmission(EventPayload.forRejectEvent(submission, List.of(problem))); } @@ -556,7 +556,7 @@ class SubscriberClientTest { final FitConnectSubscriberException exception = assertThrows(FitConnectSubscriberException.class, () -> underTest.requestSubmission(submissionId)); // Then - assertThat(exception.getCause().getMessage(), containsString("Data is invalid")); + assertThat(exception.getCause().getMessage(), containsString("Submission data checksum wrong")); verify(subscriberMock, times(1)).rejectSubmission(EventPayload.forRejectEvent(submission, List.of(problem))); } @@ -613,7 +613,7 @@ class SubscriberClientTest { final FitConnectSubscriberException exception = assertThrows(FitConnectSubscriberException.class, () -> underTest.requestSubmission(submissionId)); // Then - assertThat(exception.getCause().getMessage(), containsString("Data is invalid")); + assertThat(exception.getCause().getMessage(), containsString("Submission data does not comply to schema")); verify(subscriberMock, times(1)).rejectSubmission(EventPayload.forRejectEvent(submission, List.of(problem))); } @@ -682,7 +682,7 @@ class SubscriberClientTest { final FitConnectSubscriberException exception = assertThrows(FitConnectSubscriberException.class, () -> underTest.requestSubmission(submissionId)); // Then - assertThat(exception.getCause().getMessage(), containsString("Attachment validation failed")); + assertThat(exception.getCause().getMessage(), containsString("The authentication tag for the attachment " + attachment.getAttachmentId() + " is invalid")); verify(subscriberMock, times(1)).rejectSubmission(EventPayload.forRejectEvent(submission, List.of(problem))); } diff --git a/core/src/main/java/dev/fitko/fitconnect/core/validation/DefaultValidationService.java b/core/src/main/java/dev/fitko/fitconnect/core/validation/DefaultValidationService.java index e5d8599a81a523153b7ce434102599f35bb61537..a0b712fdafd4e0f8aa48ddaf325f5de12d48ba7e 100644 --- a/core/src/main/java/dev/fitko/fitconnect/core/validation/DefaultValidationService.java +++ b/core/src/main/java/dev/fitko/fitconnect/core/validation/DefaultValidationService.java @@ -356,13 +356,14 @@ public class DefaultValidationService implements ValidationService { } // https://docs.fitko.de/fit-connect/docs/receiving/verification/#r%C3%BCckkanal - final ReplyChannel submissionReplyChannel = metadata.getReplyChannel(); - final ReplyChannel destinationReplyChannel = destination.getReplyChannels(); + if(metadata.getReplyChannel() != null && destination.getReplyChannels() == null){ + return ValidationResult.problem(new UnsupportedReplyChannel()); + } - if (submissionReplyChannel != null) { - final List<Class<?>> submissionReplyChannelClass = getNonNullReplyChannelTypes(submissionReplyChannel); - final List<Class<?>> destinationReplyChannelClass = getNonNullReplyChannelTypes(destinationReplyChannel); - if (!new HashSet<>(destinationReplyChannelClass).containsAll(submissionReplyChannelClass)) { + if (metadata.getReplyChannel() != null) { + final List<Class<?>> submissionReplyChannelClasses = getNonNullReplyChannelTypes(metadata.getReplyChannel()); + final List<Class<?>> destinationReplyChannelClasses = getNonNullReplyChannelTypes(destination.getReplyChannels()); + if (!new HashSet<>(destinationReplyChannelClasses).containsAll(submissionReplyChannelClasses)) { return ValidationResult.problem(new UnsupportedReplyChannel()); } } diff --git a/core/src/test/java/dev/fitko/fitconnect/core/validation/DefaultValidationServiceTest.java b/core/src/test/java/dev/fitko/fitconnect/core/validation/DefaultValidationServiceTest.java index 405cbd7a526bfd04b07142a1205165cb1f52c1ba..0ce07c61fa452501657d8688991fc9c2c4fa573b 100644 --- a/core/src/test/java/dev/fitko/fitconnect/core/validation/DefaultValidationServiceTest.java +++ b/core/src/test/java/dev/fitko/fitconnect/core/validation/DefaultValidationServiceTest.java @@ -669,6 +669,59 @@ class DefaultValidationServiceTest { assertThat(validationResult.getProblems().get(0), instanceOf(UnsupportedReplyChannel.class)); } + @Test + void testDestinationWithNoReplyChannelAndSubmissionWithReplyChannel() { + + // Given + final SubmissionSchema schema = new SubmissionSchema(); + schema.setSchemaUri(URI.create("https://schema.fitko.de/fit-connect/metadata/1.0.0/metadata.schema.json")); + schema.setMimeType(MimeType.APPLICATION_JSON); + + final Hash hash = new Hash(); + hash.setContent(hashService.toHexString(hashService.createHash("someBogusContent".getBytes()))); + hash.setSignatureType(SignatureType.SHA_512); + + final Data data = new Data(); + data.setSubmissionSchema(schema); + data.setHash(hash); + + final ContentStructure contentStructure = new ContentStructure(); + contentStructure.setAttachments(Collections.emptyList()); + contentStructure.setData(data); + + final var metadata = new Metadata(); + metadata.setSchema(SchemaConfig.METADATA_V_1_0_0.toString()); + metadata.setContentStructure(contentStructure); + + final DestinationService destinationService = new DestinationService(); + destinationService.setIdentifier("urn:de:fim:leika:leistung:99400048079000"); + destinationService.setSubmissionSchemas(Set.of(schema)); + + final var destination = new Destination(); + destination.setServices(Set.of(destinationService)); + + final ServiceType submissionServiceType = new ServiceType(); + submissionServiceType.setIdentifier("urn:de:fim:leika:leistung:99400048079000"); + + final var submission = new Submission(); + submission.setEncryptedMetadata("header.encryption_key.init_vector.ciphertext.metadataAuthTag"); + submission.setServiceType(submissionServiceType); + + final var authenticationTags = new AuthenticationTags(); + authenticationTags.setMetadata("metadataAuthTag"); + + final ReplyChannel submissionReplyChannel = new ReplyChannel(); + submissionReplyChannel.setEMail(new Email("test@mail.org", false, null)); + metadata.setReplyChannel(submissionReplyChannel); + + // When + final ValidationResult validationResult = underTest.validateMetadata(metadata, submission, destination, authenticationTags); + + // Then + assertTrue(validationResult.hasProblems()); + assertThat(validationResult.getProblems(), contains(new UnsupportedReplyChannel())); + } + @Test void validateMetadataWithoutSchemaAttributeButValidSchema() { @@ -1453,11 +1506,10 @@ class DefaultValidationServiceTest { final var testing = new Environment(); testing.setAllowInsecurePublicKey(allowInsecureKey); testing.setSkipSubmissionDataValidation(skipSubmissionDataValidation); - final var config = ApplicationConfig.builder() + return ApplicationConfig.builder() .environments(Map.of(envName, testing)) .activeEnvironment(envName) .build(); - return config; } } \ No newline at end of file