From 80061b56a438ff4e6a01955ada10b2a1e7ea8b8a Mon Sep 17 00:00:00 2001 From: OZGCloud <ozgcloud@mgm-tp.com> Date: Tue, 1 Mar 2022 08:57:02 +0100 Subject: [PATCH] OZG-1070 OZG-2158 validate file size by configured max file size for postfach nachricht --- .../goofy/common/ValidationMessageCodes.java | 1 + .../binaryfile/BinaryFileController.java | 12 ++--- .../BinaryFileMaxSizeConstraint.java | 25 ++++++++++ .../binaryfile/BinaryFileProperties.java | 21 ++++++++ .../binaryfile/BinaryFileRemoteService.java | 6 +-- .../common/binaryfile/BinaryFileService.java | 6 ++- .../binaryfile/UploadBinaryFileRequest.java | 10 +++- .../UploadBinaryFileSizeValidator.java | 25 ++++++++++ .../src/main/resources/application.yml | 7 +++ .../binaryfile/BinaryFileControllerTest.java | 49 +++++++----------- .../UploadBinaryFileSizeValidatorTest.java | 50 +++++++++++++++++++ .../UploadBinaryFileTestFactory.java | 11 ++-- 12 files changed, 171 insertions(+), 52 deletions(-) create mode 100644 goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileMaxSizeConstraint.java create mode 100644 goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileProperties.java create mode 100644 goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileSizeValidator.java create mode 100644 goofy-server/src/test/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileSizeValidatorTest.java diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/ValidationMessageCodes.java b/goofy-server/src/main/java/de/itvsh/goofy/common/ValidationMessageCodes.java index 58616c47f8..e48ce06cd9 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/ValidationMessageCodes.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/ValidationMessageCodes.java @@ -11,4 +11,5 @@ public class ValidationMessageCodes { public static final String FIELD_SIZE = FIELD_PREFIX + "size"; public static final String FIELD_DATE_PAST = FIELD_PREFIX + "date_past"; public static final String FIELD_INVALID = FIELD_PREFIX + "invalid"; + public static final String FIELD_FILE_SIZE_EXCEEDED = FIELD_PREFIX + "file_size_exceeded"; } \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileController.java b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileController.java index 9766d370ea..cf573e9ad5 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileController.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileController.java @@ -76,8 +76,10 @@ public class BinaryFileController { return UploadBinaryFileRequest.builder() .vorgangId(vorgangId) .field(field) - .ozgFile(buildOzgFile(file)) .uploadStream(getInputStream(file)) + .name(file.getOriginalFilename()) + .contentType(file.getContentType()) + .size(file.getSize()) .build(); } @@ -89,14 +91,6 @@ public class BinaryFileController { } } - OzgFile buildOzgFile(MultipartFile file) { - return OzgFile.builder() - .name(file.getOriginalFilename()) - .contentType(file.getContentType()) - .size(file.getSize()) - .build(); - } - public CollectionModel<EntityModel<OzgFile>> getFiles(List<FileId> fileIds) { var files = service.getFiles(mapToFileId(fileIds)).toList(); diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileMaxSizeConstraint.java b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileMaxSizeConstraint.java new file mode 100644 index 0000000000..6d6cebd3de --- /dev/null +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileMaxSizeConstraint.java @@ -0,0 +1,25 @@ +package de.itvsh.goofy.common.binaryfile; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.validation.Constraint; +import javax.validation.Payload; + +import de.itvsh.goofy.common.ValidationMessageCodes; + +@Constraint(validatedBy = UploadBinaryFileSizeValidator.class) +@Target({ TYPE }) +@Retention(RUNTIME) +@Documented +public @interface BinaryFileMaxSizeConstraint { + String message() default ValidationMessageCodes.FIELD_FILE_SIZE_EXCEEDED; + + Class<?>[] groups() default {}; + + Class<? extends Payload>[] payload() default {}; +} \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileProperties.java b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileProperties.java new file mode 100644 index 0000000000..4d862539d7 --- /dev/null +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileProperties.java @@ -0,0 +1,21 @@ +package de.itvsh.goofy.common.binaryfile; + +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Configuration +@ConfigurationProperties(BinaryFileProperties.PREFIX) +class BinaryFileProperties { + + static final String PREFIX = "goofy.upload"; + + private Map<String, Integer> maxFileSize; + +} \ No newline at end of file diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileRemoteService.java b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileRemoteService.java index 276becbcdd..ecce387c15 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileRemoteService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileRemoteService.java @@ -115,9 +115,9 @@ class BinaryFileRemoteService { .setContext(contextService.createCallContext()) .setVorgangId(uploadBinaryFileRequest.getVorgangId()) .setField(uploadBinaryFileRequest.getField()) - .setContentType(uploadBinaryFileRequest.getOzgFile().getContentType()) - .setSize(uploadBinaryFileRequest.getOzgFile().getSize()) - .setFileName(uploadBinaryFileRequest.getOzgFile().getName())) + .setContentType(uploadBinaryFileRequest.getContentType()) + .setSize(uploadBinaryFileRequest.getSize()) + .setFileName(uploadBinaryFileRequest.getName())) .build(); } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileService.java b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileService.java index df88413348..33f67ca1c7 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileService.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/BinaryFileService.java @@ -5,13 +5,17 @@ import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.stream.Stream; +import javax.validation.Valid; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; import de.itvsh.goofy.common.file.OzgFile; import de.itvsh.goofy.common.file.OzgFileData; @Service +@Validated class BinaryFileService { @Autowired @@ -22,7 +26,7 @@ class BinaryFileService { return remoteService.uploadFile(vorgangId, fieldName, file); } - public CompletableFuture<FileId> uploadFile(UploadBinaryFileRequest uploadBinaryFileRequest) { + public CompletableFuture<FileId> uploadFile(@Valid UploadBinaryFileRequest uploadBinaryFileRequest) { return remoteService.uploadFile(uploadBinaryFileRequest); } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileRequest.java b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileRequest.java index 165aa46828..9c6eeddfca 100644 --- a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileRequest.java +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileRequest.java @@ -2,16 +2,22 @@ package de.itvsh.goofy.common.binaryfile; import java.io.InputStream; -import de.itvsh.goofy.common.file.OzgFile; +import org.springframework.validation.annotation.Validated; + import lombok.Builder; import lombok.Getter; @Getter @Builder +@Validated +@BinaryFileMaxSizeConstraint class UploadBinaryFileRequest { private String vorgangId; private String field; - private OzgFile ozgFile; + + private String name; + private String contentType; + private long size; private InputStream uploadStream; } diff --git a/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileSizeValidator.java b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileSizeValidator.java new file mode 100644 index 0000000000..32555e8296 --- /dev/null +++ b/goofy-server/src/main/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileSizeValidator.java @@ -0,0 +1,25 @@ +package de.itvsh.goofy.common.binaryfile; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +import org.springframework.beans.factory.annotation.Autowired; + +class UploadBinaryFileSizeValidator implements ConstraintValidator<BinaryFileMaxSizeConstraint, UploadBinaryFileRequest> { + + @Autowired + private BinaryFileProperties binaryFileProperties; + + @Override + public boolean isValid(UploadBinaryFileRequest uploadRequest, ConstraintValidatorContext context) { + return uploadRequest.getSize() <= toMegabyte(getMaxValidSize(uploadRequest.getField())); + } + + private long toMegabyte(Integer byteValue) { + return byteValue.longValue() * 1024 * 1024; + } + + private Integer getMaxValidSize(String field) { + return binaryFileProperties.getMaxFileSize().get(field); + } +} \ No newline at end of file diff --git a/goofy-server/src/main/resources/application.yml b/goofy-server/src/main/resources/application.yml index d940267afa..e1d85b5e7b 100644 --- a/goofy-server/src/main/resources/application.yml +++ b/goofy-server/src/main/resources/application.yml @@ -14,6 +14,10 @@ spring: jackson: deserialization: 'ADJUST_DATES_TO_CONTEXT_TIME_ZONE': false + servlet: + multipart: + max-file-size: 40MB + max-request-size: 40MB server: http2: @@ -48,6 +52,9 @@ goofy: api: user: goofyApiUser password: + upload: + maxFileSize: + postfachNachrichtAttachment: 40 keycloak: auth-server-url: http://localhost:8088/auth diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/binaryfile/BinaryFileControllerTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/binaryfile/BinaryFileControllerTest.java index 396be3d268..f09961d401 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/binaryfile/BinaryFileControllerTest.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/binaryfile/BinaryFileControllerTest.java @@ -131,7 +131,7 @@ class BinaryFileControllerTest { } @Nested - class TestBuildBinaryFileUpload { + class TestBuildBinaryFileUploadRequest { @Test void shouldContainsVorgangId() { @@ -148,10 +148,24 @@ class BinaryFileControllerTest { } @Test - void shouldContainsOzgFile() { + void shouldContainsSize() { + var result = buildBinaryFileUploadRequest(); + + assertThat(result.getSize()).isEqualTo(OzgFileTestFactory.SIZE); + } + + @Test + void shouldContainsName() { + var result = buildBinaryFileUploadRequest(); + + assertThat(result.getName()).isEqualTo(OzgFileTestFactory.NAME); + } + + @Test + void shouldContainsContentType() { var result = buildBinaryFileUploadRequest(); - assertThat(result.getOzgFile()).usingRecursiveComparison().ignoringFields("id").isEqualTo(UploadBinaryFileTestFactory.OZG_FILE); + assertThat(result.getContentType()).isEqualTo(OzgFileTestFactory.CONTENT_TYPE); } @Test @@ -189,35 +203,6 @@ class BinaryFileControllerTest { } } - @Nested - class TestBuildOzgFile { - - @Test - void shouldContainsOriginalFilename() { - var ozgFile = callBuildOzgFile(); - - assertThat(ozgFile.getName()).isEqualTo(BinaryFileTestFactory.NAME); - } - - @Test - void shouldContainsContentType() { - var ozgFile = callBuildOzgFile(); - - assertThat(ozgFile.getContentType()).isEqualTo(BinaryFileTestFactory.CONTENT_TYPE); - } - - @Test - void shouldContainsSize() { - var ozgFile = callBuildOzgFile(); - - assertThat(ozgFile.getSize()).isEqualTo(BinaryFileTestFactory.SIZE); - } - - private OzgFile callBuildOzgFile() { - return controller.buildOzgFile(BinaryFileTestFactory.TEST_FILE); - } - } - @Nested class TestGetFile { diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileSizeValidatorTest.java b/goofy-server/src/test/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileSizeValidatorTest.java new file mode 100644 index 0000000000..0288f9a48e --- /dev/null +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileSizeValidatorTest.java @@ -0,0 +1,50 @@ +package de.itvsh.goofy.common.binaryfile; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Map; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +class UploadBinaryFileSizeValidatorTest { + + @InjectMocks + private UploadBinaryFileSizeValidator validator = new UploadBinaryFileSizeValidator(); + @Mock + private BinaryFileProperties properties; + + @Nested + class TestIsValid { + + @Test + void shouldCallProperties() { + when(properties.getMaxFileSize()).thenReturn(Map.of(UploadBinaryFileTestFactory.FIELD, 1)); + + validator.isValid(UploadBinaryFileTestFactory.create(), null); + + verify(properties).getMaxFileSize(); + } + + @Test + void shouldReturnFalse() { + when(properties.getMaxFileSize()).thenReturn(Map.of(UploadBinaryFileTestFactory.FIELD, 9)); + + var isValid = validator.isValid(UploadBinaryFileTestFactory.createBuilder().size(10 * 1024 * 1024).build(), null); + + assertThat(isValid).isFalse(); + } + + @Test + void shouldReturnTrue() { + when(properties.getMaxFileSize()).thenReturn(Map.of(UploadBinaryFileTestFactory.FIELD, 10)); + + var isValid = validator.isValid(UploadBinaryFileTestFactory.createBuilder().size(10 * 1024 * 1024).build(), null); + + assertThat(isValid).isTrue(); + } + } +} diff --git a/goofy-server/src/test/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileTestFactory.java b/goofy-server/src/test/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileTestFactory.java index 2842854536..4a4262bae0 100644 --- a/goofy-server/src/test/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileTestFactory.java +++ b/goofy-server/src/test/java/de/itvsh/goofy/common/binaryfile/UploadBinaryFileTestFactory.java @@ -1,16 +1,15 @@ package de.itvsh.goofy.common.binaryfile; +import static de.itvsh.goofy.common.file.OzgFileTestFactory.*; + import java.io.InputStream; -import de.itvsh.goofy.common.file.OzgFile; -import de.itvsh.goofy.common.file.OzgFileTestFactory; import de.itvsh.goofy.vorgang.VorgangHeaderTestFactory; public class UploadBinaryFileTestFactory { static final String VORGANG_ID = VorgangHeaderTestFactory.ID; static final String FIELD = BinaryFileTestFactory.FIELD; - static final OzgFile OZG_FILE = OzgFileTestFactory.create(); static final InputStream UPLOAD_STREAM = BinaryFileTestFactory.STREAM; public static UploadBinaryFileRequest create() { @@ -19,9 +18,11 @@ public class UploadBinaryFileTestFactory { public static UploadBinaryFileRequest.UploadBinaryFileRequestBuilder createBuilder() { return UploadBinaryFileRequest.builder() + .name(NAME) .vorgangId(VORGANG_ID) .field(FIELD) - .ozgFile(OZG_FILE) + .size(SIZE) + .contentType(CONTENT_TYPE) .uploadStream(UPLOAD_STREAM); } -} +} \ No newline at end of file -- GitLab