From 2ff0c62f40f4fff6ee2da091cc965ffde7827765 Mon Sep 17 00:00:00 2001 From: Aleksandar Vidakovic Date: Sun, 8 Feb 2026 01:11:05 +0100 Subject: [PATCH] FINERACT-2246: New command processing - document management --- .../org.apache.fineract.dependencies.gradle | 23 ++ config/docker/compose/fineract.yml | 3 +- config/docker/env/fineract-common.env | 3 +- .../fineract-accounting/persistence.xml | 1 - .../module/fineract-branch/persistence.xml | 1 - .../module/fineract-charge/persistence.xml | 1 - .../feign/services/DocumentsApiFixed.java | 12 +- .../DocumentsApiFixedIntegrationTest.java | 5 +- fineract-client/build.gradle | 14 + .../client/services/DocumentsApiFixed.java | 12 +- .../module/fineract-cob/persistence.xml | 1 - .../implementation/DefaultCommandAuditor.java | 20 +- .../CommandPersistenceConfiguration.java | 2 +- .../bulkimport/data/ImportData.java | 8 + .../service/BulkImportWorkbookService.java | 7 +- .../core/config/FineractProperties.java | 1 + .../adapter/EntityImageIdAdapter.java | 51 +++ .../handler/CurrencyUpdateCommandHandler.java | 1 - .../organisation/staff/domain/Staff.java | 11 +- .../client/adapter/ClientImageIdAdapter.java | 66 ++++ .../portfolio/client/domain/Client.java | 18 +- .../client/domain/ClientRepository.java | 8 + .../fineract/util/StreamResponseUtil.java | 89 ++++++ .../module/fineract-core/persistence.xml | 1 - fineract-document/dependencies.gradle | 24 +- .../config/ContentStoreConfig.java | 38 +++ .../contentstore/data/ContentStoreType.java | 22 +- .../detector/ContentDetector.java} | 13 +- .../detector/ContentDetectorContext.java | 48 +++ .../detector/ContentDetectorManager.java | 24 ++ .../DefaultContentDetectorManager.java | 36 +++ .../detector/FileContentDetector.java | 45 +++ .../detector/TikaContentDetector.java | 88 +++++ .../exception/ContentDetectorException.java} | 14 +- .../ContentPathSanitizerException.java | 28 ++ .../exception/ContentPolicyException.java | 28 ++ .../exception/ContentProcessorException.java | 32 ++ .../exception/ContentStoreException.java | 28 ++ .../contentstore/policy/ContentPolicy.java | 24 ++ .../policy/ContentPolicyContext.java | 38 +++ .../policy/DefaultDeleteContentPolicy.java | 38 +++ .../policy/DefaultDownloadContentPolicy.java | 38 +++ .../DefaultPostUploadContentPolicy.java | 36 +++ .../policy/DefaultPreUploadContentPolicy.java | 38 +++ .../policy/MimeContentPolicy.java | 48 +++ .../policy/TraversalContentPolicy.java | 43 +++ .../policy/WhitelistContentPolicy.java | 72 +++++ .../Base64DecoderContentProcessor.java | 53 +++ .../Base64EncoderContentProcessor.java | 53 +++ .../processor/ContentProcessor.java | 59 ++++ .../processor/ContentProcessorContext.java | 76 +++++ .../DataUrlDecoderContentProcessor.java | 153 +++++++++ .../DataUrlEncoderContentProcessor.java | 154 +++++++++ .../GzipDecoderContentProcessor.java | 53 +++ .../GzipEncoderContentProcessor.java | 53 +++ .../ImageResizeContentProcessor.java | 110 +++++++ .../processor/SizeContentProcessor.java | 80 +++++ .../service/ContentStoreService.java | 40 +++ .../service/FileContentStoreService.java | 198 ++++++++++++ .../service/S3ContentStoreService.java | 126 ++++++++ .../util/ContentPathRandomizer.java | 24 ++ .../util}/ContentPathSanitizer.java | 6 +- .../contentstore/util/ContentPipe.java | 169 ++++++++++ .../util/DefaultContentPathRandomizer.java | 39 +++ .../util/DefaultContentPathSanitizer.java | 47 +++ .../api/ContentResources.java | 61 ---- .../api/DocumentApiConstants.java | 31 ++ .../api/DocumentApiResource.java | 253 +++++++++++++++ .../api/DocumentManagementApiResource.java | 249 --------------- .../DocumentManagementApiResourceSwagger.java | 111 ------- .../api/ImageApiConstants.java | 33 ++ .../api/ImagesApiResource.java | 302 +++++++++--------- .../command/DocumentCommand.java | 45 +-- .../command/DocumentCommandValidator.java | 73 ----- .../command/DocumentCreateCommand.java | 28 ++ .../command/DocumentDeleteCommand.java | 28 ++ .../command/DocumentUpdateCommand.java | 28 ++ .../command/ImageCreateCommand.java | 28 ++ .../command/ImageDeleteCommand.java | 28 ++ .../contentrepository/ContentRepository.java | 56 ---- .../ContentRepositoryFactory.java | 53 --- .../ContentRepositoryUtils.java | 210 ------------ .../FileSystemContentPathSanitizer.java | 138 -------- .../FileSystemContentRepository.java | 164 ---------- .../S3ContentRepository.java | 177 ---------- .../data/DocumentContent.java | 48 +++ .../data/DocumentCreateRequest.java | 61 ++++ ...eData.java => DocumentCreateResponse.java} | 37 +-- .../documentmanagement/data/DocumentData.java | 40 ++- .../data/DocumentDeleteRequest.java | 46 +++ .../data/DocumentDeleteResponse.java | 39 +++ .../data/DocumentUpdateRequest.java | 63 ++++ .../data/DocumentUpdateResponse.java | 39 +++ .../data/ImageCreateRequest.java | 61 ++++ .../data/ImageCreateResponse.java | 39 +++ .../documentmanagement/data/ImageData.java | 55 ---- .../data/ImageDeleteRequest.java | 44 +++ .../data/ImageDeleteResponse.java | 39 +++ .../documentmanagement/data/ImageResizer.java | 93 ------ .../documentmanagement/domain/Document.java | 162 ++-------- .../domain/DocumentRepository.java | 13 +- .../documentmanagement/domain/Image.java | 63 ++-- .../domain/ImageRepository.java | 7 +- .../exception/ContentManagementException.java | 39 --- ...a => DocumentInvalidRequestException.java} | 11 +- .../exception/DocumentNotFoundException.java | 20 +- .../handler/DocumentCreateCommandHandler.java | 51 +++ .../handler/DocumentDeleteCommandHandler.java | 51 +++ .../handler/DocumentUpdateCommandHandler.java | 51 +++ .../handler/ImageCreateCommandHandler.java | 51 +++ .../handler/ImageDeleteCommandHandler.java | 51 +++ .../mapping/DocumentMapper.java | 43 +++ .../service/DocumentReadPlatformService.java | 6 +- .../DocumentReadPlatformServiceImpl.java | 104 ++---- .../service/DocumentWritePlatformService.java | 24 +- .../DocumentWritePlatformServiceImpl.java | 175 ++++++++++ ...WritePlatformServiceJpaRepositoryImpl.java | 200 ------------ .../service/ImageReadPlatformService.java | 4 +- .../service/ImageReadPlatformServiceImpl.java | 69 ++++ .../service/ImageWritePlatformService.java | 17 +- .../ImageWritePlatformServiceImpl.java | 147 +++++++++ .../document/DocumentBusinessEvent.java | 6 +- .../DocumentCreatedBusinessEvent.java | 4 +- .../DocumentDeletedBusinessEvent.java | 4 +- .../module/fineract-document/persistence.xml | 78 ----- .../infrastructure/TestConfiguration.java | 44 +++ .../detector/FileContentDetectorTest.java | 52 +++ .../detector/TikaContentDetectorTest.java | 134 ++++++++ .../policy/MimeContentPolicyTest.java | 56 ++++ .../policy/TraversalContentPolicyTest.java | 63 ++++ .../processor/ContentProcessorTest.java | 170 ++++++++++ .../service/FileContentStoreServiceTest.java | 85 +++++ .../resources/application-test.properties | 36 +++ .../src/test/resources/test-gif.png | Bin 0 -> 1018890 bytes .../src/test/resources/test-large.jpg | Bin 0 -> 2080155 bytes fineract-document/src/test/resources/test.jpg | Bin 0 -> 3118 bytes fineract-document/src/test/resources/test.png | Bin 0 -> 741 bytes .../module/fineract-investor/persistence.xml | 1 - .../module/fineract-loan/persistence.xml | 1 - .../fineract-progressive-loan/persistence.xml | 1 - .../bulkimport/api/BulkImportApiResource.java | 47 ++- .../bulkimport/data/BulkImportEvent.java | 42 +-- .../bulkimport/domain/ImportDocument.java | 38 +-- .../mapping/ImportDocumentMapper.java | 44 +++ .../service/BulkImportEventListener.java | 69 ++-- .../BulkImportWorkbookServiceImpl.java | 146 ++++----- .../core/config/SecurityConfig.java | 86 +++++ .../core/jersey/JerseyConfig.java | 2 +- .../service/ImageReadPlatformServiceImpl.java | 110 ------- ...WritePlatformServiceJpaRepositoryImpl.java | 167 ---------- .../DocumentBusinessEventSerializer.java | 39 +-- .../staff/adapter/StaffImageIdAdapter.java | 66 ++++ .../staff/domain/StaffRepository.java | 11 +- .../portfolio/client/mapper/ClientMapper.java | 24 +- .../client/api/SelfClientsApiResource.java | 107 ++++++- .../src/main/resources/application.properties | 148 +++++---- .../module/fineract-provider/persistence.xml | 4 - .../DocumentBusinessEventSerializerTest.java | 18 +- .../module/fineract-rates/persistence.xml | 1 - .../module/fineract-report/persistence.xml | 1 - .../module/fineract-savings/persistence.xml | 1 - .../module/fineract-tax/persistence.xml | 1 - integration-tests/dependencies.gradle | 1 + .../LocalContentStorageUtil.java | 89 ++++++ .../client/ClientEntityImportHandlerTest.java | 3 +- .../loan/LoanImportHandlerTest.java | 3 +- .../office/OfficeImportHandlerTest.java | 13 +- .../savings/SavingsImportHandlerTest.java | 11 +- .../integrationtests/client/DocumentTest.java | 10 +- .../client/FeignDocumentTest.java | 6 +- .../integrationtests/client/ImageTest.java | 126 +++++--- .../integrationtests/common/Utils.java | 5 +- 172 files changed, 5928 insertions(+), 3100 deletions(-) create mode 100644 fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/adapter/EntityImageIdAdapter.java create mode 100644 fineract-core/src/main/java/org/apache/fineract/portfolio/client/adapter/ClientImageIdAdapter.java create mode 100644 fineract-core/src/main/java/org/apache/fineract/util/StreamResponseUtil.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/config/ContentStoreConfig.java rename fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/StorageType.java => fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/data/ContentStoreType.java (63%) rename fineract-document/src/main/java/org/apache/fineract/infrastructure/{documentmanagement/api/ImagesApiResourceSwagger.java => contentstore/detector/ContentDetector.java} (80%) create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/ContentDetectorContext.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/ContentDetectorManager.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/DefaultContentDetectorManager.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/FileContentDetector.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/TikaContentDetector.java rename fineract-document/src/main/java/org/apache/fineract/infrastructure/{documentmanagement/exception/InvalidEntityTypeForDocumentManagementException.java => contentstore/exception/ContentDetectorException.java} (59%) create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentPathSanitizerException.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentPolicyException.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentProcessorException.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentStoreException.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/ContentPolicy.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/ContentPolicyContext.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultDeleteContentPolicy.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultDownloadContentPolicy.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultPostUploadContentPolicy.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultPreUploadContentPolicy.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/MimeContentPolicy.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/TraversalContentPolicy.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/WhitelistContentPolicy.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/Base64DecoderContentProcessor.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/Base64EncoderContentProcessor.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/ContentProcessor.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/ContentProcessorContext.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/DataUrlDecoderContentProcessor.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/DataUrlEncoderContentProcessor.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/GzipDecoderContentProcessor.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/GzipEncoderContentProcessor.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/ImageResizeContentProcessor.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/SizeContentProcessor.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/service/ContentStoreService.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/service/FileContentStoreService.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/service/S3ContentStoreService.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/ContentPathRandomizer.java rename fineract-document/src/main/java/org/apache/fineract/infrastructure/{documentmanagement/contentrepository => contentstore/util}/ContentPathSanitizer.java (83%) create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/ContentPipe.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/DefaultContentPathRandomizer.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/DefaultContentPathSanitizer.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ContentResources.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentApiConstants.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentApiResource.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentManagementApiResource.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentManagementApiResourceSwagger.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImageApiConstants.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentCommandValidator.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentCreateCommand.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentDeleteCommand.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentUpdateCommand.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/ImageCreateCommand.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/ImageDeleteCommand.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentRepository.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentRepositoryFactory.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentRepositoryUtils.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/FileSystemContentPathSanitizer.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/FileSystemContentRepository.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/S3ContentRepository.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentContent.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentCreateRequest.java rename fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/{FileData.java => DocumentCreateResponse.java} (58%) rename {fineract-core => fineract-document}/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentData.java (59%) create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentDeleteRequest.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentDeleteResponse.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentUpdateRequest.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentUpdateResponse.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageCreateRequest.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageCreateResponse.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageData.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageDeleteRequest.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageDeleteResponse.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageResizer.java rename {fineract-core => fineract-document}/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Image.java (51%) delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/ContentManagementException.java rename fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/{InvalidEntityTypeForImageManagementException.java => DocumentInvalidRequestException.java} (70%) create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/DocumentCreateCommandHandler.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/DocumentDeleteCommandHandler.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/DocumentUpdateCommandHandler.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/ImageCreateCommandHandler.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/ImageDeleteCommandHandler.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/mapping/DocumentMapper.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceImpl.java delete mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageReadPlatformServiceImpl.java create mode 100644 fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformServiceImpl.java delete mode 100644 fineract-document/src/main/resources/jpa/static-weaving/module/fineract-document/persistence.xml create mode 100644 fineract-document/src/test/java/org/apache/fineract/infrastructure/TestConfiguration.java create mode 100644 fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/detector/FileContentDetectorTest.java create mode 100644 fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/detector/TikaContentDetectorTest.java create mode 100644 fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/policy/MimeContentPolicyTest.java create mode 100644 fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/policy/TraversalContentPolicyTest.java create mode 100644 fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/processor/ContentProcessorTest.java create mode 100644 fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/service/FileContentStoreServiceTest.java create mode 100644 fineract-document/src/test/resources/application-test.properties create mode 100644 fineract-document/src/test/resources/test-gif.png create mode 100644 fineract-document/src/test/resources/test-large.jpg create mode 100644 fineract-document/src/test/resources/test.jpg create mode 100644 fineract-document/src/test/resources/test.png create mode 100644 fineract-provider/src/main/java/org/apache/fineract/infrastructure/bulkimport/mapping/ImportDocumentMapper.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageReadPlatformServiceImpl.java delete mode 100644 fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformServiceJpaRepositoryImpl.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/organisation/staff/adapter/StaffImageIdAdapter.java create mode 100644 integration-tests/src/test/java/org/apache/fineract/integrationtests/bulkimport/importhandler/LocalContentStorageUtil.java diff --git a/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle b/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle index cab710d68..271bf5d8a 100644 --- a/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle +++ b/buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle @@ -114,6 +114,23 @@ dependencyManagement { exclude 'org.apache.commons:commons-compress' exclude 'xml-apis:xml-apis' } + dependency ('org.apache.tika:tika-parser-image-module:3.2.3') { + exclude 'org.bouncycastle:bcprov-jdk15on' + exclude 'org.bouncycastle:bcjmail-jdk15on' + exclude 'org.bouncycastle:bcprov-jdk18on' + exclude 'org.bouncycastle:bcjmail-jdk18on' + exclude 'commons-logging:commons-logging' + exclude 'org.apache.logging.log4j:log4j-api' + exclude 'org.slf4j:slf4j-api' + exclude 'commons-io:commons-io' + exclude 'commons-codec:commons-codec' + exclude 'org.apache.commons:commons-lang3' + exclude 'org.apache.poi:poi' + exclude 'org.apache.poi:poi-scratchpad' + exclude 'org.glassfish.jaxb:jaxb-runtime' + exclude 'org.apache.commons:commons-compress' + exclude 'xml-apis:xml-apis' + } dependency ('org.apache.httpcomponents:httpclient:4.5.14') { exclude 'commons-logging:commons-logging:' } @@ -265,6 +282,12 @@ dependencyManagement { dependency 'com.lmax:disruptor:3.4.4' + dependency ('com.github.romankh3:image-comparison:4.4.0') { + exclude 'org.junit.jupiter:junit-jupiter-api' + exclude 'org.junit.jupiter:junit-jupiter-engine' + exclude 'org.mockito:mockito-core' + } + dependency 'com.ibm.icu:icu4j:76.1' dependency 'org.yakworks:spring-icu4j:0.4.2' dependency 'org.apache.commons:commons-lang3:3.18.0' diff --git a/config/docker/compose/fineract.yml b/config/docker/compose/fineract.yml index 801b73fc6..4d92fdf49 100644 --- a/config/docker/compose/fineract.yml +++ b/config/docker/compose/fineract.yml @@ -18,12 +18,13 @@ services: fineract: - # user: "${FINERACT_USER}:${FINERACT_GROUP}" image: fineract:latest + user: "${FINERACT_USER}:${FINERACT_GROUP}" volumes: - ${PWD}/config/docker/logback/logback-override.xml:/app/logback-override.xml - ${PWD}/config/docker/aws/etc/credentials:/etc/aws/credentials:ro - ${PWD}/build/fineract/logs:/var/logs/fineract:rw + # - ${PWD}/build/fineract/tmp:/tmp:rw healthcheck: test: ["CMD", 'sh', '-c', 'echo -e "Checking for the availability of Fineract server deployment"; while ! nc -z "localhost" 8443; do sleep 1; printf "-"; done; echo -e " >> Fineract server has started";' ] timeout: 1s diff --git a/config/docker/env/fineract-common.env b/config/docker/env/fineract-common.env index 4b0dc2465..78ac9951f 100644 --- a/config/docker/env/fineract-common.env +++ b/config/docker/env/fineract-common.env @@ -54,6 +54,7 @@ FINERACT_MANAGEMENT_ENDPOINT_WEB_EXPOSURE_INCLUDE=health,info,prometheus FINERACT_MANAGEMENT_METRICS_TAGS_APPLICATION=fineract FINERACT_REMOTE_JOB_MESSAGE_HANDLER_SPRING_EVENTS_ENABLED=true FINERACT_INSECURE_HTTP_CLIENT=true +FINERACT_CONTENT_FILESYSTEM_ROOT_FOLDER=/tmp SPRING_PROFILES_ACTIVE=test,diagnostics OTEL_SERVICE_NAME=fineract -JAVA_TOOL_OPTIONS=" -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5000 -Xmx1G -XX:MinRAMPercentage=25 -XX:MaxRAMPercentage=80 -XX:TieredStopAtLevel=1 -XX:+UseContainerSupport -XX:+UseStringDeduplication --add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.management/javax.management=ALL-UNNAMED --add-opens=java.naming/javax.naming=ALL-UNNAMED" +JAVA_TOOL_OPTIONS="-Xmx1G -XX:MinRAMPercentage=25 -XX:MaxRAMPercentage=80 -XX:TieredStopAtLevel=1 -XX:+UseContainerSupport -XX:+UseStringDeduplication -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5000 --add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.management/javax.management=ALL-UNNAMED --add-opens=java.naming/javax.naming=ALL-UNNAMED" diff --git a/fineract-accounting/src/main/resources/jpa/static-weaving/module/fineract-accounting/persistence.xml b/fineract-accounting/src/main/resources/jpa/static-weaving/module/fineract-accounting/persistence.xml index 60e55ff84..81504a3f7 100644 --- a/fineract-accounting/src/main/resources/jpa/static-weaving/module/fineract-accounting/persistence.xml +++ b/fineract-accounting/src/main/resources/jpa/static-weaving/module/fineract-accounting/persistence.xml @@ -34,7 +34,6 @@ org.apache.fineract.useradministration.domain.Role org.apache.fineract.portfolio.fund.domain.Fund - org.apache.fineract.infrastructure.documentmanagement.domain.Image org.apache.fineract.organisation.workingdays.domain.WorkingDays org.apache.fineract.useradministration.domain.Permission org.apache.fineract.useradministration.domain.AppUserClientMapping diff --git a/fineract-branch/src/main/resources/jpa/static-weaving/module/fineract-branch/persistence.xml b/fineract-branch/src/main/resources/jpa/static-weaving/module/fineract-branch/persistence.xml index 5e972e532..9d976c68d 100644 --- a/fineract-branch/src/main/resources/jpa/static-weaving/module/fineract-branch/persistence.xml +++ b/fineract-branch/src/main/resources/jpa/static-weaving/module/fineract-branch/persistence.xml @@ -34,7 +34,6 @@ org.apache.fineract.useradministration.domain.Role org.apache.fineract.portfolio.fund.domain.Fund - org.apache.fineract.infrastructure.documentmanagement.domain.Image org.apache.fineract.organisation.workingdays.domain.WorkingDays org.apache.fineract.useradministration.domain.Permission org.apache.fineract.useradministration.domain.AppUserClientMapping diff --git a/fineract-charge/src/main/resources/jpa/static-weaving/module/fineract-charge/persistence.xml b/fineract-charge/src/main/resources/jpa/static-weaving/module/fineract-charge/persistence.xml index 695790147..fb0b9cf94 100644 --- a/fineract-charge/src/main/resources/jpa/static-weaving/module/fineract-charge/persistence.xml +++ b/fineract-charge/src/main/resources/jpa/static-weaving/module/fineract-charge/persistence.xml @@ -34,7 +34,6 @@ org.apache.fineract.useradministration.domain.Role org.apache.fineract.portfolio.fund.domain.Fund - org.apache.fineract.infrastructure.documentmanagement.domain.Image org.apache.fineract.organisation.workingdays.domain.WorkingDays org.apache.fineract.useradministration.domain.Permission org.apache.fineract.useradministration.domain.AppUserClientMapping diff --git a/fineract-client-feign/src/main/java/org/apache/fineract/client/feign/services/DocumentsApiFixed.java b/fineract-client-feign/src/main/java/org/apache/fineract/client/feign/services/DocumentsApiFixed.java index 39fd22156..1d9aad236 100644 --- a/fineract-client-feign/src/main/java/org/apache/fineract/client/feign/services/DocumentsApiFixed.java +++ b/fineract-client-feign/src/main/java/org/apache/fineract/client/feign/services/DocumentsApiFixed.java @@ -22,10 +22,10 @@ import feign.Param; import feign.RequestLine; import feign.Response; import java.util.List; -import org.apache.fineract.client.models.DeleteEntityTypeEntityIdDocumentsResponse; +import org.apache.fineract.client.models.DocumentCreateResponse; import org.apache.fineract.client.models.DocumentData; -import org.apache.fineract.client.models.PostEntityTypeEntityIdDocumentsResponse; -import org.apache.fineract.client.models.PutEntityTypeEntityIdDocumentsResponse; +import org.apache.fineract.client.models.DocumentDeleteResponse; +import org.apache.fineract.client.models.DocumentUpdateResponse; /** * This class was originally generated by OpenAPI Generator, but then had @@ -44,7 +44,7 @@ public interface DocumentsApiFixed { * @return PostEntityTypeEntityIdDocumentsResponse */ @RequestLine("POST /v1/{entityType}/{entityId}/documents") - PostEntityTypeEntityIdDocumentsResponse createDocument(@Param("entityType") String entityType, @Param("entityId") Long entityId, + DocumentCreateResponse createDocument(@Param("entityType") String entityType, @Param("entityId") Long entityId, org.apache.fineract.client.feign.FineractMultipartEncoder.MultipartData multipartData); /** @@ -59,7 +59,7 @@ public interface DocumentsApiFixed { * @return DeleteEntityTypeEntityIdDocumentsResponse */ @RequestLine("DELETE /v1/{entityType}/{entityId}/documents/{documentId}") - DeleteEntityTypeEntityIdDocumentsResponse deleteDocument(@Param("entityType") String entityType, @Param("entityId") Long entityId, + DocumentDeleteResponse deleteDocument(@Param("entityType") String entityType, @Param("entityId") Long entityId, @Param("documentId") Long documentId); /** @@ -114,6 +114,6 @@ public interface DocumentsApiFixed { * @return PutEntityTypeEntityIdDocumentsResponse */ @RequestLine("PUT /v1/{entityType}/{entityId}/documents/{documentId}") - PutEntityTypeEntityIdDocumentsResponse updateDocument(@Param("entityType") String entityType, @Param("entityId") Long entityId, + DocumentUpdateResponse updateDocument(@Param("entityType") String entityType, @Param("entityId") Long entityId, @Param("documentId") Long documentId, org.apache.fineract.client.feign.FineractMultipartEncoder.MultipartData multipartData); } diff --git a/fineract-client-feign/src/test/java/org/apache/fineract/client/services/DocumentsApiFixedIntegrationTest.java b/fineract-client-feign/src/test/java/org/apache/fineract/client/services/DocumentsApiFixedIntegrationTest.java index d19703607..b59be072c 100644 --- a/fineract-client-feign/src/test/java/org/apache/fineract/client/services/DocumentsApiFixedIntegrationTest.java +++ b/fineract-client-feign/src/test/java/org/apache/fineract/client/services/DocumentsApiFixedIntegrationTest.java @@ -35,7 +35,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; import org.apache.fineract.client.feign.FineractFeignClientConfig; import org.apache.fineract.client.feign.services.DocumentsApiFixed; -import org.apache.fineract.client.models.DeleteEntityTypeEntityIdDocumentsResponse; import org.apache.fineract.client.models.DocumentData; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -149,7 +148,7 @@ class DocumentsApiFixedIntegrationTest { .willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json").withBody(responseBody))); DocumentsApiFixed api = config.createClient(DocumentsApiFixed.class); - DeleteEntityTypeEntityIdDocumentsResponse response = api.deleteDocument("clients", 123L, 456L); + var response = api.deleteDocument("clients", 123L, 456L); assertThat(response).isNotNull(); assertThat(response.getResourceId()).isEqualTo(456L); @@ -162,7 +161,7 @@ class DocumentsApiFixedIntegrationTest { .willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json").withBody(responseBody))); DocumentsApiFixed api = config.createClient(DocumentsApiFixed.class); - DeleteEntityTypeEntityIdDocumentsResponse response = api.deleteDocument("loans", 789L, 999L); + var response = api.deleteDocument("loans", 789L, 999L); assertThat(response).isNotNull(); assertThat(response.getResourceId()).isEqualTo(999L); diff --git a/fineract-client/build.gradle b/fineract-client/build.gradle index 3017b6dfd..4acfe358a 100644 --- a/fineract-client/build.gradle +++ b/fineract-client/build.gradle @@ -17,6 +17,7 @@ * under the License. */ apply plugin: 'org.openapi.generator' +apply plugin: 'idea' description = 'Fineract Client' apply from: 'dependencies.gradle' @@ -35,6 +36,19 @@ openApiValidate { recommend = true } +openApiGenerate { + outputDir = "$buildDir/generated/temp-java".toString() +} + +idea { + module { + // Marks the generated directory as a Source Root + sourceDirs += file("$buildDir/generated/temp-java/src/main/java") + // Or use generatedSourceDirs for explicit "Generated Source" marking + generatedSourceDirs += file("$buildDir/generated/temp-java/src/main/java") + } +} + task buildJavaSdk(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask) { generatorName = 'java' verbose = false diff --git a/fineract-client/src/main/java/org/apache/fineract/client/services/DocumentsApiFixed.java b/fineract-client/src/main/java/org/apache/fineract/client/services/DocumentsApiFixed.java index 8d56912fb..647054177 100644 --- a/fineract-client/src/main/java/org/apache/fineract/client/services/DocumentsApiFixed.java +++ b/fineract-client/src/main/java/org/apache/fineract/client/services/DocumentsApiFixed.java @@ -20,10 +20,10 @@ package org.apache.fineract.client.services; import java.util.List; import okhttp3.ResponseBody; -import org.apache.fineract.client.models.DeleteEntityTypeEntityIdDocumentsResponse; +import org.apache.fineract.client.models.DocumentCreateResponse; import org.apache.fineract.client.models.DocumentData; -import org.apache.fineract.client.models.PostEntityTypeEntityIdDocumentsResponse; -import org.apache.fineract.client.models.PutEntityTypeEntityIdDocumentsResponse; +import org.apache.fineract.client.models.DocumentDeleteResponse; +import org.apache.fineract.client.models.DocumentUpdateResponse; import retrofit2.Call; import retrofit2.http.DELETE; import retrofit2.http.GET; @@ -54,7 +54,7 @@ public interface DocumentsApiFixed { */ @retrofit2.http.Multipart @POST("v1/{entityType}/{entityId}/documents") - Call createDocument(@retrofit2.http.Path("entityType") String entityType, + Call createDocument(@retrofit2.http.Path("entityType") String entityType, @retrofit2.http.Path("entityId") Long entityId, @retrofit2.http.Part okhttp3.MultipartBody.Part file, @retrofit2.http.Part("name") String name, @retrofit2.http.Part("description") String description); @@ -70,7 +70,7 @@ public interface DocumentsApiFixed { * @return Call<DeleteEntityTypeEntityIdDocumentsResponse> */ @DELETE("v1/{entityType}/{entityId}/documents/{documentId}") - Call deleteDocument(@retrofit2.http.Path("entityType") String entityType, + Call deleteDocument(@retrofit2.http.Path("entityType") String entityType, @retrofit2.http.Path("entityId") Long entityId, @retrofit2.http.Path("documentId") Long documentId); /** @@ -139,7 +139,7 @@ public interface DocumentsApiFixed { */ @retrofit2.http.Multipart @PUT("v1/{entityType}/{entityId}/documents/{documentId}") - Call updateDocument(@retrofit2.http.Path("entityType") String entityType, + Call updateDocument(@retrofit2.http.Path("entityType") String entityType, @retrofit2.http.Path("entityId") Long entityId, @retrofit2.http.Path("documentId") Long documentId, @retrofit2.http.Part okhttp3.MultipartBody.Part file, @retrofit2.http.Part("name") String name, @retrofit2.http.Part("description") String description); diff --git a/fineract-cob/src/main/resources/jpa/static-weaving/module/fineract-cob/persistence.xml b/fineract-cob/src/main/resources/jpa/static-weaving/module/fineract-cob/persistence.xml index 78d58dca7..509a60dd9 100644 --- a/fineract-cob/src/main/resources/jpa/static-weaving/module/fineract-cob/persistence.xml +++ b/fineract-cob/src/main/resources/jpa/static-weaving/module/fineract-cob/persistence.xml @@ -33,7 +33,6 @@ org.apache.fineract.useradministration.domain.Role org.apache.fineract.portfolio.fund.domain.Fund - org.apache.fineract.infrastructure.documentmanagement.domain.Image org.apache.fineract.organisation.workingdays.domain.WorkingDays org.apache.fineract.useradministration.domain.Permission org.apache.fineract.useradministration.domain.AppUserClientMapping diff --git a/fineract-command/src/main/java/org/apache/fineract/command/implementation/DefaultCommandAuditor.java b/fineract-command/src/main/java/org/apache/fineract/command/implementation/DefaultCommandAuditor.java index 410560f9a..6946b8cd2 100644 --- a/fineract-command/src/main/java/org/apache/fineract/command/implementation/DefaultCommandAuditor.java +++ b/fineract-command/src/main/java/org/apache/fineract/command/implementation/DefaultCommandAuditor.java @@ -114,6 +114,7 @@ public class DefaultCommandAuditor implements CommandAuditor { final var now = Instant.now(); final var commandEntity = mapper.map(command); + commandEntity.setExecutedAt(now); commandEntity.setUpdatedAt(now); commandEntity.setState(ERROR); @@ -138,7 +139,17 @@ public class DefaultCommandAuditor implements CommandAuditor { @Retry(name = "commandAuditFallback", fallbackMethod = "fatal") @SuppressWarnings("UnusedMethod") - private void fallback(Command command, Throwable t) throws Exception { + void fallback(Command command, Throwable t) throws Exception { + if (Boolean.TRUE.equals(properties.getFileDeadLetterQueueEnabled())) { + fallback(command, null, t); + } else { + fatal(command, t); + } + } + + @Retry(name = "commandAuditFallback", fallbackMethod = "fatal") + @SuppressWarnings("UnusedMethod") + void fallback(Command command, Object response, Throwable t) throws Exception { if (Boolean.TRUE.equals(properties.getFileDeadLetterQueueEnabled())) { setError(command, t); write(command); @@ -148,7 +159,12 @@ public class DefaultCommandAuditor implements CommandAuditor { } @SuppressWarnings("UnusedMethod") - private void fatal(Command command, Throwable t) { + void fatal(Command command, Throwable t) { + fatal(command, null, t); + } + + @SuppressWarnings("UnusedMethod") + void fatal(Command command, Object response, Throwable t) { // note: last line of defense; if this fails then all is lost setError(command, t); log.error("Command audit error: {}", command, t); diff --git a/fineract-command/src/main/java/org/apache/fineract/command/starter/CommandPersistenceConfiguration.java b/fineract-command/src/main/java/org/apache/fineract/command/starter/CommandPersistenceConfiguration.java index 43d3a73b0..110908f75 100644 --- a/fineract-command/src/main/java/org/apache/fineract/command/starter/CommandPersistenceConfiguration.java +++ b/fineract-command/src/main/java/org/apache/fineract/command/starter/CommandPersistenceConfiguration.java @@ -28,7 +28,7 @@ import org.springframework.data.jdbc.core.convert.JdbcCustomConversions; import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; @Configuration -@EnableJdbcRepositories(basePackages = { "org.apache.fineract.command.persistence" }) +@EnableJdbcRepositories(basePackages = { "org.apache.fineract.**.domain", "org.apache.fineract.**.persistence" }) @ComponentScan("org.apache.fineract.command.persistence") class CommandPersistenceConfiguration { diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportData.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportData.java index 445f3667f..2b8dc3a68 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportData.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/data/ImportData.java @@ -19,7 +19,13 @@ package org.apache.fineract.infrastructure.bulkimport.data; import java.time.LocalDate; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +@AllArgsConstructor +@NoArgsConstructor +@Data public final class ImportData { @SuppressWarnings("unused") @@ -27,6 +33,8 @@ public final class ImportData { @SuppressWarnings("unused") private Long documentId; @SuppressWarnings("unused") + private Integer entityType; + @SuppressWarnings("unused") private String name; @SuppressWarnings("unused") private LocalDate importTime; diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookService.java index 30dd64e46..68889f9dd 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookService.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/bulkimport/service/BulkImportWorkbookService.java @@ -18,12 +18,10 @@ */ package org.apache.fineract.infrastructure.bulkimport.service; -import jakarta.ws.rs.core.Response; import java.io.InputStream; import java.util.Collection; import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType; import org.apache.fineract.infrastructure.bulkimport.data.ImportData; -import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData; import org.glassfish.jersey.media.multipart.FormDataContentDisposition; public interface BulkImportWorkbookService { @@ -33,8 +31,5 @@ public interface BulkImportWorkbookService { Collection getImports(GlobalEntityType type); - DocumentData getOutputTemplateLocation(String importDocumentId); - - Response getOutputTemplate(String importDocumentId); - + ImportData getImport(Long id); } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java index 9730467be..26100f390 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java @@ -364,6 +364,7 @@ public class FineractProperties { private List regexWhitelist; private boolean mimeWhitelistEnabled; private List mimeWhitelist; + private Integer defaultBufferSize; private FineractContentFilesystemProperties filesystem; private FineractContentS3Properties s3; } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/adapter/EntityImageIdAdapter.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/adapter/EntityImageIdAdapter.java new file mode 100644 index 000000000..f763f7268 --- /dev/null +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/adapter/EntityImageIdAdapter.java @@ -0,0 +1,51 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.adapter; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Optional; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +// NOTE: this is a trick to decouple the entity image IDs from the image service +@Deprecated +public interface EntityImageIdAdapter { + + boolean accept(String entityType); + + Optional get(Long entityId); + + Optional set(Long entityId, Long imageId); + + @Builder + @Data + @NoArgsConstructor + @AllArgsConstructor + class ImageIdResult implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Long id; + private String displayName; + } +} diff --git a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/handler/CurrencyUpdateCommandHandler.java b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/handler/CurrencyUpdateCommandHandler.java index 312344862..7fc73a2fc 100644 --- a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/handler/CurrencyUpdateCommandHandler.java +++ b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/handler/CurrencyUpdateCommandHandler.java @@ -40,7 +40,6 @@ public class CurrencyUpdateCommandHandler implements CommandHandler command) { - // NOTE: fallback method needs to be in the same class return writePlatformService.updateAllowedCurrencies(command.getPayload()); } diff --git a/fineract-core/src/main/java/org/apache/fineract/organisation/staff/domain/Staff.java b/fineract-core/src/main/java/org/apache/fineract/organisation/staff/domain/Staff.java index 7830c40f6..477c3df13 100644 --- a/fineract-core/src/main/java/org/apache/fineract/organisation/staff/domain/Staff.java +++ b/fineract-core/src/main/java/org/apache/fineract/organisation/staff/domain/Staff.java @@ -22,7 +22,6 @@ import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import jakarta.persistence.UniqueConstraint; import java.time.LocalDate; @@ -33,7 +32,6 @@ import org.apache.commons.lang3.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.EnumOptionData; import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; -import org.apache.fineract.infrastructure.documentmanagement.domain.Image; import org.apache.fineract.organisation.office.domain.Office; @Getter @@ -81,9 +79,8 @@ public class Staff extends AbstractPersistableCustom { @JoinColumn(name = "organisational_role_parent_staff_id") private Staff organisationalRoleParentStaff; - @OneToOne(optional = true) - @JoinColumn(name = "image_id") - private Image image; + @Column(name = "image_id") + private Long imageId; public static Staff fromJson(final Office staffOffice, final JsonCommand command) { @@ -262,8 +259,4 @@ public class Staff extends AbstractPersistableCustom { return this.office; } - public void setImage(Image image) { - this.image = image; - } - } diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/adapter/ClientImageIdAdapter.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/adapter/ClientImageIdAdapter.java new file mode 100644 index 000000000..b46c79cc5 --- /dev/null +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/adapter/ClientImageIdAdapter.java @@ -0,0 +1,66 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.client.adapter; + +import static java.util.Objects.nonNull; + +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.documentmanagement.adapter.EntityImageIdAdapter; +import org.apache.fineract.portfolio.client.domain.ClientRepository; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@RequiredArgsConstructor +@Component +@Deprecated +class ClientImageIdAdapter implements EntityImageIdAdapter { + + private static final String ENTITY_TYPE = "clients"; + + private final ClientRepository repository; + + @Override + public boolean accept(String entityType) { + return ENTITY_TYPE.equalsIgnoreCase(entityType); + } + + @Override + @Transactional(readOnly = true) + public Optional get(Long entityId) { + return repository.findById(entityId).filter(client -> nonNull(client.getImageId())) + .map(client -> ImageIdResult.builder().id(client.getImageId()).displayName(client.getDisplayName()).build()); + } + + @Override + @Transactional + public Optional set(Long entityId, Long imageId) { + final var result = get(entityId); + + if (imageId == null) { + repository.removeImageId(entityId); + } else { + repository.updateByIdAndImageId(entityId, imageId); + } + + return result; + } +} diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java index 60fafa98a..951128679 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java @@ -27,7 +27,6 @@ import jakarta.persistence.JoinTable; import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; -import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import jakarta.persistence.UniqueConstraint; import java.time.LocalDate; @@ -46,7 +45,6 @@ import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDa import org.apache.fineract.infrastructure.core.domain.ExternalId; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.infrastructure.core.service.DateUtils; -import org.apache.fineract.infrastructure.documentmanagement.domain.Image; import org.apache.fineract.infrastructure.security.service.RandomPasswordGenerator; import org.apache.fineract.organisation.office.domain.Office; import org.apache.fineract.organisation.staff.domain.Staff; @@ -72,13 +70,9 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom { @JoinColumn(name = "transfer_to_office_id") private Office transferToOffice; - @OneToOne(optional = true) - @JoinColumn(name = "image_id") - private Image image; + @Column(name = "image_id") + private Long imageId; - /** - * A value from {@link ClientStatus}. - */ @Column(name = "status_enum", nullable = false) private Integer status; @@ -494,10 +488,6 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom { return this.office.getId(); } - public void setImage(final Image image) { - this.image = image; - } - public String mobileNo() { return this.mobileNo; } @@ -510,10 +500,6 @@ public class Client extends AbstractAuditableWithUTCDateTimeCustom { this.mobileNo = mobileNo; } - public boolean isNotStaff() { - return !isStaff(); - } - public boolean isStaff() { return this.isStaff; } diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepository.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepository.java index f3a9ff112..055789653 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepository.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/client/domain/ClientRepository.java @@ -22,6 +22,7 @@ import org.apache.fineract.infrastructure.core.domain.ExternalId; import org.apache.fineract.portfolio.client.domain.search.SearchingClientRepository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -46,4 +47,11 @@ public interface ClientRepository extends JpaRepository, JpaSpecif @Query("SELECT c.id FROM Client c WHERE c.externalId = :externalId") Long findIdByExternalId(@Param("externalId") ExternalId externalId); + @Modifying + @Query("UPDATE Client client SET client.imageId = :imageId WHERE client.id = :clientId") + void updateByIdAndImageId(@Param("clientId") Long staffId, @Param("imageId") Long imageId); + + @Modifying + @Query("UPDATE Client client SET client.imageId = null WHERE client.id = :clientId") + void removeImageId(@Param("clientId") Long clientId); } diff --git a/fineract-core/src/main/java/org/apache/fineract/util/StreamResponseUtil.java b/fineract-core/src/main/java/org/apache/fineract/util/StreamResponseUtil.java new file mode 100644 index 000000000..9beb490df --- /dev/null +++ b/fineract-core/src/main/java/org/apache/fineract/util/StreamResponseUtil.java @@ -0,0 +1,89 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.util; + +import jakarta.ws.rs.container.AsyncResponse; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.StreamingOutput; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; + +@Slf4j +public final class StreamResponseUtil { + + public static String DISPOSITION_TYPE_ATTACHMENT = "attachment"; + public static String DISPOSITION_TYPE_INLINE = "inline"; + + private static final ExecutorService executor = Executors.newCachedThreadPool(); + + private StreamResponseUtil() {} + + public static Response ok(final StreamResponseData content) { + final var stream = new StreamingOutput() { + + @Override + public void write(OutputStream out) throws IOException { + IOUtils.copy(content.getStream(), out); + } + }; + + if (StringUtils.isEmpty(content.getDispositionType())) { + return Response.ok(stream, content.getType()).build(); + } else { + return Response.ok(stream, content.getType()).header(HttpHeaders.CONTENT_DISPOSITION, + String.format("%s; filename=\"%s\"", content.getDispositionType(), content.getFileName())).build(); + } + } + + public static Future ok(final AsyncResponse asyncResponse, final StreamResponseData content) { + return executor.submit(() -> { + if (StringUtils.isEmpty(content.getDispositionType())) { + asyncResponse.resume(Response.ok(content.getStream(), content.getType()).build()); + } else { + asyncResponse.resume(Response.ok(content.getStream(), content.getType()).header(HttpHeaders.CONTENT_DISPOSITION, + String.format("%s; filename=\"%s\"", content.getDispositionType(), content.getFileName())).build()); + } + }); + } + + @Builder + @Data + @NoArgsConstructor + @AllArgsConstructor + public static final class StreamResponseData { + + private InputStream stream; + private String type; + private String fileName; + private String dispositionType; + private Long size; + } +} diff --git a/fineract-core/src/main/resources/jpa/static-weaving/module/fineract-core/persistence.xml b/fineract-core/src/main/resources/jpa/static-weaving/module/fineract-core/persistence.xml index aeb8e6522..551f6cbee 100644 --- a/fineract-core/src/main/resources/jpa/static-weaving/module/fineract-core/persistence.xml +++ b/fineract-core/src/main/resources/jpa/static-weaving/module/fineract-core/persistence.xml @@ -34,7 +34,6 @@ org.apache.fineract.useradministration.domain.Role org.apache.fineract.portfolio.fund.domain.Fund - org.apache.fineract.infrastructure.documentmanagement.domain.Image org.apache.fineract.organisation.workingdays.domain.WorkingDays org.apache.fineract.useradministration.domain.Permission org.apache.fineract.useradministration.domain.AppUserClientMapping diff --git a/fineract-document/dependencies.gradle b/fineract-document/dependencies.gradle index 0f4c8facd..e1cc0e429 100644 --- a/fineract-document/dependencies.gradle +++ b/fineract-document/dependencies.gradle @@ -24,27 +24,25 @@ dependencies { // implementation dependencies are directly used (compiled against) in src/main (and src/test) // - implementation(project(path: ':fineract-core')) + implementation( + project(path: ':fineract-core'), + project(path: ':fineract-command'), + ) implementation( 'org.springframework.boot:spring-boot-starter-web', + 'org.springframework.boot:spring-boot-starter-validation', 'org.springframework.boot:spring-boot-starter-security', + 'org.springframework.boot:spring-boot-starter-data-jdbc', 'jakarta.ws.rs:jakarta.ws.rs-api', 'org.glassfish.jersey.media:jersey-media-multipart', - - 'com.google.guava:guava', - 'com.google.code.gson:gson', + 'com.fasterxml.jackson.core:jackson-databind', 'org.apache.commons:commons-lang3', - 'com.jayway.jsonpath:json-path', - 'com.github.spotbugs:spotbugs-annotations', 'io.swagger.core.v3:swagger-annotations-jakarta', - 'com.squareup.retrofit2:converter-gson', - - 'org.springdoc:springdoc-openapi-starter-webmvc-ui', 'org.mapstruct:mapstruct', 'io.github.resilience4j:resilience4j-spring-boot3', @@ -53,6 +51,7 @@ dependencies { 'org.apache.tika:tika-core', 'org.apache.tika:tika-parser-microsoft-module', 'org.apache.tika:tika-parser-miscoffice-module', + 'org.apache.tika:tika-parser-image-module', ) compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' @@ -62,12 +61,6 @@ dependencies { } implementation ('software.amazon.awssdk:auth') { } - implementation ('org.springframework.boot:spring-boot-starter-data-jpa') { - exclude group: 'org.hibernate' - } - implementation('org.eclipse.persistence:org.eclipse.persistence.jpa') { - exclude group: 'org.eclipse.persistence', module: 'jakarta.persistence' - } // testCompile dependencies are ONLY used in src/test, not src/main. // Do NOT repeat dependencies which are ALREADY in implementation or runtimeOnly! // @@ -80,4 +73,5 @@ dependencies { exclude group: 'org.skyscreamer' } testImplementation ('org.mockito:mockito-inline') + testImplementation 'com.github.romankh3:image-comparison' } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/config/ContentStoreConfig.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/config/ContentStoreConfig.java new file mode 100644 index 000000000..2af614d85 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/config/ContentStoreConfig.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.config; + +import static org.apache.fineract.infrastructure.contentstore.processor.ContentProcessor.BEAN_NAME_EXECUTOR; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@RequiredArgsConstructor +class ContentStoreConfig { + + @Bean(BEAN_NAME_EXECUTOR) + ExecutorService contentProcessorExecutor() { + // TODO: make this more configurable? + return Executors.newCachedThreadPool(); + } +} diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/StorageType.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/data/ContentStoreType.java similarity index 63% rename from fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/StorageType.java rename to fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/data/ContentStoreType.java index 2bd697eb1..306952d60 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/StorageType.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/data/ContentStoreType.java @@ -16,36 +16,20 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.fineract.infrastructure.documentmanagement.domain; +package org.apache.fineract.infrastructure.contentstore.data; -import java.util.HashMap; -import java.util.Map; - -public enum StorageType { +public enum ContentStoreType { FILE_SYSTEM(1), // S3(2); // private final Integer value; - StorageType(final Integer value) { + ContentStoreType(final Integer value) { this.value = value; } public Integer getValue() { return this.value; } - - private static final Map intToEnumMap = new HashMap<>(); - - static { - for (final StorageType type : StorageType.values()) { - intToEnumMap.put(type.value, type); - } - } - - public static StorageType fromInt(final int i) { - final StorageType type = intToEnumMap.get(Integer.valueOf(i)); - return type; - } } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImagesApiResourceSwagger.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/ContentDetector.java similarity index 80% rename from fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImagesApiResourceSwagger.java rename to fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/ContentDetector.java index 1535c0b54..323b3c798 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImagesApiResourceSwagger.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/ContentDetector.java @@ -16,16 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.fineract.infrastructure.documentmanagement.api; +package org.apache.fineract.infrastructure.contentstore.detector; -/** - * Created by sanyam on 10/8/17. - */ - -final class ImagesApiResourceSwagger { - - private ImagesApiResourceSwagger() { - - } +public interface ContentDetector { + ContentDetectorContext detect(ContentDetectorContext ctx); } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/ContentDetectorContext.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/ContentDetectorContext.java new file mode 100644 index 000000000..fffbe0b4c --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/ContentDetectorContext.java @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.detector; + +import java.io.InputStream; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public final class ContentDetectorContext { + + private InputStream inputStream; + @Builder.Default + private boolean inputStreamEnabled = false; + private String fileName; + private String mimeType; + private String extension; + private String format; + + public ContentDetectorContext clone(String mimeType, String extension, String format) { + return new ContentDetectorContext(this.inputStream, this.inputStreamEnabled, this.fileName, mimeType, extension, format); + } + + public ContentDetectorContext clone(InputStream inputStream, String mimeType, String extension, String format) { + return new ContentDetectorContext(inputStream, this.inputStreamEnabled, this.fileName, mimeType, extension, format); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/ContentDetectorManager.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/ContentDetectorManager.java new file mode 100644 index 000000000..c7d5c0398 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/ContentDetectorManager.java @@ -0,0 +1,24 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.detector; + +public interface ContentDetectorManager { + + ContentDetectorContext detect(ContentDetectorContext ctx); +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/DefaultContentDetectorManager.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/DefaultContentDetectorManager.java new file mode 100644 index 000000000..d89bcb938 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/DefaultContentDetectorManager.java @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.detector; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public final class DefaultContentDetectorManager implements ContentDetectorManager { + + private final TikaContentDetector tikaContentDetector; + + @Override + public ContentDetectorContext detect(ContentDetectorContext ctx) { + return tikaContentDetector.detect(ctx); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/FileContentDetector.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/FileContentDetector.java new file mode 100644 index 000000000..048bc1a32 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/FileContentDetector.java @@ -0,0 +1,45 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.detector; + +import java.nio.file.Files; +import java.nio.file.Paths; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.apache.fineract.infrastructure.contentstore.exception.ContentDetectorException; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public final class FileContentDetector implements ContentDetector { + + @Override + public ContentDetectorContext detect(ContentDetectorContext ctx) { + try { + final var mimeType = Files.probeContentType(Paths.get(ctx.getFileName())); + final var format = FilenameUtils.getExtension(ctx.getFileName()); + + return ctx.clone(mimeType, "." + format, format); + } catch (Exception e) { + throw new ContentDetectorException(e); + } + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/TikaContentDetector.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/TikaContentDetector.java new file mode 100644 index 000000000..bdfbf7eef --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/detector/TikaContentDetector.java @@ -0,0 +1,88 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.detector; + +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.fineract.infrastructure.contentstore.exception.ContentDetectorException; +import org.apache.tika.Tika; +import org.apache.tika.io.TikaInputStream; +import org.apache.tika.metadata.Metadata; +import org.apache.tika.metadata.TikaCoreProperties; +import org.apache.tika.mime.MimeTypeException; +import org.apache.tika.mime.MimeTypes; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public final class TikaContentDetector implements ContentDetector { + + private final Tika tika = new Tika(); + + @Override + public ContentDetectorContext detect(ContentDetectorContext ctx) { + if (ctx.getInputStream() != null && !ctx.isInputStreamEnabled()) { + log.warn( + "Input stream provided, but not explicitly enabled for detection. This operation is potentially making the input stream unusable, especially with HTTP multipart streams. Input stream will be ignored!"); + } + + try { + if (ctx.getInputStream() != null && ctx.isInputStreamEnabled()) { + final var stream = TikaInputStream.get(ctx.getInputStream()); + final var metadata = new Metadata(); + metadata.set(TikaCoreProperties.RESOURCE_NAME_KEY, ctx.getFileName()); + + final var mimeType = tika.detect(stream, metadata); + final var extension = getExtension(mimeType); + + stream.reset(); + + // note: original stream should be still usable if "mark" is supported + return ctx.clone(mimeType, extension, extension.substring(1)); + } else if (StringUtils.isNotEmpty(ctx.getFileName())) { + final var mimeType = tika.detect(ctx.getFileName()); + final var extension = getExtension(mimeType); + + return ctx.clone(mimeType, extension, extension.substring(1)); + } + } catch (Exception e) { + throw new ContentDetectorException(e); + } + + throw new ContentDetectorException( + new IllegalArgumentException("Could not run detection, because required arguments were missing.")); + } + + private String getExtension(String mimeType) { + try { + return Optional.ofNullable(MimeTypes.getDefaultMimeTypes().forName(mimeType)).orElseGet(() -> { + try { + return MimeTypes.getDefaultMimeTypes().forName(MimeTypes.OCTET_STREAM); + } catch (MimeTypeException e) { + throw new ContentDetectorException(e); + } + }).getExtension(); + } catch (Exception e) { + throw new ContentDetectorException(e); + } + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/InvalidEntityTypeForDocumentManagementException.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentDetectorException.java similarity index 59% rename from fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/InvalidEntityTypeForDocumentManagementException.java rename to fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentDetectorException.java index 655f77106..d2fba0c53 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/InvalidEntityTypeForDocumentManagementException.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentDetectorException.java @@ -16,17 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.fineract.infrastructure.documentmanagement.exception; +package org.apache.fineract.infrastructure.contentstore.exception; -import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; +import org.apache.fineract.infrastructure.core.exception.AbstractPlatformException; -/** - * A {@link RuntimeException} thrown when document management functionality is invoked for invalid Entity Types - */ -public class InvalidEntityTypeForDocumentManagementException extends AbstractPlatformResourceNotFoundException { +public class ContentDetectorException extends AbstractPlatformException { - public InvalidEntityTypeForDocumentManagementException(final String entityType) { - super("error.documentmanagement.entitytype.invalid", "Document Management is not support for the Entity Type: " + entityType, - entityType); + public ContentDetectorException(Exception e) { + super("error.msg.content.detector", e.getMessage(), e); } } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentPathSanitizerException.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentPathSanitizerException.java new file mode 100644 index 000000000..56f149349 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentPathSanitizerException.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.exception; + +import org.apache.fineract.infrastructure.core.exception.AbstractPlatformException; + +public class ContentPathSanitizerException extends AbstractPlatformException { + + public ContentPathSanitizerException(String message) { + super("error.msg.content.sanitizer", message); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentPolicyException.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentPolicyException.java new file mode 100644 index 000000000..3ba139b11 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentPolicyException.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.exception; + +import org.apache.fineract.infrastructure.core.exception.AbstractPlatformException; + +public class ContentPolicyException extends AbstractPlatformException { + + public ContentPolicyException(String message) { + super("error.msg.content.policy", message); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentProcessorException.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentProcessorException.java new file mode 100644 index 000000000..1fe80600b --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentProcessorException.java @@ -0,0 +1,32 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.exception; + +import org.apache.fineract.infrastructure.core.exception.AbstractPlatformException; + +public class ContentProcessorException extends AbstractPlatformException { + + public ContentProcessorException(String message) { + super("error.msg.content.processor", message); + } + + public ContentProcessorException(Exception e) { + super("error.msg.content.processor", e.getMessage(), e); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentStoreException.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentStoreException.java new file mode 100644 index 000000000..9dc81396b --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/exception/ContentStoreException.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.exception; + +import org.apache.fineract.infrastructure.core.exception.AbstractPlatformException; + +public class ContentStoreException extends AbstractPlatformException { + + public ContentStoreException(Exception e) { + super("error.msg.content.store", e.getMessage(), e); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/ContentPolicy.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/ContentPolicy.java new file mode 100644 index 000000000..db6c7666a --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/ContentPolicy.java @@ -0,0 +1,24 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.policy; + +public interface ContentPolicy { + + void check(ContentPolicyContext ctx); +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/ContentPolicyContext.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/ContentPolicyContext.java new file mode 100644 index 000000000..9b27922ac --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/ContentPolicyContext.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.policy; + +import java.io.InputStream; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public final class ContentPolicyContext { + + private String path; + private Long size; + private InputStream inputStream; + private String mimeType; + private String extension; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultDeleteContentPolicy.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultDeleteContentPolicy.java new file mode 100644 index 000000000..9fb410118 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultDeleteContentPolicy.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.policy; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class DefaultDeleteContentPolicy implements ContentPolicy { + + private final TraversalContentPolicy traversalContentPolicy; + private final FineractProperties properties; + + @Override + public void check(ContentPolicyContext ctx) { + traversalContentPolicy.check(ctx); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultDownloadContentPolicy.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultDownloadContentPolicy.java new file mode 100644 index 000000000..2a0249911 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultDownloadContentPolicy.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.policy; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class DefaultDownloadContentPolicy implements ContentPolicy { + + private final TraversalContentPolicy traversalContentPolicy; + private final FineractProperties properties; + + @Override + public void check(ContentPolicyContext ctx) { + traversalContentPolicy.check(ctx); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultPostUploadContentPolicy.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultPostUploadContentPolicy.java new file mode 100644 index 000000000..c071545ed --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultPostUploadContentPolicy.java @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.policy; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class DefaultPostUploadContentPolicy implements ContentPolicy { + + private final MimeContentPolicy mimeContentPolicy; + + @Override + public void check(ContentPolicyContext ctx) { + mimeContentPolicy.check(ctx); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultPreUploadContentPolicy.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultPreUploadContentPolicy.java new file mode 100644 index 000000000..26f8beaf0 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/DefaultPreUploadContentPolicy.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.policy; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class DefaultPreUploadContentPolicy implements ContentPolicy { + + private final WhitelistContentPolicy whitelistContentPolicy; + private final TraversalContentPolicy traversalContentPolicy; + + @Override + public void check(ContentPolicyContext ctx) { + traversalContentPolicy.check(ctx); + whitelistContentPolicy.check(ctx); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/MimeContentPolicy.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/MimeContentPolicy.java new file mode 100644 index 000000000..e1218d564 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/MimeContentPolicy.java @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.policy; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.Strings; +import org.apache.fineract.infrastructure.contentstore.detector.ContentDetectorContext; +import org.apache.fineract.infrastructure.contentstore.detector.ContentDetectorManager; +import org.apache.fineract.infrastructure.contentstore.exception.ContentPolicyException; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class MimeContentPolicy implements ContentPolicy { + + private final ContentDetectorManager contentDetectorManager; + + @Override + public void check(ContentPolicyContext ctx) { + if (ctx.getInputStream() != null) { + var result = contentDetectorManager + .detect(ContentDetectorContext.builder().inputStream(ctx.getInputStream()).inputStreamEnabled(true).build()); + + if (!Strings.CI.equals(result.getMimeType(), ctx.getMimeType())) { + throw new ContentPolicyException(String.format("Detected file type (%s), but mime type (%s) was provided. Mismatch!", + result.getMimeType(), ctx.getMimeType())); + } + } + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/TraversalContentPolicy.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/TraversalContentPolicy.java new file mode 100644 index 000000000..7ca247d95 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/TraversalContentPolicy.java @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.policy; + +import java.util.regex.Pattern; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.contentstore.exception.ContentPolicyException; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class TraversalContentPolicy implements ContentPolicy { + + private final Pattern overwriteSiblingsPattern = Pattern.compile(".*((\\.)?\\./+)+(/+)?.*"); + + private final FineractProperties properties; + + @Override + public void check(ContentPolicyContext ctx) { + if (overwriteSiblingsPattern.matcher(ctx.getPath()).matches()) { + throw new ContentPolicyException(String.format("Trying to overwrite a sibling file: %s", ctx.getPath())); + } + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/WhitelistContentPolicy.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/WhitelistContentPolicy.java new file mode 100644 index 000000000..f12e37c09 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/policy/WhitelistContentPolicy.java @@ -0,0 +1,72 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.policy; + +import java.util.List; +import java.util.regex.Pattern; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.fineract.infrastructure.contentstore.exception.ContentPolicyException; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.boot.context.event.ApplicationStartedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class WhitelistContentPolicy implements ContentPolicy { + + private final FineractProperties properties; + + private List regexWhitelist; + + @EventListener(ApplicationStartedEvent.class) + void onStartup() { + regexWhitelist = properties.getContent().getRegexWhitelist().stream().map(Pattern::compile).toList(); + } + + @Override + public void check(ContentPolicyContext ctx) { + if (properties.getContent().isRegexWhitelistEnabled()) { + final var fileName = FilenameUtils.getName(ctx.getPath()); + + boolean matches = regexWhitelist.stream().anyMatch(p -> p.matcher(fileName).matches()); + + if (!matches) { + throw new ContentPolicyException(String.format("File name not allowed: %s", fileName)); + } + } + + if (properties.getContent().isMimeWhitelistEnabled()) { + final var fileName = FilenameUtils.getName(ctx.getPath()); + + if (StringUtils.isEmpty(ctx.getMimeType())) { + throw new ContentPolicyException(String.format("Could not detect mime type for filename %s!", fileName)); + } + + if (!properties.getContent().getMimeWhitelist().contains(ctx.getMimeType())) { + throw new ContentPolicyException( + String.format("Detected mime type %s for filename %s not allowed!", ctx.getMimeType(), fileName)); + } + } + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/Base64DecoderContentProcessor.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/Base64DecoderContentProcessor.java new file mode 100644 index 000000000..8a9245868 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/Base64DecoderContentProcessor.java @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.processor; + +import static java.util.Objects.requireNonNullElse; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Base64InputStream; +import org.apache.fineract.infrastructure.contentstore.util.ContentPipe; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class Base64DecoderContentProcessor implements ContentProcessor { + + private static final String BASE64_DECODE_PREFIX = "base64.decode."; + + public static final String BASE64_DECODE_PARAM_BUFFER_SIZE = BASE64_DECODE_PREFIX + "buffer-size"; + + private final ContentPipe pipe; + private final FineractProperties properties; + + @Override + public ContentProcessorContext process(final ContentProcessorContext ctx) { + final Integer bufferSize = ctx.getParameter(BASE64_DECODE_PARAM_BUFFER_SIZE, + requireNonNullElse(properties.getContent().getDefaultBufferSize(), 8192)); + + final var pipedInputStream = pipe.pipe(ctx.getInputStream(), (in, out) -> { + pipe.write(new Base64InputStream(in), out, new byte[bufferSize]); + }); + + return ctx.clone(pipedInputStream); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/Base64EncoderContentProcessor.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/Base64EncoderContentProcessor.java new file mode 100644 index 000000000..b870a94cb --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/Base64EncoderContentProcessor.java @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.processor; + +import static java.util.Objects.requireNonNullElse; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Base64OutputStream; +import org.apache.fineract.infrastructure.contentstore.util.ContentPipe; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class Base64EncoderContentProcessor implements ContentProcessor { + + private static final String BASE64_ENCODE_PREFIX = "base64.encode."; + + public static final String BASE64_ENCODE_PARAM_BUFFER_SIZE = BASE64_ENCODE_PREFIX + "buffer-size"; + + private final ContentPipe pipe; + private final FineractProperties properties; + + @Override + public ContentProcessorContext process(final ContentProcessorContext ctx) { + final Integer bufferSize = ctx.getParameter(BASE64_ENCODE_PARAM_BUFFER_SIZE, + requireNonNullElse(properties.getContent().getDefaultBufferSize(), 8192)); + + final var pipedInputStream = pipe.pipe(ctx.getInputStream(), (in, out) -> { + pipe.write(in, new Base64OutputStream(out), new byte[bufferSize]); + }); + + return ctx.clone(pipedInputStream); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/ContentProcessor.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/ContentProcessor.java new file mode 100644 index 000000000..6a882f415 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/ContentProcessor.java @@ -0,0 +1,59 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.processor; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; + +@FunctionalInterface +public interface ContentProcessor { + + String BEAN_NAME_EXECUTOR = "contentProcessorExecutor"; + + ContentProcessorContext process(ContentProcessorContext context); + + default void apply() { + // do nothing by default + } + + default ContentProcessorContext process(InputStream is) { + return process(new ContentProcessorContext(is)); + } + + default ContentProcessorContext process(InputStream is, Map parameters) { + return process(new ContentProcessorContext(is, parameters)); + } + + default ContentProcessor then(ContentProcessor next) { + return (context) -> next.process(this.process(context)); + } + + @FunctionalInterface + interface InputOutputStreamConsumer { + + void accept(InputStream input, OutputStream output) throws Exception; + } + + @FunctionalInterface + interface OutputStreamConsumer { + + void accept(OutputStream output) throws Exception; + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/ContentProcessorContext.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/ContentProcessorContext.java new file mode 100644 index 000000000..71cdc82a7 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/ContentProcessorContext.java @@ -0,0 +1,76 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.processor; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Getter +public final class ContentProcessorContext { + + private final InputStream inputStream; + private final Map parameters; + private final Map results; + + public ContentProcessorContext(InputStream inputStream) { + this(inputStream, Map.of(), new HashMap<>()); + } + + public ContentProcessorContext(InputStream inputStream, Map parameters) { + this(inputStream, parameters, new HashMap<>()); + } + + ContentProcessorContext(InputStream inputStream, Map parameters, Map results) { + this.inputStream = inputStream; + this.parameters = parameters; + this.results = results; + } + + public R getParameter(String key) { + return getParameter(key, null); + } + + public R getParameter(String key, R defaultValue) { + final var val = parameters.get(key); + + return val != null ? (R) val : defaultValue; + } + + public void setResult(String key, Object value) { + results.put(key, value); + } + + public R getResult(String key) { + return getResult(key, null); + } + + public R getResult(String key, R defaultValue) { + final var val = results.get(key); + + return val != null ? (R) val : defaultValue; + } + + public ContentProcessorContext clone(InputStream inputStream) { + return new ContentProcessorContext(inputStream, this.parameters, this.results); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/DataUrlDecoderContentProcessor.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/DataUrlDecoderContentProcessor.java new file mode 100644 index 000000000..608efe4d8 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/DataUrlDecoderContentProcessor.java @@ -0,0 +1,153 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.processor; + +import static java.util.Objects.requireNonNullElse; + +import java.io.ByteArrayOutputStream; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.fineract.infrastructure.contentstore.util.ContentPipe; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class DataUrlDecoderContentProcessor implements ContentProcessor { + + private static final String DATA_URL_PREFIX = "dataurl.decode."; + + public static final String DATA_URL_DECODE_RESULT_CONTENT_TYPE = DATA_URL_PREFIX + "result.content-type"; + public static final String DATA_URL_DECODE_RESULT_ENCODING = DATA_URL_PREFIX + "result.encoding"; + public static final String DATA_URL_DECODE_PARAM_BUFFER_SIZE = DATA_URL_PREFIX + "param.buffer-size"; + + private final ContentPipe pipe; + private final FineractProperties properties; + + @Override + public ContentProcessorContext process(final ContentProcessorContext ctx) { + final Integer bufferSize = ctx.getParameter(DATA_URL_DECODE_PARAM_BUFFER_SIZE, + requireNonNullElse(properties.getContent().getDefaultBufferSize(), 8192)); + + final var pipedInputStream = pipe.pipe(ctx.getInputStream(), (in, out) -> { + var dataUrlIn = new DataUrlInputStream(in); + + ctx.setResult(DATA_URL_DECODE_RESULT_CONTENT_TYPE, dataUrlIn.getContentType()); + ctx.setResult(DATA_URL_DECODE_RESULT_ENCODING, dataUrlIn.getEncoding()); + + pipe.write(dataUrlIn, out, new byte[bufferSize]); + }); + + return ctx.clone(pipedInputStream); + } + + private static class DataUrlInputStream extends FilterInputStream { + + private static final String DEFAULT_MEDIA_TYPE = "text/plain;charset=US-ASCII"; + private static final String ENCODING_BASE64 = "base64"; + private static final String ENCODING_URL = "urlencoded"; + private static final String META_PART = "data:"; + private static final char COMMA_CHAR = ','; + private static final char SEMICOLON_CHAR = ';'; + + private volatile String contentType; + private volatile String encoding; + + DataUrlInputStream(InputStream in) { + super(in); + } + + private void readHeaderProcessed() throws IOException { + if (StringUtils.isNotEmpty(contentType)) { + return; + } + + final var headerBuffer = new ByteArrayOutputStream(128); + + int b; + while ((b = in.read()) != -1) { + if (b == COMMA_CHAR) { + // stop reading header + break; + } + headerBuffer.write(b); + } + + var header = headerBuffer.toString(StandardCharsets.UTF_8); + + parseHeader(header); + } + + private void parseHeader(String header) { + if (!header.startsWith(META_PART)) { + this.contentType = DEFAULT_MEDIA_TYPE; + this.encoding = ENCODING_URL; + return; + } + + String metaPart = header.substring(5); // Remove "data:" + + if (metaPart.endsWith(SEMICOLON_CHAR + ENCODING_BASE64)) { + this.encoding = ENCODING_BASE64; + // remove ";base64" + metaPart = metaPart.substring(0, metaPart.length() - ENCODING_BASE64.length() - 1); + } else { + this.encoding = ENCODING_URL; + } + + if (metaPart.isEmpty()) { + this.contentType = DEFAULT_MEDIA_TYPE; + } else { + this.contentType = metaPart; + } + } + + String getContentType() throws IOException { + readHeaderProcessed(); + + return contentType; + } + + String getEncoding() throws IOException { + readHeaderProcessed(); + + return encoding; + } + + @Override + public int read() throws IOException { + readHeaderProcessed(); + + return in.read(); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + readHeaderProcessed(); + + return in.read(b, off, len); + } + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/DataUrlEncoderContentProcessor.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/DataUrlEncoderContentProcessor.java new file mode 100644 index 000000000..6163cea17 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/DataUrlEncoderContentProcessor.java @@ -0,0 +1,154 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.processor; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Objects.requireNonNullElse; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.contentstore.util.ContentPipe; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class DataUrlEncoderContentProcessor implements ContentProcessor { + + private static final String DATA_URL_ENCODE_PREFIX = "dataurl.encode."; + + public static final String DATA_URL_ENCODE_PARAM_BUFFER_SIZE = DATA_URL_ENCODE_PREFIX + "param.buffer-size"; + public static final String DATA_URL_ENCODE_PARAM_CONTENT_TYPE = DATA_URL_ENCODE_PREFIX + "param.content-type"; + public static final String DATA_URL_ENCODE_PARAM_ENCODING = DATA_URL_ENCODE_PREFIX + "param.encoding"; + + private final ContentPipe pipe; + private final FineractProperties properties; + + @Override + public ContentProcessorContext process(final ContentProcessorContext ctx) { + final Integer bufferSize = ctx.getParameter(DATA_URL_ENCODE_PARAM_BUFFER_SIZE, + requireNonNullElse(properties.getContent().getDefaultBufferSize(), 8192)); + final String contentType = ctx.getParameter(DATA_URL_ENCODE_PARAM_CONTENT_TYPE, "text/plain"); + final String encoding = ctx.getParameter(DATA_URL_ENCODE_PARAM_ENCODING, "charset=US-ASCII"); + + final var pipedInputStream = pipe.pipe(ctx.getInputStream(), (in, out) -> { + pipe.write(new DataUrlEncoderInputStream(in, contentType, encoding), out, new byte[bufferSize]); + }); + + return ctx.clone(pipedInputStream); + } + + private static class DataUrlEncoderInputStream extends FilterInputStream { + + private static final String META_PART = "data:"; + private static final char COMMA_CHAR = ','; + private static final char SEMICOLON_CHAR = ';'; + + private final byte[] prefix; + private int prefixIndex = 0; + + DataUrlEncoderInputStream(InputStream in, String contentType, String encoding) { + super(in); + this.prefix = (META_PART + contentType + SEMICOLON_CHAR + encoding + COMMA_CHAR).getBytes(UTF_8); + } + + private boolean isPrefixConsumed() { + return prefixIndex >= prefix.length; + } + + @Override + public int read() throws IOException { + if (!isPrefixConsumed()) { + // return the next byte of the prefix + // we need to cast to int and mask with 0xFF to ensure positive value (0-255) + return prefix[prefixIndex++] & 0xFF; + } + + // served the prefix, now the real stream starts + return in.read(); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + // optimization: do not call super.read(b, off, len) as that might call + // the single-byte read() repeatedly, which is slow. + + if (isPrefixConsumed()) { + return in.read(b, off, len); + } + + // still have prefix data to write + int availableInPrefix = prefix.length - prefixIndex; + + // fill the buffer with remaining prefix bytes (or as much as requested) + int bytesToCopyFromPrefix = Math.min(len, availableInPrefix); + + System.arraycopy(prefix, prefixIndex, b, off, bytesToCopyFromPrefix); + prefixIndex += bytesToCopyFromPrefix; + + // if we filled the request entirely with the prefix, return immediately + if (bytesToCopyFromPrefix == len) { + return len; + } + + // if we still have space in the buffer, fill the rest from the underlying stream + int bytesToReadFromStream = len - bytesToCopyFromPrefix; + int bytesReadFromStream = in.read(b, off + bytesToCopyFromPrefix, bytesToReadFromStream); + + if (bytesReadFromStream == -1) { + // underlying stream is empty, but we did write the prefix + return bytesToCopyFromPrefix; + } + + return bytesToCopyFromPrefix + bytesReadFromStream; + } + + @Override + public long skip(long n) throws IOException { + if (isPrefixConsumed()) { + return in.skip(n); + } + + long availableInPrefix = Integer.valueOf(prefix.length - prefixIndex).longValue(); + long skippableInPrefix = Math.min(n, availableInPrefix); + + prefixIndex += Long.valueOf(skippableInPrefix).intValue(); + long remainingToSkip = n - skippableInPrefix; + + if (remainingToSkip > 0) { + return skippableInPrefix + in.skip(remainingToSkip); + } + + return skippableInPrefix; + } + + @Override + public int available() throws IOException { + if (isPrefixConsumed()) { + return in.available(); + } + // total available is prefix remaining + stream available + return (prefix.length - prefixIndex) + in.available(); + } + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/GzipDecoderContentProcessor.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/GzipDecoderContentProcessor.java new file mode 100644 index 000000000..aa0e7eecf --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/GzipDecoderContentProcessor.java @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.processor; + +import static java.util.Objects.requireNonNullElse; + +import java.util.zip.GZIPInputStream; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.contentstore.util.ContentPipe; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class GzipDecoderContentProcessor implements ContentProcessor { + + private static final String GZIP_DECODE_PREFIX = "gzip.decode."; + + public static final String GZIP_DECODE_PARAM_BUFFER_SIZE = GZIP_DECODE_PREFIX + "buffer-size"; + + private final ContentPipe pipe; + private final FineractProperties properties; + + @Override + public ContentProcessorContext process(final ContentProcessorContext ctx) { + final Integer bufferSize = ctx.getParameter(GZIP_DECODE_PARAM_BUFFER_SIZE, + requireNonNullElse(properties.getContent().getDefaultBufferSize(), 8192)); + + final var pipedInputStream = pipe.pipe(ctx.getInputStream(), (in, out) -> { + pipe.write(new GZIPInputStream(in), out, new byte[bufferSize]); + }); + + return ctx.clone(pipedInputStream); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/GzipEncoderContentProcessor.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/GzipEncoderContentProcessor.java new file mode 100644 index 000000000..a3a0d7bb2 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/GzipEncoderContentProcessor.java @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.processor; + +import static java.util.Objects.requireNonNullElse; + +import java.util.zip.GZIPOutputStream; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.contentstore.util.ContentPipe; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class GzipEncoderContentProcessor implements ContentProcessor { + + private static final String GZIP_ENCODE_PREFIX = "gzip.encode."; + + public static final String GZIP_ENCODE_PARAM_BUFFER_SIZE = GZIP_ENCODE_PREFIX + "buffer-size"; + + private final ContentPipe pipe; + private final FineractProperties properties; + + @Override + public ContentProcessorContext process(final ContentProcessorContext ctx) { + final Integer bufferSize = ctx.getParameter(GZIP_ENCODE_PARAM_BUFFER_SIZE, + requireNonNullElse(properties.getContent().getDefaultBufferSize(), 8192)); + + final var pipedInputStream = pipe.pipe(ctx.getInputStream(), (in, out) -> { + pipe.write(in, new GZIPOutputStream(out), new byte[bufferSize]); + }); + + return ctx.clone(pipedInputStream); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/ImageResizeContentProcessor.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/ImageResizeContentProcessor.java new file mode 100644 index 000000000..13caf17fa --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/ImageResizeContentProcessor.java @@ -0,0 +1,110 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.processor; + +import static java.util.Objects.requireNonNull; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; +import java.util.regex.Pattern; +import javax.imageio.ImageIO; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.contentstore.exception.ContentProcessorException; +import org.apache.fineract.infrastructure.contentstore.util.ContentPipe; +import org.springframework.stereotype.Component; +import org.springframework.util.StreamUtils; + +@Slf4j +@RequiredArgsConstructor +@Component +public class ImageResizeContentProcessor implements ContentProcessor { + + private static final String IMAGE_RESIZE_PREFIX = "image.resize."; + + public static final String IMAGE_RESIZE_PARAM_MAX_WIDTH = IMAGE_RESIZE_PREFIX + "max-width"; + public static final String IMAGE_RESIZE_PARAM_MAX_HEIGHT = IMAGE_RESIZE_PREFIX + "max-height"; + public static final String IMAGE_RESIZE_PARAM_FORMAT = IMAGE_RESIZE_PREFIX + "format"; + + private final ContentPipe pipe; + + private static final Pattern VALID_IMAGE_FORMATS = Pattern.compile("^(gif|jpg|jpeg|png)$", Pattern.CASE_INSENSITIVE); + + @Override + public ContentProcessorContext process(final ContentProcessorContext ctx) { + final Integer maxWidth = ctx.getParameter(IMAGE_RESIZE_PARAM_MAX_WIDTH); + final Integer maxHeight = ctx.getParameter(IMAGE_RESIZE_PARAM_MAX_HEIGHT); + final String format = ctx.getParameter(IMAGE_RESIZE_PARAM_FORMAT, "jpg"); + + requireNonNull(maxWidth, "Missing max width parameter"); + requireNonNull(maxHeight, "Missing max height parameter"); + + if (!VALID_IMAGE_FORMATS.matcher(format).matches()) { + throw new ContentProcessorException(String.format("Wrong image format parameter: %s", format)); + } + + final var pipedInputStream = pipe.pipe(ctx.getInputStream(), (in, out) -> { + final var image = resize(in, maxWidth, maxHeight); + + // compresses the image into the specified format (e.g., "gif", "jpeg", "png") + ImageIO.write(image, format, out); + }); + + return ctx.clone(pipedInputStream); + } + + private BufferedImage resize(InputStream is, int targetWidth, int targetHeight) throws IOException { + final var imageIs = ImageIO.createImageInputStream(StreamUtils.nonClosing(is)); + + final var readers = ImageIO.getImageReaders(imageIs); + + if (!readers.hasNext()) { + throw new ContentProcessorException("No image reader found for format"); + } + + final var reader = readers.next(); + + try { + reader.setInput(imageIs, true, true); + + // get original dimensions to calculate subsampling ratio + int originalWidth = reader.getWidth(0); + int originalHeight = reader.getHeight(0); + + // calculate subsampling ratio + // subsampling is an integer ratio of source size to output size + int subsampleX = Math.max(1, originalWidth / targetWidth); + int subsampleY = Math.max(1, originalHeight / targetHeight); + int subsampling = Math.max(subsampleX, subsampleY); + + final var param = reader.getDefaultReadParam(); + param.setSourceSubsampling(subsampling, subsampling, 0, 0); + + // image will be close to the target size, but not exact, + // as subsampling only works with integer ratios. Further quality scaling + // can be done on the smaller BufferedImage if exact dimensions are needed. + + // read the image using the parameters + return reader.read(0, param); + } finally { + reader.dispose(); + } + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/SizeContentProcessor.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/SizeContentProcessor.java new file mode 100644 index 000000000..3c7b9575f --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/processor/SizeContentProcessor.java @@ -0,0 +1,80 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.processor; + +import java.io.FilterInputStream; +import java.io.IOException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class SizeContentProcessor implements ContentProcessor { + + private static final String SIZE_PREFIX = "size."; + + public static final String SIZE_RESULT_VALUE = SIZE_PREFIX + "result.value"; + + @Override + public ContentProcessorContext process(ContentProcessorContext ctx) { + return ctx.clone(new ByteCountingInputStream(ctx)); + } + + private static final class ByteCountingInputStream extends FilterInputStream { + + private final ContentProcessorContext ctx; + private long byteCount = 0; + + ByteCountingInputStream(ContentProcessorContext ctx) { + super(ctx.getInputStream()); + this.ctx = ctx; + } + + @Override + public int read() throws IOException { + int data = in.read(); + + if (data != -1) { + byteCount++; + } + + return data; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + int count = in.read(b, off, len); + + if (count != -1) { + byteCount += count; + } + + return count; + } + + @Override + public void close() throws IOException { + ctx.setResult(SIZE_RESULT_VALUE, byteCount); + + super.close(); + } + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/service/ContentStoreService.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/service/ContentStoreService.java new file mode 100644 index 000000000..2da1fce35 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/service/ContentStoreService.java @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.service; + +import java.io.InputStream; +import org.apache.fineract.infrastructure.contentstore.data.ContentStoreType; + +public interface ContentStoreService { + + String EXTENSION_REGEX = "^.+\\..+$"; + String DELIMITER = "/"; + + InputStream download(String path); + + String upload(String path, InputStream is, String mimeType); + + void delete(String path); + + ContentStoreType getType(); + + default String getDelimiter() { + return DELIMITER; + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/service/FileContentStoreService.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/service/FileContentStoreService.java new file mode 100644 index 000000000..1f293764b --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/service/FileContentStoreService.java @@ -0,0 +1,198 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.service; + +import static java.util.Objects.requireNonNull; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; +import java.util.stream.Stream; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.fineract.infrastructure.contentstore.data.ContentStoreType; +import org.apache.fineract.infrastructure.contentstore.detector.ContentDetectorContext; +import org.apache.fineract.infrastructure.contentstore.detector.ContentDetectorManager; +import org.apache.fineract.infrastructure.contentstore.exception.ContentPolicyException; +import org.apache.fineract.infrastructure.contentstore.exception.ContentStoreException; +import org.apache.fineract.infrastructure.contentstore.policy.ContentPolicyContext; +import org.apache.fineract.infrastructure.contentstore.policy.DefaultDeleteContentPolicy; +import org.apache.fineract.infrastructure.contentstore.policy.DefaultDownloadContentPolicy; +import org.apache.fineract.infrastructure.contentstore.policy.DefaultPostUploadContentPolicy; +import org.apache.fineract.infrastructure.contentstore.policy.DefaultPreUploadContentPolicy; +import org.apache.fineract.infrastructure.contentstore.util.ContentPathRandomizer; +import org.apache.fineract.infrastructure.contentstore.util.ContentPathSanitizer; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Service; + +@Slf4j +@RequiredArgsConstructor +@Service +@ConditionalOnProperty(name = "fineract.content.filesystem.enabled", havingValue = "true") +public class FileContentStoreService implements ContentStoreService { + + private final ContentPathSanitizer pathSanitizer; + private final ContentPathRandomizer pathRandomizer; + private final DefaultDownloadContentPolicy downloadContentPolicy; + private final DefaultPreUploadContentPolicy preUploadContentPolicy; + private final DefaultPostUploadContentPolicy postUploadContentPolicy; + private final DefaultDeleteContentPolicy deleteContentPolicy; + private final ContentDetectorManager contentDetectorManager; + private final FineractProperties properties; + + @Override + public InputStream download(String path) { + downloadContentPolicy.check(ContentPolicyContext.builder().path(path).build()); + + final var safePath = pathSanitizer.sanitize(path); + + try { + final var target = getPath(safePath, false); + + return Files.newInputStream(target); + } catch (IOException e) { + throw new ContentStoreException(e); + } + } + + @Override + public String upload(String path, InputStream is, String mimeType) { + requireNonNull(path, "Path missing"); + requireNonNull(is, "Data missing"); + + if (StringUtils.isEmpty(mimeType)) { + mimeType = Optional.ofNullable(contentDetectorManager.detect(ContentDetectorContext.builder().fileName(path).build())) + .map(ContentDetectorContext::getMimeType).orElse(APPLICATION_OCTET_STREAM_VALUE); + } + + preUploadContentPolicy.check(ContentPolicyContext.builder().path(path).mimeType(mimeType).build()); + + var safePath = pathSanitizer.sanitize(path); + + final var target = Files.exists(getPath(safePath, false)) ? getPath(safePath, false) : getPath(safePath, true); + + try (var in = is) { + IOUtils.copy(in, new FileOutputStream(target.toString())); + } catch (Exception e) { + throw new ContentStoreException(e); + } + + final var relativePath = getRelativePath(target); + + try { + postUploadContentPolicy + .check(ContentPolicyContext.builder().path(path).inputStream(getInputStream(target)).mimeType(mimeType).build()); + } catch (ContentPolicyException e) { + log.warn("Delete file because it didn't comply with the post-upload policy check: {} - {}", target, e.getMessage()); + + delete(relativePath.toString()); + + throw e; + } + + return relativePath.toString(); + } + + @Override + public void delete(String path) { + deleteContentPolicy.check(ContentPolicyContext.builder().path(path).build()); + + final var safePath = pathSanitizer.sanitize(path); + + try { + final var target = getPath(safePath, false); + + final boolean deleted = Files.deleteIfExists(target); + + if (!hasFiles(target.getParent())) { + Files.deleteIfExists(target.getParent()); + } + + if (!deleted) { + // no need to throw an Error, what's a caller going to do about it, so simply log a warning + log.warn("Unable to delete file {}", safePath); + } + } catch (Exception e) { + throw new ContentStoreException(e); + } + } + + @Override + public ContentStoreType getType() { + return ContentStoreType.FILE_SYSTEM; + } + + private Path getPath(String path, boolean randomize) { + Path p; + + if (randomize) { + var tail = Path.of(path); + var file = tail.getFileName(); + + p = getRootPath().resolve(tail.getParent()).resolve(pathRandomizer.randomize()).resolve(file); + + try { + if (Files.notExists(p.getParent())) { + Files.createDirectories(p.getParent()); + } + } catch (Exception e) { + throw new ContentStoreException(e); + } + } else { + p = getRootPath().resolve(path); + } + + return p; + } + + private Path getRelativePath(Path fullPath) { + return getRootPath().relativize(fullPath); + } + + private Path getRootPath() { + return Path.of(properties.getContent().getFilesystem().getRootFolder(), + ThreadLocalContextUtil.getTenant().getName().replaceAll(" ", "").trim()); + } + + private InputStream getInputStream(Path path) { + try { + return Files.newInputStream(path); + } catch (IOException ioe) { + throw new ContentStoreException(ioe); + } + } + + boolean hasFiles(Path folder) throws IOException { + if (Files.exists(folder) && Files.isDirectory(folder)) { + try (Stream entries = Files.list(folder)) { + return entries.anyMatch(Files::isRegularFile); + } + } + + return false; + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/service/S3ContentStoreService.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/service/S3ContentStoreService.java new file mode 100644 index 000000000..8800f35fc --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/service/S3ContentStoreService.java @@ -0,0 +1,126 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.service; + +import static java.util.Objects.requireNonNull; + +import java.io.InputStream; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.contentstore.data.ContentStoreType; +import org.apache.fineract.infrastructure.contentstore.detector.ContentDetectorManager; +import org.apache.fineract.infrastructure.contentstore.exception.ContentPolicyException; +import org.apache.fineract.infrastructure.contentstore.exception.ContentStoreException; +import org.apache.fineract.infrastructure.contentstore.policy.ContentPolicyContext; +import org.apache.fineract.infrastructure.contentstore.policy.DefaultDeleteContentPolicy; +import org.apache.fineract.infrastructure.contentstore.policy.DefaultDownloadContentPolicy; +import org.apache.fineract.infrastructure.contentstore.policy.DefaultPostUploadContentPolicy; +import org.apache.fineract.infrastructure.contentstore.policy.DefaultPreUploadContentPolicy; +import org.apache.fineract.infrastructure.contentstore.util.ContentPathSanitizer; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Service; +import software.amazon.awssdk.core.sync.RequestBody; +import software.amazon.awssdk.core.sync.ResponseTransformer; +import software.amazon.awssdk.http.ContentStreamProvider; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.model.GetObjectRequest; + +@Slf4j +@RequiredArgsConstructor +@Service +@ConditionalOnProperty(name = "fineract.content.s3.enabled", havingValue = "true") +public class S3ContentStoreService implements ContentStoreService { + + private final S3Client s3Client; + private final ContentPathSanitizer pathSanitizer; + private final DefaultDownloadContentPolicy downloadContentPolicy; + private final DefaultPreUploadContentPolicy preUploadContentPolicy; + private final DefaultPostUploadContentPolicy postUploadContentPolicy; + private final DefaultDeleteContentPolicy deleteContentPolicy; + private final ContentDetectorManager contentDetectorManager; + private final FineractProperties properties; + + @Override + public InputStream download(String path) { + downloadContentPolicy.check(ContentPolicyContext.builder().path(path).build()); + + final var safePath = pathSanitizer.sanitize(path); + + try { + return s3Client + .getObject(GetObjectRequest.builder().bucket(properties.getContent().getS3().getBucketName()).key(safePath).build(), + ResponseTransformer.toBytes()) + .asInputStream(); + } catch (Exception e) { + throw new ContentStoreException(e); + } + } + + @Override + public String upload(String path, InputStream is, String mimeType) { + requireNonNull(path, "Path missing"); + requireNonNull(is, "Data missing"); + + preUploadContentPolicy.check(ContentPolicyContext.builder().path(path).mimeType(mimeType).build()); + + var safePath = pathSanitizer.sanitize(path); + + try { + final var p = safePath; + + s3Client.putObject(builder -> builder.bucket(properties.getContent().getS3().getBucketName()).key(p), + RequestBody.fromContentProvider(ContentStreamProvider.fromInputStream(is), mimeType)); + } catch (Exception e) { + throw new ContentStoreException(e); + } + + try { + // TODO: verify if this is working; maybe there is a better way (e.g. temporary storage on file system) + postUploadContentPolicy + .check(ContentPolicyContext.builder().path(path).inputStream(download(safePath)).mimeType(mimeType).build()); + } catch (ContentPolicyException e) { + log.warn("Delete file because it didn't comply with the post-upload policy check: {} - {}", safePath, e.getMessage()); + + delete(safePath); + + throw e; + } + + return safePath; + } + + @Override + public void delete(String path) { + deleteContentPolicy.check(ContentPolicyContext.builder().path(path).build()); + + final var safePath = pathSanitizer.sanitize(path); + + try { + s3Client.deleteObject(builder -> builder.bucket(properties.getContent().getS3().getBucketName()).key(safePath)); + } catch (Exception e) { + throw new ContentStoreException(e); + } + } + + @Override + public ContentStoreType getType() { + return ContentStoreType.S3; + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/ContentPathRandomizer.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/ContentPathRandomizer.java new file mode 100644 index 000000000..6ac73bd70 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/ContentPathRandomizer.java @@ -0,0 +1,24 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.util; + +public interface ContentPathRandomizer { + + String randomize(); +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentPathSanitizer.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/ContentPathSanitizer.java similarity index 83% rename from fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentPathSanitizer.java rename to fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/ContentPathSanitizer.java index 415532fcd..ef07ee769 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentPathSanitizer.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/ContentPathSanitizer.java @@ -16,13 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.fineract.infrastructure.documentmanagement.contentrepository; - -import java.io.BufferedInputStream; +package org.apache.fineract.infrastructure.contentstore.util; public interface ContentPathSanitizer { String sanitize(String path); - - String sanitize(String path, BufferedInputStream is); } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/ContentPipe.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/ContentPipe.java new file mode 100644 index 000000000..131c50e40 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/ContentPipe.java @@ -0,0 +1,169 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.util; + +import static java.util.Objects.requireNonNullElse; +import static org.apache.fineract.infrastructure.contentstore.processor.ContentProcessor.BEAN_NAME_EXECUTOR; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.contentstore.exception.ContentProcessorException; +import org.apache.fineract.infrastructure.contentstore.processor.ContentProcessor; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public final class ContentPipe { + + private final ExecutorService executor; + private final FineractProperties properties; + + public ContentPipe(@Qualifier(BEAN_NAME_EXECUTOR) ExecutorService executor, FineractProperties properties) { + this.executor = executor; + this.properties = properties; + } + + public InputStream pipe(ContentProcessor.OutputStreamConsumer consumer) { + var pis = new PipedInputStream(requireNonNullElse(properties.getContent().getDefaultBufferSize(), 8192)); + var pos = newPipedOutputStream(pis); + + var future = executor.submit(() -> { + try (var os = pos) { + consumer.accept(os); + } catch (Throwable e) { + // if an error occurs, the pipe will close + throw new ContentProcessorException(new IOException(e)); + } + }); + + return new FutureInputStream(pis, future); + } + + public InputStream pipe(InputStream inputStream, ContentProcessor.InputOutputStreamConsumer consumer) { + // Java default buffer is 1024 bytes + var pis = new PipedInputStream(requireNonNullElse(properties.getContent().getDefaultBufferSize(), 8192)); + var pos = newPipedOutputStream(pis); + + // submit the work to the executor + var future = executor.submit(() -> { + try (var os = pos; var is = inputStream) { + // run the user logic (e.g., zipping, resizing) + consumer.accept(is, os); + // flushing is handled by try-with-resources close() + } catch (Throwable e) { + // if an error occurs, the pipe will close + throw new ContentProcessorException(new IOException(e)); + } + }); + + // tracks errors + return new FutureInputStream(pis, future); + } + + public void write(InputStream is, OutputStream os, byte[] buffer) throws IOException { + int bytesRead; + + while ((bytesRead = is.read(buffer)) != -1) { + os.write(buffer, 0, bytesRead); + } + } + + private PipedOutputStream newPipedOutputStream(PipedInputStream pis) { + try { + return new PipedOutputStream(pis); + } catch (IOException e) { + throw new ContentProcessorException(e); + } + } + + private static class FutureInputStream extends InputStream { + + private final PipedInputStream delegate; + private final Future future; + + FutureInputStream(PipedInputStream delegate, Future future) { + this.delegate = delegate; + this.future = future; + } + + @SuppressWarnings("AvoidHidingCauseException") + private void checkException() throws IOException { + // if the task is done, check for exceptions + if (future.isDone()) { + try { + // throws "ExecutionException" if task failed + future.get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + + throw new IOException("Processing interrupted", e); + } catch (ExecutionException e) { + // unwrap cause + Throwable cause = e.getCause(); + + if (cause instanceof IOException ioe) { + throw ioe; + } + + throw new IOException("Processing failed in worker thread", cause); + } + } + } + + @Override + public int read() throws IOException { + checkException(); + + int data = delegate.read(); + + // check EOF because of error + checkException(); + + return data; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + checkException(); + + int count = delegate.read(b, off, len); + + checkException(); + + return count; + } + + @Override + public void close() throws IOException { + delegate.close(); + + // good practice + future.cancel(true); + } + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/DefaultContentPathRandomizer.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/DefaultContentPathRandomizer.java new file mode 100644 index 000000000..90da0da83 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/DefaultContentPathRandomizer.java @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.util; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class DefaultContentPathRandomizer implements ContentPathRandomizer { + + private final FineractProperties properties; + + @Override + public String randomize() { + // TODO: make length configurable + return RandomStringUtils.secureStrong().randomAlphabetic(16); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/DefaultContentPathSanitizer.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/DefaultContentPathSanitizer.java new file mode 100644 index 000000000..2827480d6 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/contentstore/util/DefaultContentPathSanitizer.java @@ -0,0 +1,47 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.util; + +import java.nio.file.Path; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class DefaultContentPathSanitizer implements ContentPathSanitizer { + + private final FineractProperties properties; + + @Override + public String sanitize(String path) { + final var sanitizedPath = Path.of(path).normalize().toString(); + + if (log.isDebugEnabled()) { + final var fileName = FilenameUtils.getName(sanitizedPath).toLowerCase(); + + log.debug("Path: {} -> {} ({})", path, sanitizedPath, fileName); + } + + return sanitizedPath; + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ContentResources.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ContentResources.java deleted file mode 100644 index 905d2a614..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ContentResources.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.api; - -import com.google.common.io.ByteSource; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.core.Response.ResponseBuilder; -import java.io.IOException; -import java.io.InputStream; -import org.apache.fineract.infrastructure.documentmanagement.data.FileData; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Utilities common to file upload/download resources. - * - * @author Michael Vorburger.ch - */ -final class ContentResources { - - private static final Logger LOG = LoggerFactory.getLogger(ContentResources.class); - - private ContentResources() {} - - static Response fileDataToResponse(FileData fileData, String fileName, String dispositionType) { - ResponseBuilder response; - try { - ByteSource byteSource = fileData.getByteSource(); - // TODO Where is this InputStream closed?! It needs to be AFTER it's read by JAX-RS.. how to do that? - InputStream is = byteSource.openBufferedStream(); - response = Response.ok(is); - response.header("Content-Disposition", dispositionType + "; filename=\"" + fileName + "\""); - response.header("Content-Length", byteSource.sizeIfKnown().or(-1L)); - response.header("Content-Type", fileData.contentType()); - } catch (IOException e) { - LOG.error("resizedImage.getByteSource().openBufferedStream() failed", e); - response = Response.serverError(); - } - return response.build(); - } - - static Response fileDataToResponse(FileData fileData, String dispositionType) { - return fileDataToResponse(fileData, fileData.name(), dispositionType); - } -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentApiConstants.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentApiConstants.java new file mode 100644 index 000000000..59fe93273 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentApiConstants.java @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.api; + +public final class DocumentApiConstants { + + private DocumentApiConstants() {} + + public static final String DOCUMENT_API_PARAM_ENTITY_TYPE = "entityType"; + public static final String DOCUMENT_API_PARAM_ENTITY_ID = "entityId"; + public static final String DOCUMENT_API_PARAM_DOCUMENT_ID = "documentId"; + public static final String DOCUMENT_API_PARAM_FILE = "file"; + public static final String DOCUMENT_API_PARAM_NAME = "name"; + public static final String DOCUMENT_API_PARAM_DESCRIPTION = "description"; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentApiResource.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentApiResource.java new file mode 100644 index 000000000..1922b2bb0 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentApiResource.java @@ -0,0 +1,253 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.api; + +import static org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiConstants.DOCUMENT_API_PARAM_DESCRIPTION; +import static org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiConstants.DOCUMENT_API_PARAM_DOCUMENT_ID; +import static org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiConstants.DOCUMENT_API_PARAM_ENTITY_ID; +import static org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiConstants.DOCUMENT_API_PARAM_ENTITY_TYPE; +import static org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiConstants.DOCUMENT_API_PARAM_FILE; +import static org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiConstants.DOCUMENT_API_PARAM_NAME; +import static org.apache.fineract.util.StreamResponseUtil.DISPOSITION_TYPE_ATTACHMENT; +import static org.springframework.http.HttpHeaders.CONTENT_LENGTH; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.HeaderParam; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import java.io.InputStream; +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.command.core.CommandPipeline; +import org.apache.fineract.infrastructure.contentstore.detector.ContentDetectorContext; +import org.apache.fineract.infrastructure.contentstore.detector.ContentDetectorManager; +import org.apache.fineract.infrastructure.documentmanagement.command.DocumentCreateCommand; +import org.apache.fineract.infrastructure.documentmanagement.command.DocumentDeleteCommand; +import org.apache.fineract.infrastructure.documentmanagement.command.DocumentUpdateCommand; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentCreateRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentCreateResponse; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentDeleteRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentDeleteResponse; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentUpdateRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentUpdateResponse; +import org.apache.fineract.infrastructure.documentmanagement.service.DocumentReadPlatformService; +import org.apache.fineract.util.StreamResponseUtil; +import org.glassfish.jersey.media.multipart.FormDataBodyPart; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@Path("/v1/{entityType}/{entityId}/documents") +@Tag(name = "Documents", description = """ + Multiple Documents (a combination of a name, description and a file) may be attached to different entities like clients, groups, staff, loans, savings and client identifiers in the system + + Note: the currently allowed entities are + + - clients: URL pattern as clients + - staff: URL pattern as staff + - loans: URL pattern as loans + - savings: URL pattern as savings + - client identifiers: URL pattern as client_identifiers + - groups: URL pattern as groups + """) +@RequiredArgsConstructor +public class DocumentApiResource { + + private final DocumentReadPlatformService documentReadPlatformService; + private final FileUploadValidator fileUploadValidator; + private final ContentDetectorManager contentDetectorManager; + private final CommandPipeline commandPipeline; + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + @Operation(summary = "List documents", description = """ + Example Requests: + + - clients/1/documents + - client_identifiers/1/documents + - loans/1/documents?fields=name,description + """) + public List retrieveAllDocuments(@PathParam(DOCUMENT_API_PARAM_ENTITY_TYPE) final String entityType, + @PathParam(DOCUMENT_API_PARAM_ENTITY_ID) final Long entityId) { + + return documentReadPlatformService.retrieveAllDocuments(entityType, entityId); + } + + @GET + @Path("{documentId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + @Operation(summary = "Retrieve a Document", description = """ + Example Requests: + + - clients/1/documents/1 + - loans/1/documents/1 + - client_identifiers/1/documents/1?fields=name,description + """) + public DocumentData getDocument(@PathParam(DOCUMENT_API_PARAM_ENTITY_TYPE) final String entityType, + @PathParam(DOCUMENT_API_PARAM_ENTITY_ID) final Long entityId, + @PathParam(DOCUMENT_API_PARAM_DOCUMENT_ID) final Long documentId) { + + return documentReadPlatformService.retrieveDocument(entityType, entityId, documentId); + } + + @GET + @Path("{documentId}/attachment") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_OCTET_STREAM }) + @Operation(summary = "Retrieve Binary File associated with Document", description = """ + Request used to download the file associated with the document + + Example Requests: + + - clients/1/documents/1/attachment + - loans/1/documents/1/inline + """) + @ApiResponse(responseCode = "200", description = "Not Shown: The corresponding Binary file") + public Response downloadFile(@PathParam(DOCUMENT_API_PARAM_ENTITY_TYPE) final String entityType, + @PathParam(DOCUMENT_API_PARAM_ENTITY_ID) final Long entityId, + @PathParam(DOCUMENT_API_PARAM_DOCUMENT_ID) final Long documentId) { + + final var content = documentReadPlatformService.retrieveDocumentContent(entityType, entityId, documentId); + + return StreamResponseUtil + .ok(StreamResponseUtil.StreamResponseData.builder().type(content.getContentType()).fileName(content.getFileName()) + .dispositionType(DISPOSITION_TYPE_ATTACHMENT).stream(content.getStream()).size(content.getSize()).build()); + } + + @POST + @Consumes({ MediaType.MULTIPART_FORM_DATA }) + @Produces({ MediaType.APPLICATION_JSON }) + @Operation(summary = "Create a Document", description = """ + Note: A document is created using a Multi-part form upload + + Body parts + + - name : name or summary of the document + - description : description of the document + - file : the file to be uploaded + + Mandatory fields : + + - file + - description + """) + @ApiResponse(responseCode = "200", description = "Not Shown (multi-part form data)") + public DocumentCreateResponse createDocument(@PathParam(DOCUMENT_API_PARAM_ENTITY_TYPE) final String entityType, + @PathParam(DOCUMENT_API_PARAM_ENTITY_ID) final Long entityId, @HeaderParam(CONTENT_LENGTH) final Long fileSize, + @FormDataParam(DOCUMENT_API_PARAM_FILE) final InputStream is, + @FormDataParam(DOCUMENT_API_PARAM_FILE) final FormDataContentDisposition fileDetails, + @FormDataParam(DOCUMENT_API_PARAM_FILE) final FormDataBodyPart filePart, + @FormDataParam(DOCUMENT_API_PARAM_NAME) final String name, + @FormDataParam(DOCUMENT_API_PARAM_DESCRIPTION) final String description) { + + fileUploadValidator.validate(fileSize, is, fileDetails, filePart); + + final var command = new DocumentCreateCommand(); + + var type = Optional.ofNullable(filePart.getMediaType()).map(MediaType::toString) + .or(() -> Optional.of(contentDetectorManager + .detect(ContentDetectorContext.builder().fileName(fileDetails.getFileName()).build()).getMimeType())) + .orElse(APPLICATION_OCTET_STREAM_VALUE); + + command.setPayload(DocumentCreateRequest.builder().entityId(entityId).entityType(entityType).name(name).description(description) + .fileName(fileDetails.getFileName()).size(fileSize).type(type).stream(is).build()); + + final Supplier response = commandPipeline.send(command); + + return response.get(); + } + + @PUT + @Path("{documentId}") + @Consumes({ MediaType.MULTIPART_FORM_DATA }) + @Produces({ MediaType.APPLICATION_JSON }) + // @RequestBody(description = "Update document", content = { @Content(mediaType = MediaType.MULTIPART_FORM_DATA) }) + @Operation(summary = "Update a Document", description = """ + Note: A document is updated using a Multi-part form upload + + Body Parts + + - name: name or summary of the document + - description: description of the document + - file: the file to be uploaded + """) + @ApiResponse(responseCode = "200", description = "Not Shown (multi-part form data)") + public DocumentUpdateResponse updateDocument(@PathParam(DOCUMENT_API_PARAM_ENTITY_TYPE) final String entityType, + @PathParam(DOCUMENT_API_PARAM_ENTITY_ID) final Long entityId, @PathParam(DOCUMENT_API_PARAM_DOCUMENT_ID) final Long documentId, + @HeaderParam(CONTENT_LENGTH) final Long fileSize, @FormDataParam(DOCUMENT_API_PARAM_FILE) final InputStream is, + @FormDataParam(DOCUMENT_API_PARAM_FILE) final FormDataContentDisposition fileDetails, + @FormDataParam(DOCUMENT_API_PARAM_FILE) final FormDataBodyPart filePart, + @FormDataParam(DOCUMENT_API_PARAM_NAME) final String name, + @FormDataParam(DOCUMENT_API_PARAM_DESCRIPTION) final String description) { + + final var command = new DocumentUpdateCommand(); + + final var request = DocumentUpdateRequest.builder().id(documentId).entityId(entityId).entityType(entityType).name(name) + .description(description).stream(is); + + if (fileDetails != null) { + request.fileName(fileDetails.getFileName()).type(fileDetails.getType()).size(fileSize); + } + + command.setPayload(DocumentUpdateRequest.builder().id(documentId).entityId(entityId).entityType(entityType).name(name) + .description(description).stream(is).build()); + + final Supplier response = commandPipeline.send(command); + + // TODO: does not return list of changes, should be done for consistency with rest of API + return response.get(); + } + + @DELETE + @Path("{documentId}") + @Operation(summary = "Remove a Document", description = """ + """) + @ApiResponse(responseCode = "200", description = "OK") + public DocumentDeleteResponse deleteDocument(@PathParam(DOCUMENT_API_PARAM_ENTITY_TYPE) final String entityType, + @PathParam(DOCUMENT_API_PARAM_ENTITY_ID) final Long entityId, + @PathParam(DOCUMENT_API_PARAM_DOCUMENT_ID) final Long documentId) { + + final var command = new DocumentDeleteCommand(); + + command.setPayload(DocumentDeleteRequest.builder().id(documentId).entityId(entityId).entityType(entityType).build()); + + final Supplier response = commandPipeline.send(command); + + return response.get(); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentManagementApiResource.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentManagementApiResource.java deleted file mode 100644 index c44d4fcaa..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentManagementApiResource.java +++ /dev/null @@ -1,249 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.api; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.parameters.RequestBody; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.HeaderParam; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.PUT; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import java.io.InputStream; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import lombok.RequiredArgsConstructor; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; -import org.apache.fineract.infrastructure.documentmanagement.command.DocumentCommand; -import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData; -import org.apache.fineract.infrastructure.documentmanagement.data.FileData; -import org.apache.fineract.infrastructure.documentmanagement.service.DocumentReadPlatformService; -import org.apache.fineract.infrastructure.documentmanagement.service.DocumentWritePlatformService; -import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; -import org.glassfish.jersey.media.multipart.FormDataBodyPart; -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; -import org.glassfish.jersey.media.multipart.FormDataParam; -import org.springframework.stereotype.Component; - -@Component -@Path("/v1/{entityType}/{entityId}/documents") -@Tag(name = "Documents", description = """ - Multiple Documents (a combination of a name, description and a file) may be attached to different Entities like Clients, Groups, Staff, Loans, Savings and Client Identifiers in the system - - Note: The currently allowed Entities are - - Clients: URL Pattern as clients - Staff: URL Pattern as staff - Loans: URL Pattern as loans - Savings: URL Pattern as savings - Client Identifiers: URL Pattern as client_identifiers - Groups: URL Pattern as groups""") -@RequiredArgsConstructor -public class DocumentManagementApiResource { - - private static final String SYSTEM_ENTITY_TYPE = "DOCUMENT"; - - private final PlatformSecurityContext context; - private final DocumentReadPlatformService documentReadPlatformService; - private final DocumentWritePlatformService documentWritePlatformService; - private final FileUploadValidator fileUploadValidator; - - @GET - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - @Operation(summary = "List documents", description = """ - Example Requests: - - clients/1/documents - - client_identifiers/1/documents - - loans/1/documents?fields=name,description""") - public List retrieveAllDocuments(@PathParam("entityType") @Parameter(description = "entityType") final String entityType, - @PathParam("entityId") @Parameter(description = "entityId") final Long entityId) { - - context.authenticatedUser().validateHasReadPermission(SYSTEM_ENTITY_TYPE); - return documentReadPlatformService.retrieveAllDocuments(entityType, entityId); - } - - @POST - @Consumes({ MediaType.MULTIPART_FORM_DATA }) - @Produces({ MediaType.APPLICATION_JSON }) - @RequestBody(description = "Create document", content = { - @Content(mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(implementation = DocumentManagementApiResourceSwagger.DocumentUploadRequest.class)) }) - @Operation(summary = "Create a Document", description = """ - Note: A document is created using a Multi-part form upload\s - - Body Parts - - name :\s - Name or summary of the document - - description :\s - Description of the document - - file :\s - The file to be uploaded - - Mandatory Fields :\s - file and description""") - - @ApiResponse(responseCode = "200", description = "Not Shown (multi-part form data)", content = @Content(schema = @Schema(implementation = DocumentManagementApiResourceSwagger.PostEntityTypeEntityIdDocumentsResponse.class))) - public CommandProcessingResult createDocument(@PathParam("entityType") @Parameter(description = "entityType") final String entityType, - @PathParam("entityId") @Parameter(description = "entityId") final Long entityId, - @HeaderParam("Content-Length") @Parameter(description = "Content-Length") final Long fileSize, - @FormDataParam("file") final InputStream inputStream, @FormDataParam("file") final FormDataContentDisposition fileDetails, - @FormDataParam("file") final FormDataBodyPart bodyPart, @FormDataParam("name") final String name, - @FormDataParam("description") final String description) { - - // TODO: stop reading from stream after max size is reached to protect against malicious clients - // TODO: need to extract the actual file type and determine if they are permissible - - fileUploadValidator.validate(fileSize, inputStream, fileDetails, bodyPart); - final DocumentCommand documentCommand = new DocumentCommand(null, null, entityType, entityId, name, fileDetails.getFileName(), - fileSize, bodyPart.getMediaType().toString(), description, null); - final Long documentId = documentWritePlatformService.createDocument(documentCommand, inputStream); - return CommandProcessingResult.resourceResult(documentId); - } - - @PUT - @Path("{documentId}") - @Consumes({ MediaType.MULTIPART_FORM_DATA }) - @Produces({ MediaType.APPLICATION_JSON }) - @RequestBody(description = "Update document", content = { - @Content(mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(implementation = DocumentManagementApiResourceSwagger.DocumentUploadRequest.class)) }) - @Operation(summary = "Update a Document", description = """ - Note: A document is updated using a Multi-part form upload\s - Body Parts - name - Name or summary of the document - description - Description of the document - file - The file to be uploaded""") - - @ApiResponse(responseCode = "200", description = "Not Shown (multi-part form data)", content = @Content(schema = @Schema(implementation = DocumentManagementApiResourceSwagger.PutEntityTypeEntityIdDocumentsResponse.class))) - public CommandProcessingResult updateDocument(@PathParam("entityType") @Parameter(description = "entityType") final String entityType, - @PathParam("entityId") @Parameter(description = "entityId") final Long entityId, - @PathParam("documentId") @Parameter(description = "documentId") final Long documentId, - @HeaderParam("Content-Length") @Parameter(description = "Content-Length") final Long fileSize, - @FormDataParam("file") final InputStream inputStream, @FormDataParam("file") final FormDataContentDisposition fileDetails, - @FormDataParam("file") final FormDataBodyPart bodyPart, @FormDataParam("name") final String name, - @FormDataParam("description") final String description) { - - final Set modifiedParams = new HashSet<>(); - modifiedParams.add("name"); - modifiedParams.add("description"); - - /*** - * Populate Document command based on whether a file has also been passed in as a part of the update - ***/ - DocumentCommand documentCommand; - if (inputStream != null && fileDetails.getFileName() != null) { - fileUploadValidator.validate(fileSize, inputStream, fileDetails, bodyPart); - modifiedParams.add("fileName"); - modifiedParams.add("size"); - modifiedParams.add("type"); - modifiedParams.add("location"); - documentCommand = new DocumentCommand(modifiedParams, documentId, entityType, entityId, name, fileDetails.getFileName(), - fileSize, bodyPart.getMediaType().toString(), description, null); - } else { - documentCommand = new DocumentCommand(modifiedParams, documentId, entityType, entityId, name, null, null, null, description, - null); - } - /*** - * TODO: does not return list of changes, should be done for consistency with rest of API - **/ - return documentWritePlatformService.updateDocument(documentCommand, inputStream); - } - - @GET - @Path("{documentId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - @Operation(summary = "Retrieve a Document", description = """ - Example Requests: - - clients/1/documents/1 - - - loans/1/documents/1 - - - client_identifiers/1/documents/1?fields=name,description""") - public DocumentData getDocument(@PathParam("entityType") @Parameter(description = "entityType") final String entityType, - @PathParam("entityId") @Parameter(description = "entityId") final Long entityId, - @PathParam("documentId") @Parameter(description = "documentId") final Long documentId) { - - context.authenticatedUser().validateHasReadPermission(SYSTEM_ENTITY_TYPE); - return documentReadPlatformService.retrieveDocument(entityType, entityId, documentId); - } - - @GET - @Path("{documentId}/attachment") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_OCTET_STREAM }) - @Operation(summary = "Retrieve Binary File associated with Document", description = """ - Request used to download the file associated with the document - - Example Requests: - - clients/1/documents/1/attachment - - - loans/1/documents/1/attachment""") - @ApiResponse(responseCode = "200", description = "Not Shown: The corresponding Binary file") - public Response downloadFile(@PathParam("entityType") @Parameter(description = "entityType") final String entityType, - @PathParam("entityId") @Parameter(description = "entityId") final Long entityId, - @PathParam("documentId") @Parameter(description = "documentId") final Long documentId) { - - context.authenticatedUser().validateHasReadPermission(SYSTEM_ENTITY_TYPE); - final FileData fileData = documentReadPlatformService.retrieveFileData(entityType, entityId, documentId); - return ContentResources.fileDataToResponse(fileData, "attachment"); - } - - @DELETE - @Path("{documentId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - @Operation(summary = "Remove a Document", description = "") - - @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = DocumentManagementApiResourceSwagger.DeleteEntityTypeEntityIdDocumentsResponse.class))) - public CommandProcessingResult deleteDocument(@PathParam("entityType") @Parameter(description = "entityType") final String entityType, - @PathParam("entityId") @Parameter(description = "entityId") final Long entityId, - @PathParam("documentId") @Parameter(description = "documentId") final Long documentId) { - - final DocumentCommand documentCommand = new DocumentCommand(null, documentId, entityType, entityId, null, null, null, null, null, - null); - - return documentWritePlatformService.deleteDocument(documentCommand); - } -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentManagementApiResourceSwagger.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentManagementApiResourceSwagger.java deleted file mode 100644 index 91ad2f2c9..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/DocumentManagementApiResourceSwagger.java +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.api; - -import io.swagger.v3.oas.annotations.media.Schema; -import org.apache.fineract.infrastructure.core.data.UploadRequest; -import org.glassfish.jersey.media.multipart.FormDataParam; - -/** - * Created by sanyam on 7/8/17. - */ - -final class DocumentManagementApiResourceSwagger { - - private DocumentManagementApiResourceSwagger() { - - } - - @Schema(description = "PostEntityTypeEntityIdDocumentsResponse") - public static final class PostEntityTypeEntityIdDocumentsResponse { - - private PostEntityTypeEntityIdDocumentsResponse() { - - } - - @Schema(example = "3") - public Long resourceId; - @Schema(example = "3") - public String resourceIdentifier; - } - - @Schema(description = "PutEntityTypeEntityIdDocumentsResponse") - public static final class PutEntityTypeEntityIdDocumentsResponse { - - private PutEntityTypeEntityIdDocumentsResponse() { - - } - - public static final class PutEntityTypeEntityIdDocumentsResponseChangesSwagger { - - private PutEntityTypeEntityIdDocumentsResponseChangesSwagger() { - - } - - } - - @Schema(example = "3") - public Long resourceId; - public PutEntityTypeEntityIdDocumentsResponse.PutEntityTypeEntityIdDocumentsResponseChangesSwagger changes; - @Schema(example = "3") - public String resourceIdentifier; - } - - @Schema(description = "DeleteEntityTypeEntityIdDocumentsResponse") - public static final class DeleteEntityTypeEntityIdDocumentsResponse { - - private DeleteEntityTypeEntityIdDocumentsResponse() { - - } - - @Schema(example = "3") - public Long resourceId; - @Schema(example = "3") - public String resourceIdentifier; - } - - @Schema(description = "Document upload request") - public static final class DocumentUploadRequest extends UploadRequest { - - @Schema(name = "name", type = "string", accessMode = Schema.AccessMode.READ_WRITE) - @FormDataParam("name") - private String name; - - @Schema(name = "description", type = "string", accessMode = Schema.AccessMode.READ_WRITE) - @FormDataParam("description") - private String description; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - } - -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImageApiConstants.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImageApiConstants.java new file mode 100644 index 000000000..54c8d473e --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImageApiConstants.java @@ -0,0 +1,33 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.api; + +public final class ImageApiConstants { + + private ImageApiConstants() {} + + public static final String IMAGE_API_PARAM_MAX_WIDTH = "maxWidth"; + public static final String IMAGE_API_PARAM_MAX_HEIGHT = "maxHeight"; + public static final String IMAGE_API_PARAM_OUTPUT = "output"; + public static final String IMAGE_API_VALUE_OUTPUT_INLINE_OCTET = "inline_octet"; + public static final String IMAGE_API_VALUE_IMAGE_TYPE_JPG = "jpg"; + public static final String IMAGE_API_VALUE_ENCODING_BASE64 = "base64"; + // public static final String IMAGE_API_VALUE_IMAGE_TYPE_GIF = "gif"; + // public static final String IMAGE_API_VALUE_IMAGE_TYPE_PNG = "png"; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImagesApiResource.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImagesApiResource.java index 2c3f257c2..b29b99346 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImagesApiResource.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImagesApiResource.java @@ -18,9 +18,30 @@ */ package org.apache.fineract.infrastructure.documentmanagement.api; +import static java.util.Objects.requireNonNull; +import static org.apache.fineract.infrastructure.contentstore.processor.DataUrlEncoderContentProcessor.DATA_URL_ENCODE_PARAM_CONTENT_TYPE; +import static org.apache.fineract.infrastructure.contentstore.processor.DataUrlEncoderContentProcessor.DATA_URL_ENCODE_PARAM_ENCODING; +import static org.apache.fineract.infrastructure.contentstore.processor.ImageResizeContentProcessor.IMAGE_RESIZE_PARAM_FORMAT; +import static org.apache.fineract.infrastructure.contentstore.processor.ImageResizeContentProcessor.IMAGE_RESIZE_PARAM_MAX_HEIGHT; +import static org.apache.fineract.infrastructure.contentstore.processor.ImageResizeContentProcessor.IMAGE_RESIZE_PARAM_MAX_WIDTH; +import static org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiConstants.DOCUMENT_API_PARAM_ENTITY_ID; +import static org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiConstants.DOCUMENT_API_PARAM_ENTITY_TYPE; +import static org.apache.fineract.infrastructure.documentmanagement.api.DocumentApiConstants.DOCUMENT_API_PARAM_FILE; +import static org.apache.fineract.infrastructure.documentmanagement.api.ImageApiConstants.IMAGE_API_PARAM_MAX_HEIGHT; +import static org.apache.fineract.infrastructure.documentmanagement.api.ImageApiConstants.IMAGE_API_PARAM_MAX_WIDTH; +import static org.apache.fineract.infrastructure.documentmanagement.api.ImageApiConstants.IMAGE_API_PARAM_OUTPUT; +import static org.apache.fineract.infrastructure.documentmanagement.api.ImageApiConstants.IMAGE_API_VALUE_ENCODING_BASE64; +import static org.apache.fineract.infrastructure.documentmanagement.api.ImageApiConstants.IMAGE_API_VALUE_OUTPUT_INLINE_OCTET; +import static org.apache.fineract.util.StreamResponseUtil.DISPOSITION_TYPE_ATTACHMENT; +import static org.apache.fineract.util.StreamResponseUtil.DISPOSITION_TYPE_INLINE; +import static org.springframework.http.HttpHeaders.ACCEPT; +import static org.springframework.http.HttpHeaders.CONTENT_LENGTH; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE; +import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE; + import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.DELETE; import jakarta.ws.rs.GET; @@ -33,196 +54,175 @@ import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -import java.io.IOException; import java.io.InputStream; -import java.util.Base64; +import java.util.Map; +import java.util.Optional; +import java.util.function.Supplier; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; -import org.apache.fineract.infrastructure.core.data.UploadRequest; -import org.apache.fineract.infrastructure.core.domain.Base64EncodedImage; -import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils; -import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils.ImageFileExtension; -import org.apache.fineract.infrastructure.documentmanagement.data.FileData; -import org.apache.fineract.infrastructure.documentmanagement.data.ImageResizer; -import org.apache.fineract.infrastructure.documentmanagement.exception.ContentManagementException; -import org.apache.fineract.infrastructure.documentmanagement.exception.InvalidEntityTypeForImageManagementException; +import org.apache.fineract.command.core.CommandPipeline; +import org.apache.fineract.infrastructure.contentstore.processor.Base64DecoderContentProcessor; +import org.apache.fineract.infrastructure.contentstore.processor.Base64EncoderContentProcessor; +import org.apache.fineract.infrastructure.contentstore.processor.ContentProcessorContext; +import org.apache.fineract.infrastructure.contentstore.processor.DataUrlDecoderContentProcessor; +import org.apache.fineract.infrastructure.contentstore.processor.DataUrlEncoderContentProcessor; +import org.apache.fineract.infrastructure.contentstore.processor.ImageResizeContentProcessor; +import org.apache.fineract.infrastructure.documentmanagement.command.ImageCreateCommand; +import org.apache.fineract.infrastructure.documentmanagement.command.ImageDeleteCommand; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageCreateRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageCreateResponse; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageDeleteRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageDeleteResponse; import org.apache.fineract.infrastructure.documentmanagement.service.ImageReadPlatformService; -import org.apache.fineract.infrastructure.documentmanagement.service.ImageWritePlatformService; -import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; +import org.apache.fineract.util.StreamResponseUtil; import org.glassfish.jersey.media.multipart.FormDataBodyPart; import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataParam; import org.springframework.stereotype.Component; +// NOTE: left for backward compatibility only, could be unified with documents +@Deprecated @Slf4j @RequiredArgsConstructor @Component -@Path("/v1/{entity}/{entityId}/images") +@Path("/v1/{entityType}/{entityId}/images") public class ImagesApiResource { - private final PlatformSecurityContext context; private final ImageReadPlatformService imageReadPlatformService; - private final ImageWritePlatformService imageWritePlatformService; + private final CommandPipeline commandPipeline; + private final ImageResizeContentProcessor imageResizeContentProcessor; + private final Base64EncoderContentProcessor base64EncoderContentProcessor; + private final DataUrlEncoderContentProcessor dataUrlEncoderContentProcessor; + private final Base64DecoderContentProcessor base64DecoderContentProcessor; + private final DataUrlDecoderContentProcessor dataUrlDecoderContentProcessor; private final FileUploadValidator fileUploadValidator; - private final ImageResizer imageResizer; - /** - * Upload images through multi-part form upload - */ - @POST - @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.APPLICATION_JSON) - @RequestBody(description = "Upload new client image", content = { - @Content(mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(implementation = UploadRequest.class)) }) - public CommandProcessingResult addNewClientImage(@PathParam("entity") final String entityName, - @PathParam("entityId") final Long entityId, @HeaderParam("Content-Length") final Long fileSize, - @FormDataParam("file") final InputStream inputStream, @FormDataParam("file") final FormDataContentDisposition fileDetails, - @FormDataParam("file") final FormDataBodyPart bodyPart) { - validateEntityTypeforImage(entityName); - fileUploadValidator.validate(fileSize, inputStream, fileDetails, bodyPart); - // TODO: vishwas might need more advances validation (like reading magic - // number) for handling malicious clients - // and clients not setting mime type - ContentRepositoryUtils.validateClientImageNotEmpty(fileDetails.getFileName()); - ContentRepositoryUtils.validateImageMimeType(bodyPart.getMediaType().toString()); - - return imageWritePlatformService.saveOrUpdateImage(entityName, entityId, fileDetails.getFileName(), inputStream, fileSize); - } - - /** - * Upload image as a Data URL (essentially a base64 encoded stream) - */ - @POST - @Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) - @Produces(MediaType.APPLICATION_JSON) - public CommandProcessingResult addNewClientImage(@PathParam("entity") final String entityName, - @PathParam("entityId") final Long entityId, final String jsonRequestBody) { - validateEntityTypeforImage(entityName); - - final Base64EncodedImage base64EncodedImage = ContentRepositoryUtils.extractImageFromDataURL(jsonRequestBody); - - return imageWritePlatformService.saveOrUpdateImage(entityName, entityId, base64EncodedImage); - } - - /** - * Returns a images, either as Base64 encoded text/plain or as inline or attachment with image MIME type as - * Content-Type. - */ @GET @Consumes(MediaType.APPLICATION_JSON) // FINERACT-1265: Do NOT specify @Produces(TEXT_PLAIN) here - it may actually not (if it calls the next methods it's // octet-stream) - public Response retrieveImage(@PathParam("entity") final String entityName, @PathParam("entityId") final Long entityId, - @QueryParam("maxWidth") final Integer maxWidth, @QueryParam("maxHeight") final Integer maxHeight, - @QueryParam("output") final String output, @HeaderParam("Accept") String acceptHeader) { - validateEntityTypeforImage(entityName); - if (EntityTypeForImages.CLIENTS.toString().equalsIgnoreCase(entityName)) { - context.authenticatedUser().validateHasReadPermission("CLIENTIMAGE"); - } else if (EntityTypeForImages.STAFF.toString().equalsIgnoreCase(entityName)) { - context.authenticatedUser().validateHasReadPermission("STAFFIMAGE"); + public Response retrieveImage(@PathParam(DOCUMENT_API_PARAM_ENTITY_TYPE) final String entityName, + @PathParam(DOCUMENT_API_PARAM_ENTITY_ID) final Long entityId, @QueryParam(IMAGE_API_PARAM_MAX_WIDTH) final Integer maxWidth, + @QueryParam(IMAGE_API_PARAM_MAX_HEIGHT) final Integer maxHeight, @QueryParam(IMAGE_API_PARAM_OUTPUT) String output, + @HeaderParam(ACCEPT) String acceptHeader) { + + // TODO: pass resize information here and do all the processing in the service + final var content = imageReadPlatformService.retrieveImage(entityName, entityId); + + String dispositionType = null; + ContentProcessorContext ctx = new ContentProcessorContext(content.getStream()); + String type; + + // prevent clients sending non-sense + if (!"octet".equalsIgnoreCase(output) && !"inline_octet".equalsIgnoreCase(output)) { + output = null; } - final FileData imageData = imageReadPlatformService.retrieveImage(entityName, entityId); - final FileData resizedImage = imageResizer.resize(imageData, maxWidth, maxHeight); - - // If client wants (Accept header) octet-stream, or output="octet" or "inline_octet", then send that instead of - // text - if (MediaType.APPLICATION_OCTET_STREAM.equalsIgnoreCase(acceptHeader) - || (output != null && (output.equals("octet") || output.equals("inline_octet")))) { - return ContentResources.fileDataToResponse(resizedImage, resizedImage.name() + ImageFileExtension.JPEG, - "inline_octet".equals(output) ? "inline" : "attachment"); - } - - // Else return response with Base64 encoded - // TODO: Need a better way of determining image type - String imageDataURISuffix = ContentRepositoryUtils.ImageDataURIsuffix.JPEG.getValue(); - if (StringUtils.endsWith(imageData.name(), ContentRepositoryUtils.ImageFileExtension.GIF.getValue())) { - imageDataURISuffix = ContentRepositoryUtils.ImageDataURIsuffix.GIF.getValue(); - } else if (StringUtils.endsWith(imageData.name(), ContentRepositoryUtils.ImageFileExtension.PNG.getValue())) { - imageDataURISuffix = ContentRepositoryUtils.ImageDataURIsuffix.PNG.getValue(); - } - - try { - byte[] resizedImageBytes = resizedImage.getByteSource().read(); - if (resizedImageBytes != null) { - final String clientImageAsBase64Text = imageDataURISuffix + Base64.getMimeEncoder().encodeToString(resizedImageBytes); - return Response.ok(clientImageAsBase64Text, MediaType.TEXT_PLAIN_TYPE).build(); - } else { - log.error("resizedImageBytes is null for entityName={}, entityId={}, maxWidth={}, maxHeight={}", entityName, entityId, - maxWidth, maxHeight); - return Response.serverError().build(); + if ((StringUtils.isNotEmpty(output) && output.contains("octet")) || APPLICATION_OCTET_STREAM_VALUE.equalsIgnoreCase(acceptHeader)) { + if (maxWidth != null && maxHeight != null) { + ctx = imageResizeContentProcessor.process(content.getStream(), Map.of(IMAGE_RESIZE_PARAM_MAX_WIDTH, maxWidth, + IMAGE_RESIZE_PARAM_MAX_HEIGHT, maxHeight, IMAGE_RESIZE_PARAM_FORMAT, content.getFormat())); } - } catch (IOException e) { - throw new ContentManagementException(imageData.name(), e.getMessage(), e); + + if (IMAGE_API_VALUE_OUTPUT_INLINE_OCTET.equalsIgnoreCase(output)) { + dispositionType = DISPOSITION_TYPE_INLINE; + } else { + dispositionType = DISPOSITION_TYPE_ATTACHMENT; + } + + type = content.getContentType(); + } else { + // else stream base64 encoded original format + if (maxWidth != null && maxHeight != null) { + ctx = imageResizeContentProcessor.then(base64EncoderContentProcessor).then(dataUrlEncoderContentProcessor).process( + content.getStream(), + Map.of(IMAGE_RESIZE_PARAM_MAX_WIDTH, maxWidth, IMAGE_RESIZE_PARAM_MAX_HEIGHT, maxHeight, IMAGE_RESIZE_PARAM_FORMAT, + content.getFormat(), DATA_URL_ENCODE_PARAM_CONTENT_TYPE, content.getContentType(), + DATA_URL_ENCODE_PARAM_ENCODING, IMAGE_API_VALUE_ENCODING_BASE64)); + } else { + ctx = base64EncoderContentProcessor.then(dataUrlEncoderContentProcessor).process(content.getStream(), + Map.of(DATA_URL_ENCODE_PARAM_CONTENT_TYPE, content.getContentType(), DATA_URL_ENCODE_PARAM_ENCODING, + IMAGE_API_VALUE_ENCODING_BASE64)); + } + + type = TEXT_PLAIN_VALUE; } + + // make sure we use the transformed input stream ("ctx.getInputStream()") + return StreamResponseUtil.ok(StreamResponseUtil.StreamResponseData.builder().fileName(content.getDisplayName()).type(type) + .stream(ctx.getInputStream()).dispositionType(dispositionType).build()); + } + + @POST + @Consumes({ MediaType.MULTIPART_FORM_DATA }) + @Produces({ MediaType.APPLICATION_JSON }) + @ApiResponse(responseCode = "200", description = "Not Shown (multi-part form data)") + public ImageCreateResponse createImage(@PathParam(DOCUMENT_API_PARAM_ENTITY_TYPE) final String entityType, + @PathParam(DOCUMENT_API_PARAM_ENTITY_ID) final Long entityId, @HeaderParam(CONTENT_LENGTH) final Long fileSize, + @FormDataParam(DOCUMENT_API_PARAM_FILE) final InputStream is, + @FormDataParam(DOCUMENT_API_PARAM_FILE) final FormDataContentDisposition fileDetails, + @FormDataParam(DOCUMENT_API_PARAM_FILE) final FormDataBodyPart filePart) { + + fileUploadValidator.validate(fileSize, is, fileDetails, filePart); + + final var command = new ImageCreateCommand(); + + command.setPayload( + ImageCreateRequest.builder().entityId(entityId).entityType(entityType).fileName(fileDetails.getFileName()).size(fileSize) + .type(Optional.ofNullable(filePart.getMediaType()).map(MediaType::toString).orElse(null)).stream(is).build()); + + final Supplier response = commandPipeline.send(command); + + return response.get(); + } + + @POST + @Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) + public ImageCreateResponse createImage(@PathParam(DOCUMENT_API_PARAM_ENTITY_TYPE) final String entityType, + @PathParam(DOCUMENT_API_PARAM_ENTITY_ID) final Long entityId, final InputStream body) { + + requireNonNull(body, "Missing input stream"); + + final var command = new ImageCreateCommand(); + + var ctx = dataUrlDecoderContentProcessor.then(base64DecoderContentProcessor).process(new ContentProcessorContext(body)); + + command.setPayload(ImageCreateRequest.builder().entityId(entityId).entityType(entityType).stream(ctx.getInputStream()).build()); + + final Supplier response = commandPipeline.send(command); + + return response.get(); } - /** - * This method is added only for consistency with other URL patterns and for maintaining consistency of usage of the - * HTTP "verb" at the client side - */ @PUT @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces(MediaType.APPLICATION_JSON) - @RequestBody(description = "Update client image", content = { - @Content(mediaType = MediaType.MULTIPART_FORM_DATA, schema = @Schema(implementation = UploadRequest.class)) }) - public CommandProcessingResult updateClientImage(@PathParam("entity") final String entityName, - @PathParam("entityId") final Long entityId, @HeaderParam("Content-Length") final Long fileSize, - @FormDataParam("file") final InputStream inputStream, @FormDataParam("file") final FormDataContentDisposition fileDetails, - @FormDataParam("file") final FormDataBodyPart bodyPart) { - return addNewClientImage(entityName, entityId, fileSize, inputStream, fileDetails, bodyPart); + @RequestBody(description = "Update image", content = { @Content(mediaType = MediaType.MULTIPART_FORM_DATA) }) + public ImageCreateResponse updateImage(@PathParam(DOCUMENT_API_PARAM_ENTITY_TYPE) final String entityName, + @PathParam(DOCUMENT_API_PARAM_ENTITY_ID) final Long entityId, @HeaderParam(CONTENT_LENGTH) final Long fileSize, + @FormDataParam(DOCUMENT_API_PARAM_FILE) final InputStream inputStream, + @FormDataParam(DOCUMENT_API_PARAM_FILE) final FormDataContentDisposition fileDetails, + @FormDataParam(DOCUMENT_API_PARAM_FILE) final FormDataBodyPart bodyPart) { + return createImage(entityName, entityId, fileSize, inputStream, fileDetails, bodyPart); } - /** - * This method is added only for consistency with other URL patterns and for maintaining consistency of usage of the - * HTTP "verb" at the client side - * - * Upload image as a Data URL (essentially a base64 encoded stream) - */ @PUT @Consumes({ MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) - @Produces(MediaType.APPLICATION_JSON) - public CommandProcessingResult updateClientImage(@PathParam("entity") final String entityName, - @PathParam("entityId") final Long entityId, final String jsonRequestBody) { - return addNewClientImage(entityName, entityId, jsonRequestBody); + public ImageCreateResponse updateImage(@PathParam(DOCUMENT_API_PARAM_ENTITY_TYPE) final String entityName, + @PathParam(DOCUMENT_API_PARAM_ENTITY_ID) final Long entityId, final InputStream body) { + return createImage(entityName, entityId, body); } @DELETE - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - public CommandProcessingResult deleteClientImage(@PathParam("entity") final String entityName, - @PathParam("entityId") final Long entityId) { - validateEntityTypeforImage(entityName); - imageWritePlatformService.deleteImage(entityName, entityId); - return CommandProcessingResult.resourceResult(entityId); - } + public ImageDeleteResponse deleteImage(@PathParam(DOCUMENT_API_PARAM_ENTITY_TYPE) final String entityType, + @PathParam(DOCUMENT_API_PARAM_ENTITY_ID) final Long entityId) { - /*** Entities for document Management **/ - public enum EntityTypeForImages { + final var command = new ImageDeleteCommand(); - STAFF, // - CLIENTS; // + command.setPayload(ImageDeleteRequest.builder().entityId(entityId).entityType(entityType).build()); - @Override - public String toString() { - return name().toLowerCase(); - } - } + final Supplier response = commandPipeline.send(command); - private void validateEntityTypeforImage(final String entityName) { - if (!checkValidEntityType(entityName)) { - throw new InvalidEntityTypeForImageManagementException(entityName); - } - } - - private static boolean checkValidEntityType(final String entityType) { - for (final EntityTypeForImages entities : EntityTypeForImages.values()) { - if (entities.name().equalsIgnoreCase(entityType)) { - return true; - } - } - return false; + return response.get(); } } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentCommand.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentCommand.java index 0c430c8fd..ecfa5a294 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentCommand.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentCommand.java @@ -20,9 +20,7 @@ package org.apache.fineract.infrastructure.documentmanagement.command; import java.util.Set; -/** - * Immutable command for creating or updating details of a client identifier. - */ +@Deprecated(forRemoval = true) public class DocumentCommand { private final Long id; @@ -35,13 +33,9 @@ public class DocumentCommand { private Long size; private String type; private String location; - private Integer storageType; - - private final Set modifiedParameters; public DocumentCommand(final Set modifiedParameters, final Long id, final String parentEntityType, final Long parentEntityId, final String name, final String fileName, final Long size, final String type, final String description, final String location) { - this.modifiedParameters = modifiedParameters; this.id = id; this.parentEntityType = parentEntityType; this.parentEntityId = parentEntityId; @@ -89,10 +83,6 @@ public class DocumentCommand { return this.location; } - public Set getModifiedParameters() { - return this.modifiedParameters; - } - public void setFileName(final String fileName) { this.fileName = fileName; } @@ -108,37 +98,4 @@ public class DocumentCommand { public void setLocation(final String location) { this.location = location; } - - public Integer getStorageType() { - return this.storageType; - } - - public void setStorageType(final Integer storageType) { - this.storageType = storageType; - } - - public boolean isNameChanged() { - return this.modifiedParameters.contains("name"); - } - - public boolean isFileNameChanged() { - return this.modifiedParameters.contains("fileName"); - } - - public boolean isSizeChanged() { - return this.modifiedParameters.contains("size"); - } - - public boolean isFileTypeChanged() { - return this.modifiedParameters.contains("type"); - } - - public boolean isDescriptionChanged() { - return this.modifiedParameters.contains("description"); - } - - public boolean isLocationChanged() { - return this.modifiedParameters.contains("location"); - } - } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentCommandValidator.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentCommandValidator.java deleted file mode 100644 index 4cb094397..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentCommandValidator.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.command; - -import java.util.ArrayList; -import java.util.List; -import org.apache.fineract.infrastructure.core.data.ApiParameterError; -import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; -import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; - -public class DocumentCommandValidator { - - private final DocumentCommand command; - - public DocumentCommandValidator(final DocumentCommand command) { - this.command = command; - } - - public void validateForUpdate() { - final List dataValidationErrors = new ArrayList<>(); - - final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("document"); - - baseDataValidator.reset().parameter("name").value(this.command.getName()).ignoreIfNull().notBlank(); - baseDataValidator.reset().parameter("size").value(this.command.getSize()).ignoreIfNull().integerGreaterThanZero(); - baseDataValidator.reset().parameter("fileName").value(this.command.getFileName()).ignoreIfNull().notBlank() - .notExceedingLengthOf(250); - baseDataValidator.reset().parameter("location").value(this.command.getLocation()).ignoreIfNull().notBlank(); - baseDataValidator.reset().parameter("description").value(this.command.getName()).ignoreIfNull().notExceedingLengthOf(250); - - baseDataValidator.reset().anyOfNotNull(this.command.getName(), this.command.getFileName(), this.command.getDescription(), - this.command.getLocation(), this.command.getSize()); - - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", - dataValidationErrors); - } - } - - public void validateForCreate() { - final List dataValidationErrors = new ArrayList<>(); - - final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("document"); - baseDataValidator.reset().parameter("parentEntityType").value(this.command.getParentEntityType()).notBlank() - .notExceedingLengthOf(50); - baseDataValidator.reset().parameter("parentEntityId").value(this.command.getParentEntityId()).integerGreaterThanZero(); - baseDataValidator.reset().parameter("name").value(this.command.getName()).notBlank().notExceedingLengthOf(250); - baseDataValidator.reset().parameter("size").value(this.command.getSize()).integerGreaterThanZero(); - baseDataValidator.reset().parameter("fileName").value(this.command.getFileName()).notBlank().notExceedingLengthOf(250); - baseDataValidator.reset().parameter("description").value(this.command.getName()).notExceedingLengthOf(250); - - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", - dataValidationErrors); - } - } -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentCreateCommand.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentCreateCommand.java new file mode 100644 index 000000000..a8b0d1e65 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentCreateCommand.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.command; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentCreateRequest; + +@Data +@EqualsAndHashCode(callSuper = true) +public class DocumentCreateCommand extends Command {} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentDeleteCommand.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentDeleteCommand.java new file mode 100644 index 000000000..1f0b5dc90 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentDeleteCommand.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.command; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentDeleteRequest; + +@Data +@EqualsAndHashCode(callSuper = true) +public class DocumentDeleteCommand extends Command {} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentUpdateCommand.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentUpdateCommand.java new file mode 100644 index 000000000..609b76bab --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/DocumentUpdateCommand.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.command; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentUpdateRequest; + +@Data +@EqualsAndHashCode(callSuper = true) +public class DocumentUpdateCommand extends Command {} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/ImageCreateCommand.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/ImageCreateCommand.java new file mode 100644 index 000000000..2018da75e --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/ImageCreateCommand.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.command; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageCreateRequest; + +@Data +@EqualsAndHashCode(callSuper = true) +public class ImageCreateCommand extends Command {} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/ImageDeleteCommand.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/ImageDeleteCommand.java new file mode 100644 index 000000000..e510df660 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/command/ImageDeleteCommand.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.command; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageDeleteRequest; + +@Data +@EqualsAndHashCode(callSuper = true) +public class ImageDeleteCommand extends Command {} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentRepository.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentRepository.java deleted file mode 100644 index 831e7b682..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentRepository.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.contentrepository; - -import java.io.InputStream; -import org.apache.fineract.infrastructure.core.domain.Base64EncodedImage; -import org.apache.fineract.infrastructure.documentmanagement.command.DocumentCommand; -import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData; -import org.apache.fineract.infrastructure.documentmanagement.data.FileData; -import org.apache.fineract.infrastructure.documentmanagement.data.ImageData; -import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType; - -/** - * Repository which stores Files (AKA Documents) and Images. - */ -public interface ContentRepository { - - // TODO:Vishwas Need to move these settings to the Database - Integer MAX_FILE_UPLOAD_SIZE_IN_MB = 5; - - // TODO:Vishwas Need to move these settings to the Database - Integer MAX_IMAGE_UPLOAD_SIZE_IN_MB = 1; - - String saveFile(InputStream uploadedInputStream, DocumentCommand documentCommand); - - void deleteFile(String documentPath); - - FileData fetchFile(DocumentData documentData); - - String saveImage(InputStream uploadedInputStream, Long resourceId, String imageName, Long fileSize); - - String saveImage(Base64EncodedImage base64EncodedImage, Long resourceId, String imageName); - - void deleteImage(String location); - - FileData fetchImage(ImageData imageData); - - StorageType getStorageType(); - -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentRepositoryFactory.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentRepositoryFactory.java deleted file mode 100644 index b17803e02..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentRepositoryFactory.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.contentrepository; - -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.apache.fineract.infrastructure.core.config.FineractProperties; -import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType; -import org.springframework.stereotype.Component; - -@Component -@RequiredArgsConstructor -public class ContentRepositoryFactory { - - private final FineractProperties fineractProperties; - private final List contentRepositories; - - public ContentRepository getRepository() { - if (fineractProperties.getContent() != null) { - if (fineractProperties.getContent().getFilesystem() != null - && Boolean.TRUE.equals(fineractProperties.getContent().getFilesystem().getEnabled())) { - return getRepository(StorageType.FILE_SYSTEM); - } else if (fineractProperties.getContent().getS3() != null - && Boolean.TRUE.equals(fineractProperties.getContent().getS3().getEnabled())) { - return getRepository(StorageType.S3); - } - } - - throw new RuntimeException( - "No content repository enabled. Please set either 'fineract.content.filesystem.enabled=true' or 'fineract.content.s3.enabled=true' in your application.properties."); - } - - public ContentRepository getRepository(StorageType storageType) { - return contentRepositories.stream().filter(cr -> cr.getStorageType().equals(storageType)).findFirst().orElseThrow( - () -> new RuntimeException(String.format("No content repository implementation found for storage type: %s", storageType))); - } -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentRepositoryUtils.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentRepositoryUtils.java deleted file mode 100644 index d13d08b72..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/ContentRepositoryUtils.java +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.contentrepository; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.List; -import org.apache.commons.lang3.StringUtils; -import org.apache.fineract.infrastructure.core.data.ApiParameterError; -import org.apache.fineract.infrastructure.core.domain.Base64EncodedImage; -import org.apache.fineract.infrastructure.core.exception.ImageDataURLNotValidException; -import org.apache.fineract.infrastructure.core.exception.ImageUploadException; -import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; -import org.apache.fineract.infrastructure.documentmanagement.exception.ContentManagementException; - -public final class ContentRepositoryUtils { - - private static final SecureRandom random = new SecureRandom(); - - private ContentRepositoryUtils() {} - - public enum ImageMIMEtype { - - GIF("image/gif"), // - JPEG("image/jpeg"), // - PNG("image/png"); // - - private final String value; - - ImageMIMEtype(final String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } - - @SuppressWarnings("UnnecessaryDefaultInEnumSwitch") - public static ImageMIMEtype fromFileExtension(ImageFileExtension fileExtension) { - switch (fileExtension) { - case GIF: - return ImageMIMEtype.GIF; - case JPG: - case JPEG: - return ImageMIMEtype.JPEG; - case PNG: - return ImageMIMEtype.PNG; - default: - throw new IllegalArgumentException(); - } - } - } - - public enum ImageFileExtension { - - GIF(".gif"), // - JPEG(".jpeg"), // - JPG(".jpg"), // - PNG(".png"); // - - private final String value; - - ImageFileExtension(final String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } - - public String getValueWithoutDot() { - return this.value.substring(1); - } - - public ImageFileExtension getFileExtension() { - switch (this) { - case GIF: - return ImageFileExtension.GIF; - case JPEG: - return ImageFileExtension.JPEG; - case PNG: - return ImageFileExtension.PNG; - default: - throw new IllegalArgumentException(); - } - } - } - - public enum ImageDataURIsuffix { - - GIF("data:" + ImageMIMEtype.GIF.getValue() + ";base64,"), // - JPEG("data:" + ImageMIMEtype.JPEG.getValue() + ";base64,"), // - PNG("data:" + ImageMIMEtype.PNG.getValue() + ";base64,"); - - private final String value; - - ImageDataURIsuffix(final String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } - } - - public static ImageFileExtension imageExtensionFromFileName(String fileName) { - if (StringUtils.endsWith(fileName.toLowerCase(), ContentRepositoryUtils.ImageFileExtension.GIF.getValue())) { - return ContentRepositoryUtils.ImageFileExtension.GIF; - } else if (StringUtils.endsWith(fileName, ContentRepositoryUtils.ImageFileExtension.PNG.getValue())) { - return ContentRepositoryUtils.ImageFileExtension.PNG; - } else { - return ContentRepositoryUtils.ImageFileExtension.JPEG; - } - } - - /** - * Validates that passed in Mime type maps to known image mime types - * - * @param mimeType - */ - public static void validateImageMimeType(final String mimeType) { - if ((!mimeType.equalsIgnoreCase(ImageMIMEtype.GIF.getValue()) && !mimeType.equalsIgnoreCase(ImageMIMEtype.JPEG.getValue()) - && !mimeType.equalsIgnoreCase(ImageMIMEtype.PNG.getValue()))) { - throw new ImageUploadException(mimeType); - } - } - - /** - * Extracts Image from a Data URL - * - * @param dataURL - * mimeType - */ - public static Base64EncodedImage extractImageFromDataURL(final String dataURL) { - String fileExtension = ""; - String base64EncodedString = null; - if (StringUtils.startsWith(dataURL, ImageDataURIsuffix.GIF.getValue())) { - base64EncodedString = dataURL.replaceAll(ImageDataURIsuffix.GIF.getValue(), ""); - fileExtension = ImageFileExtension.GIF.getValue(); - } else if (StringUtils.startsWith(dataURL, ImageDataURIsuffix.PNG.getValue())) { - base64EncodedString = dataURL.replaceAll(ImageDataURIsuffix.PNG.getValue(), ""); - fileExtension = ImageFileExtension.PNG.getValue(); - } else if (StringUtils.startsWith(dataURL, ImageDataURIsuffix.JPEG.getValue())) { - base64EncodedString = dataURL.replaceAll(ImageDataURIsuffix.JPEG.getValue(), ""); - fileExtension = ImageFileExtension.JPEG.getValue(); - } else { - throw new ImageDataURLNotValidException(); - } - - return new Base64EncodedImage(base64EncodedString, fileExtension); - } - - public static void validateFileSizeWithinPermissibleRange(final Long fileSize, final String name) { - /** - * Using Content-Length gives me size of the entire request, which is good enough for now for a fast fail as the - * length of the rest of the content i.e name and description while compared to the uploaded file size is - * negligible - **/ - if (fileSize != null && ((fileSize / (1024 * 1024)) > ContentRepository.MAX_FILE_UPLOAD_SIZE_IN_MB)) { - throw new ContentManagementException(name, fileSize, ContentRepository.MAX_FILE_UPLOAD_SIZE_IN_MB); - } - } - - public static void validateClientImageNotEmpty(final String imageFileName) { - final List dataValidationErrors = new ArrayList<>(); - if (imageFileName == null) { - final StringBuilder validationErrorCode = new StringBuilder("validation.msg.clientImage.cannot.be.blank"); - final StringBuilder defaultEnglishMessage = new StringBuilder("The parameter image cannot be blank."); - final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), - defaultEnglishMessage.toString(), "image"); - dataValidationErrors.add(error); - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", - dataValidationErrors); - } - } - - /** - * Generate a random String. - */ - - @SuppressFBWarnings(value = { - "DMI_RANDOM_USED_ONLY_ONCE" }, justification = "False positive for random object created and used only once") - public static String generateRandomString() { - final String characters = "abcdefghijklmnopqrstuvwxyz123456789"; - // length is a random number between 5 to 16 - final int length = random.nextInt(11) + 5; - final char[] text = new char[length]; - for (int i = 0; i < length; i++) { - text[i] = characters.charAt(random.nextInt(characters.length())); - } - return new String(text); - } -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/FileSystemContentPathSanitizer.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/FileSystemContentPathSanitizer.java deleted file mode 100644 index 9d7c55889..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/FileSystemContentPathSanitizer.java +++ /dev/null @@ -1,138 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.contentrepository; - -import jakarta.annotation.PostConstruct; -import java.io.BufferedInputStream; -import java.nio.file.Path; -import java.util.List; -import java.util.regex.Pattern; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.fineract.infrastructure.core.config.FineractProperties; -import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; -import org.apache.fineract.infrastructure.documentmanagement.exception.ContentManagementException; -import org.apache.tika.Tika; -import org.apache.tika.io.TikaInputStream; -import org.apache.tika.metadata.Metadata; -import org.apache.tika.parser.AutoDetectParser; -import org.apache.tika.sax.BodyContentHandler; -import org.springframework.stereotype.Component; - -@Slf4j -@RequiredArgsConstructor -@Component -public class FileSystemContentPathSanitizer implements ContentPathSanitizer { - - private final FineractProperties fineractProperties; - - private List regexWhitelist; - - private static Pattern OVERWRITE_SIBLING_IMAGE = Pattern.compile(".*\\.\\./+[0-9]+/+.*"); - - @PostConstruct - public void init() { - regexWhitelist = fineractProperties.getContent().getRegexWhitelist().stream().map(Pattern::compile).toList(); - } - - @Override - public String sanitize(String path) { - return sanitize(path, null); - } - - @Override - public String sanitize(String path, BufferedInputStream is) { - try { - if (OVERWRITE_SIBLING_IMAGE.matcher(path).matches()) { - throw new RuntimeException(String.format("Trying to overwrite another resource's image: %s", path)); - } - - String sanitizedPath = Path.of(path).normalize().toString(); - - String fileName = FilenameUtils.getName(sanitizedPath).toLowerCase(); - - if (log.isDebugEnabled()) { - log.debug("Path: {} -> {} ({})", path, sanitizedPath, fileName); - } - - if (fineractProperties.getContent().isRegexWhitelistEnabled()) { - boolean matches = regexWhitelist.stream().anyMatch(p -> p.matcher(fileName).matches()); - - if (!matches) { - throw new RuntimeException(String.format("File name not allowed: %s", fileName)); - } - } - - if (is != null && fineractProperties.getContent().isMimeWhitelistEnabled()) { - Tika tika = new Tika(); - String extensionMimeType = tika.detect(fileName); - - if (StringUtils.isEmpty(extensionMimeType)) { - throw new RuntimeException(String.format("Could not detect mime type for filename %s!", fileName)); - } - - if (!fineractProperties.getContent().getMimeWhitelist().contains(extensionMimeType)) { - throw new RuntimeException( - String.format("Detected mime type %s for filename %s not allowed!", extensionMimeType, fileName)); - } - - String contentMimeType = detectContentMimeType(is); - - if (StringUtils.isEmpty(contentMimeType)) { - throw new RuntimeException(String.format("Could not detect content mime type for %s!", fileName)); - } - - if (!fineractProperties.getContent().getMimeWhitelist().contains(contentMimeType)) { - throw new RuntimeException( - String.format("Detected content mime type %s for %s not allowed!", contentMimeType, fileName)); - } - - if (!contentMimeType.equalsIgnoreCase(extensionMimeType)) { - throw new RuntimeException(String.format("Detected filename (%s) and content (%s) mime type do not match!", - extensionMimeType, contentMimeType)); - } - } - - Path target = Path.of(sanitizedPath); - Path rootFolder = Path.of(fineractProperties.getContent().getFilesystem().getRootFolder(), - ThreadLocalContextUtil.getTenant().getName().replaceAll(" ", "").trim()); - - if (!target.startsWith(rootFolder)) { - throw new RuntimeException(String.format("Path traversal attempt: %s (%s)", target, rootFolder)); - } - - return sanitizedPath; - } catch (Exception e) { - throw new ContentManagementException(path, e.getMessage(), e); - } - } - - private String detectContentMimeType(BufferedInputStream bis) throws Exception { - TikaInputStream tis = TikaInputStream.get(bis); - AutoDetectParser parser = new AutoDetectParser(); - // NOTE: turn off write limit with "-1" - BodyContentHandler handler = new BodyContentHandler(-1); - Metadata metadata = new Metadata(); - parser.parse(tis, handler, metadata); - - return metadata.get("Content-Type"); - } -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/FileSystemContentRepository.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/FileSystemContentRepository.java deleted file mode 100644 index 6d546ba25..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/FileSystemContentRepository.java +++ /dev/null @@ -1,164 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.contentrepository; - -import com.google.common.io.Files; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Base64; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.FileUtils; -import org.apache.fineract.infrastructure.core.config.FineractProperties; -import org.apache.fineract.infrastructure.core.domain.Base64EncodedImage; -import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; -import org.apache.fineract.infrastructure.documentmanagement.command.DocumentCommand; -import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData; -import org.apache.fineract.infrastructure.documentmanagement.data.FileData; -import org.apache.fineract.infrastructure.documentmanagement.data.ImageData; -import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType; -import org.apache.fineract.infrastructure.documentmanagement.exception.ContentManagementException; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.stereotype.Component; - -@Slf4j -@RequiredArgsConstructor -@Component -@ConditionalOnProperty("fineract.content.filesystem.enabled") -public class FileSystemContentRepository implements ContentRepository { - - private final FileSystemContentPathSanitizer pathSanitizer; - private final FineractProperties fineractProperties; - - @Override - public String saveFile(final InputStream uploadedInputStream, final DocumentCommand documentCommand) { - final String fileName = documentCommand.getFileName(); - ContentRepositoryUtils.validateFileSizeWithinPermissibleRange(documentCommand.getSize(), fileName); - - final String fileLocation = generateFileParentDirectory(documentCommand.getParentEntityType(), documentCommand.getParentEntityId()) - + File.separator + fileName; - - return writeFileToFileSystem(fileName, uploadedInputStream, fileLocation); - } - - @Override - public String saveImage(final InputStream uploadedInputStream, final Long resourceId, final String imageName, final Long fileSize) { - ContentRepositoryUtils.validateFileSizeWithinPermissibleRange(fileSize, imageName); - final String fileLocation = generateClientImageParentDirectory(resourceId) + File.separator + imageName; - return writeFileToFileSystem(imageName, uploadedInputStream, fileLocation); - } - - @Override - public String saveImage(final Base64EncodedImage base64EncodedImage, final Long resourceId, final String imageName) { - final String fileLocation = generateClientImageParentDirectory(resourceId) + File.separator + imageName - + base64EncodedImage.getFileExtension(); - String base64EncodedImageString = base64EncodedImage.getBase64EncodedString(); - try { - final InputStream toUploadInputStream = new ByteArrayInputStream(Base64.getMimeDecoder().decode(base64EncodedImageString)); - return writeFileToFileSystem(imageName, toUploadInputStream, fileLocation); - } catch (IllegalArgumentException iae) { - log.error("IllegalArgumentException due to invalid Base64 encoding: {}", base64EncodedImageString, iae); - throw iae; - } - } - - @Override - public void deleteImage(final String location) { - deleteFileInternal(location); - } - - @Override - public void deleteFile(final String documentPath) { - deleteFileInternal(documentPath); - } - - private void deleteFileInternal(final String documentPath) { - String sanitizedPath = pathSanitizer.sanitize(documentPath); - - final File fileToBeDeleted = new File(sanitizedPath); - final boolean fileDeleted = fileToBeDeleted.delete(); - if (!fileDeleted) { - // no need to throw an Error, what's a caller going to do about it, so simply log a warning - log.warn("Unable to delete file {}", documentPath); - } - } - - @Override - public FileData fetchFile(final DocumentData documentData) { - String sanitizedPath = pathSanitizer.sanitize(documentData.getLocation()); - - final File file = new File(sanitizedPath); - return new FileData(Files.asByteSource(file), documentData.getFileName(), documentData.getType()); - } - - @Override - public FileData fetchImage(final ImageData imageData) { - String sanitizedPath = pathSanitizer.sanitize(imageData.location()); - - final File file = new File(sanitizedPath); - return new FileData(Files.asByteSource(file), imageData.getEntityDisplayName(), imageData.contentType().getValue()); - } - - @Override - public StorageType getStorageType() { - return StorageType.FILE_SYSTEM; - } - - /** - * Generate the directory path for storing the new document - */ - private String generateFileParentDirectory(final String entityType, final Long entityId) { - return fineractProperties.getContent().getFilesystem().getRootFolder() + File.separator - + ThreadLocalContextUtil.getTenant().getName().replace(" ", "").trim() + File.separator + "documents" + File.separator - + entityType + File.separator + entityId + File.separator + ContentRepositoryUtils.generateRandomString(); - } - - /** - * Generate ContentRepositoryUtilsfineractProperties.getContentgetWhitelist()getBlacklist() path for storing new - * Image - */ - private String generateClientImageParentDirectory(final Long resourceId) { - return fineractProperties.getContent().getFilesystem().getRootFolder() + File.separator - + ThreadLocalContextUtil.getTenant().getName().replace(" ", "").trim() + File.separator + "images" + File.separator - + "clients" + File.separator + resourceId; - } - - /** - * Recursively create the directory if it does not exist. - */ - private void makeDirectories(final String uploadDocumentLocation) throws IOException { - String sanitizedPath = pathSanitizer.sanitize(uploadDocumentLocation); - Files.createParentDirs(new File(sanitizedPath)); - } - - private String writeFileToFileSystem(final String fileName, final InputStream uploadedInputStream, final String fileLocation) { - try (BufferedInputStream bis = new BufferedInputStream(uploadedInputStream)) { - String sanitizedPath = pathSanitizer.sanitize(fileLocation, bis); - makeDirectories(sanitizedPath); - FileUtils.copyInputStreamToFile(bis, new File(sanitizedPath)); // NOSONAR - return sanitizedPath; - } catch (final IOException ioException) { - log.warn("Failed to write file!", ioException); - throw new ContentManagementException(fileName, ioException.getMessage(), ioException); - } - } -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/S3ContentRepository.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/S3ContentRepository.java deleted file mode 100644 index 180a75121..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/S3ContentRepository.java +++ /dev/null @@ -1,177 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.contentrepository; - -import com.google.common.io.ByteSource; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Base64; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.IOUtils; -import org.apache.fineract.infrastructure.core.config.FineractProperties; -import org.apache.fineract.infrastructure.core.domain.Base64EncodedImage; -import org.apache.fineract.infrastructure.documentmanagement.command.DocumentCommand; -import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData; -import org.apache.fineract.infrastructure.documentmanagement.data.FileData; -import org.apache.fineract.infrastructure.documentmanagement.data.ImageData; -import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType; -import org.apache.fineract.infrastructure.documentmanagement.exception.ContentManagementException; -import org.apache.fineract.infrastructure.documentmanagement.exception.DocumentNotFoundException; -import org.apache.fineract.infrastructure.security.utils.LogParameterEscapeUtil; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.stereotype.Component; -import software.amazon.awssdk.awscore.exception.AwsServiceException; -import software.amazon.awssdk.core.ResponseBytes; -import software.amazon.awssdk.core.exception.SdkException; -import software.amazon.awssdk.core.sync.RequestBody; -import software.amazon.awssdk.core.sync.ResponseTransformer; -import software.amazon.awssdk.services.s3.S3Client; -import software.amazon.awssdk.services.s3.model.GetObjectRequest; -import software.amazon.awssdk.services.s3.model.GetObjectResponse; - -@Slf4j -@RequiredArgsConstructor -@Component -@ConditionalOnProperty("fineract.content.s3.enabled") -public class S3ContentRepository implements ContentRepository { - - private final S3Client s3Client; - private final FineractProperties fineractProperties; - - @Override - public String saveFile(final InputStream toUpload, final DocumentCommand documentCommand) { - final String fileName = documentCommand.getFileName(); - ContentRepositoryUtils.validateFileSizeWithinPermissibleRange(documentCommand.getSize(), fileName); - - final String uploadDocFolder = generateFileParentDirectory(documentCommand.getParentEntityType(), - documentCommand.getParentEntityId()); - final String uploadDocFullPath = uploadDocFolder + File.separator + fileName; - - putObject(fileName, toUpload, uploadDocFullPath); - return uploadDocFullPath; - } - - @Override - public void deleteFile(final String documentPath) { - deleteObject(documentPath); - } - - @Override - public String saveImage(final InputStream toUploadInputStream, final Long resourceId, final String imageName, final Long fileSize) { - ContentRepositoryUtils.validateFileSizeWithinPermissibleRange(fileSize, imageName); - final String uploadImageLocation = generateClientImageParentDirectory(resourceId); - final String fileLocation = uploadImageLocation + File.separator + imageName; - - putObject(imageName, toUploadInputStream, fileLocation); - return fileLocation; - } - - @Override - public String saveImage(final Base64EncodedImage base64EncodedImage, final Long resourceId, final String imageName) { - final String uploadImageLocation = generateClientImageParentDirectory(resourceId); - final String fileLocation = uploadImageLocation + File.separator + imageName + base64EncodedImage.getFileExtension(); - final InputStream toUploadInputStream = new ByteArrayInputStream( - Base64.getMimeDecoder().decode(base64EncodedImage.getBase64EncodedString())); - - putObject(imageName, toUploadInputStream, fileLocation); - return fileLocation; - } - - @Override - public void deleteImage(final String location) { - deleteObject(location); - } - - @Override - public FileData fetchFile(final DocumentData documentData) throws DocumentNotFoundException { - return new FileData(new ByteSource() { - - @Override - public InputStream openStream() throws IOException { - return s3Client.getObject(GetObjectRequest.builder().bucket(fineractProperties.getContent().getS3().getBucketName()) - .key(documentData.getLocation()).build(), ResponseTransformer.toBytes()).asInputStream(); - } - }, documentData.getFileName(), documentData.getType()); - } - - @Override - public FileData fetchImage(final ImageData imageData) { - return new FileData(new ByteSource() { - - @Override - public InputStream openStream() throws IOException { - return s3Client.getObject(GetObjectRequest.builder().bucket(fineractProperties.getContent().getS3().getBucketName()) - .key(imageData.location()).build(), ResponseTransformer.toBytes()).asInputStream(); - } - }, imageData.getEntityDisplayName(), imageData.contentType().getValue()); - } - - @Override - public StorageType getStorageType() { - return StorageType.S3; - } - - private String generateFileParentDirectory(final String entityType, final Long entityId) { - return "documents" + File.separator + entityType + File.separator + entityId + File.separator - + ContentRepositoryUtils.generateRandomString(); - } - - private String generateClientImageParentDirectory(final Long resourceId) { - return "images" + File.separator + "clients" + File.separator + resourceId; - } - - private void deleteObject(final String location) { - try { - this.s3Client.deleteObject(builder -> builder.bucket(fineractProperties.getContent().getS3().getBucketName()).key(location)); - } catch (final AwsServiceException ase) { - throw new ContentManagementException(location, - "message=" + ase.getMessage() + ", Error Code=" + ase.awsErrorDetails().errorCode(), ase); - } catch (final SdkException ace) { - throw new ContentManagementException(location, ace.getMessage(), ace); - } - } - - public void putObject(final String filename, final InputStream inputStream, final String s3UploadLocation) - throws ContentManagementException { - try { - if (log.isDebugEnabled()) { - log.debug("Uploading a new object to S3 {}", LogParameterEscapeUtil.escapeLogParameter(s3UploadLocation)); - } - this.s3Client.putObject( - builder -> builder.bucket(fineractProperties.getContent().getS3().getBucketName()).key(s3UploadLocation), - RequestBody.fromBytes(IOUtils.toByteArray(inputStream))); - } catch (AwsServiceException | IOException ase) { - throw new ContentManagementException(filename, ase.getMessage(), ase); - } - } - - public ResponseBytes getObject(String key) { - try { - log.debug("Downloading an object from Amazon S3 Bucket: {}, location: {}", - fineractProperties.getContent().getS3().getBucketName(), key); - return this.s3Client.getObject(builder -> builder.bucket(fineractProperties.getContent().getS3().getBucketName()).key(key), - ResponseTransformer.toBytes()); - } catch (SdkException ase) { - throw new ContentManagementException(key, ase.getMessage(), ase); - } - } -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentContent.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentContent.java new file mode 100644 index 000000000..f56a57120 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentContent.java @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.data; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.Hidden; +import java.io.InputStream; +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DocumentContent implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private String displayName; + private String fileName; + private String contentType; + private String format; + private Long size; + @Hidden + @JsonIgnore + private InputStream stream; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentCreateRequest.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentCreateRequest.java new file mode 100644 index 000000000..9fe12c67a --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentCreateRequest.java @@ -0,0 +1,61 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.data; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.io.InputStream; +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DocumentCreateRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + @Size(max = 50, message = "{org.apache.fineract.document.xxx.not-null}") + private String entityType; + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + private Long entityId; + @Size(max = 250, message = "{org.apache.fineract.document.xxx.not-null}") + private String name; + @Size(max = 250, message = "{org.apache.fineract.document.xxx.not-null}") + private String description; + @Size(max = 250, message = "{org.apache.fineract.document.xxx.not-null}") + private String fileName; + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + @Min(value = 1, message = "{org.apache.fineract.document.xxx.not-null}") + private Long size; + private String type; + @Hidden + @JsonIgnore + private InputStream stream; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/FileData.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentCreateResponse.java similarity index 58% rename from fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/FileData.java rename to fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentCreateResponse.java index a17c5c3f0..d2a3d197c 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/FileData.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentCreateResponse.java @@ -18,29 +18,22 @@ */ package org.apache.fineract.infrastructure.documentmanagement.data; -import com.google.common.io.ByteSource; +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; -public class FileData { +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DocumentCreateResponse implements Serializable { - private final String fileName; - private final String contentType; - private final ByteSource byteSource; + @Serial + private static final long serialVersionUID = 1L; - public FileData(final ByteSource byteSource, final String fileName, final String contentType) { - this.fileName = fileName; - this.contentType = contentType; - this.byteSource = byteSource; - } - - public String contentType() { - return this.contentType; - } - - public String name() { - return this.fileName; - } - - public ByteSource getByteSource() { - return this.byteSource; - } + private Long resourceId; + private String resourceIdentifier; } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentData.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentData.java similarity index 59% rename from fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentData.java rename to fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentData.java index ec4879822..3621cd35c 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentData.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentData.java @@ -20,32 +20,28 @@ package org.apache.fineract.infrastructure.documentmanagement.data; import java.io.Serial; import java.io.Serializable; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; -/** - * Immutable data object representing a user document being managed on the platform. - */ -@Getter -@RequiredArgsConstructor +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor public class DocumentData implements Serializable { @Serial private static final long serialVersionUID = 1L; - private final Long id; - private final String parentEntityType; - private final Long parentEntityId; - private final String name; - private final String fileName; - private final Long size; - private final String type; - private final String location; - private final String description; - private final Integer storageType; - - public StorageType storageType() { - return StorageType.fromInt(this.storageType); - } + private Long id; + private String parentEntityType; + private Long parentEntityId; + private String name; + private String fileName; + private Long size; + private String type; + private String location; + private String description; + private Integer storageType; } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentDeleteRequest.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentDeleteRequest.java new file mode 100644 index 000000000..5557cbe36 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentDeleteRequest.java @@ -0,0 +1,46 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.data; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DocumentDeleteRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + private Long id; + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + @Size(max = 50, message = "{org.apache.fineract.document.xxx.not-null}") + private String entityType; + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + private Long entityId; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentDeleteResponse.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentDeleteResponse.java new file mode 100644 index 000000000..59f3858a1 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentDeleteResponse.java @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.data; + +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DocumentDeleteResponse implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Long resourceId; + private String resourceIdentifier; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentUpdateRequest.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentUpdateRequest.java new file mode 100644 index 000000000..2d9a17f49 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentUpdateRequest.java @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.data; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.io.InputStream; +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DocumentUpdateRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + private Long id; + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + @Size(max = 50, message = "{org.apache.fineract.document.xxx.not-null}") + private String entityType; + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + private Long entityId; + @Size(max = 250, message = "{org.apache.fineract.document.xxx.not-null}") + private String name; + @Size(max = 250, message = "{org.apache.fineract.document.xxx.not-null}") + private String description; + @Size(max = 250, message = "{org.apache.fineract.document.xxx.not-null}") + private String fileName; + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + @Min(value = 1, message = "{org.apache.fineract.document.xxx.not-null}") + private Long size; + private String type; + @Hidden + @JsonIgnore + private InputStream stream; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentUpdateResponse.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentUpdateResponse.java new file mode 100644 index 000000000..16a34efe9 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/DocumentUpdateResponse.java @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.data; + +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DocumentUpdateResponse implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Long resourceId; + private String resourceIdentifier; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageCreateRequest.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageCreateRequest.java new file mode 100644 index 000000000..a9f517d0c --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageCreateRequest.java @@ -0,0 +1,61 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.data; + +import static jakarta.validation.constraints.Pattern.Flag.CASE_INSENSITIVE; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import java.io.InputStream; +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ImageCreateRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + @Size(max = 50, message = "{org.apache.fineract.document.xxx.not-null}") + private String entityType; + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + private Long entityId; + @Size(max = 250, message = "{org.apache.fineract.document.xxx.not-null}") + private String fileName; + // @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + @Min(value = 1, message = "{org.apache.fineract.document.xxx.not-null}") + private Long size; + @Pattern(regexp = "^(image\\/gif|image\\/jpeg|image\\/png)$", flags = CASE_INSENSITIVE, message = "{org.apache.fineract.document.xxx.not-null}") + private String type; + @Hidden + @JsonIgnore + private InputStream stream; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageCreateResponse.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageCreateResponse.java new file mode 100644 index 000000000..fea6695ce --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageCreateResponse.java @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.data; + +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ImageCreateResponse implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Long resourceId; + private String resourceIdentifier; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageData.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageData.java deleted file mode 100644 index 18993eb62..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageData.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.data; - -import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils; -import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils.ImageMIMEtype; -import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType; - -public class ImageData { - - private final String location; - private final StorageType storageType; - private final String entityDisplayName; - private final ContentRepositoryUtils.ImageMIMEtype contentType; - - public ImageData(final String location, final StorageType storageType, final String entityDisplayName) { - this.location = location; - this.storageType = storageType; - this.entityDisplayName = entityDisplayName; - this.contentType = ContentRepositoryUtils.ImageMIMEtype - .fromFileExtension(ContentRepositoryUtils.imageExtensionFromFileName(location)); - } - - public ImageMIMEtype contentType() { - return this.contentType; - } - - public StorageType storageType() { - return this.storageType; - } - - public String location() { - return this.location; - } - - public String getEntityDisplayName() { - return this.entityDisplayName; - } -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageDeleteRequest.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageDeleteRequest.java new file mode 100644 index 000000000..7ef53439c --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageDeleteRequest.java @@ -0,0 +1,44 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.data; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ImageDeleteRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + @Size(max = 50, message = "{org.apache.fineract.document.xxx.not-null}") + private String entityType; + @NotNull(message = "{org.apache.fineract.document.xxx.not-null}") + private Long entityId; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageDeleteResponse.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageDeleteResponse.java new file mode 100644 index 000000000..af2430a34 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageDeleteResponse.java @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.data; + +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ImageDeleteResponse implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Long resourceId; + private String resourceIdentifier; +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageResizer.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageResizer.java deleted file mode 100644 index dc6903630..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageResizer.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.data; - -import com.google.common.io.ByteSource; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Optional; -import javax.imageio.ImageIO; -import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils; -import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils.ImageFileExtension; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -@Service -public class ImageResizer { - - private static final Logger LOG = LoggerFactory.getLogger(ImageResizer.class); - - public FileData resize(FileData fileData, Integer maxWidth, Integer maxHeight) { - if (maxWidth == null && maxHeight != null) { - return fileData; - } - try (InputStream is = fileData.getByteSource().openBufferedStream()) { - Optional optResizedIS = resizeImage(ContentRepositoryUtils.imageExtensionFromFileName(fileData.name()), is, - maxWidth != null ? maxWidth : Integer.MAX_VALUE, maxHeight != null ? maxHeight : Integer.MAX_VALUE); - if (optResizedIS.isPresent()) { - FileData resizedImage = new FileData(new ByteSource() { - - @Override - public InputStream openStream() throws IOException { - return optResizedIS.get(); // NOSONAR - } - }, fileData.name(), fileData.contentType()); - return resizedImage; - } - return fileData; - } catch (IOException e) { - LOG.warn("resize() failed, returning original image: {}", e.getMessage(), e); - return fileData; - } - } - - private Optional resizeImage(ImageFileExtension fileExtension, InputStream in, int maxWidth, int maxHeight) - throws IOException { - BufferedImage src = ImageIO.read(in); - if (src.getWidth() <= maxWidth && src.getHeight() <= maxHeight) { - return Optional.empty(); - } - float widthRatio = (float) src.getWidth() / maxWidth; - float heightRatio = (float) src.getHeight() / maxHeight; - float scaleRatio = widthRatio > heightRatio ? widthRatio : heightRatio; - - // TODO(lindahl): Improve compressed image quality (perhaps quality ratio) - - int newWidth = (int) (src.getWidth() / scaleRatio); - int newHeight = (int) (src.getHeight() / scaleRatio); - int colorModel = fileExtension == ContentRepositoryUtils.ImageFileExtension.JPEG ? BufferedImage.TYPE_INT_RGB - : BufferedImage.TYPE_INT_ARGB; - BufferedImage target = new BufferedImage(newWidth, newHeight, colorModel); - Graphics2D g = target.createGraphics(); - g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); - g.drawImage(src, 0, 0, newWidth, newHeight, Color.BLACK, null); - g.dispose(); - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - ImageIO.write(target, fileExtension != null ? fileExtension.getValueWithoutDot() : "jpeg", os); - return Optional.of(new ByteArrayInputStream(os.toByteArray())); - } -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Document.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Document.java index 2e3ea9ecd..6d0a25bd0 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Document.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Document.java @@ -18,150 +18,58 @@ */ package org.apache.fineract.infrastructure.documentmanagement.domain; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Table; -import org.apache.commons.lang3.StringUtils; -import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; -import org.apache.fineract.infrastructure.documentmanagement.command.DocumentCommand; +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; -@Entity -@Table(name = "m_document") -public class Document extends AbstractPersistableCustom { +@Table("m_document") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +@FieldNameConstants +public final class Document implements Serializable { - @Column(name = "parent_entity_type", length = 50) + @Serial + private static final long serialVersionUID = 1L; + + @Id + @Column("id") + private Long id; + + @Column("parent_entity_type") private String parentEntityType; - @Column(name = "parent_entity_id", length = 1000) + @Column("parent_entity_id") private Long parentEntityId; - @Column(name = "name", length = 250) + @Column("name") private String name; - @Column(name = "file_name", length = 250) + @Column("file_name") private String fileName; - @Column(name = "size") + @Column("size") private Long size; - @Column(name = "type", length = 50) + @Column("type") private String type; - @Column(name = "description", length = 1000) + @Column("description") private String description; - @Column(name = "location", length = 500) + @Column("location") private String location; - @Column(name = "storage_type_enum") + @Column("storage_type_enum") private Integer storageType; - - public Document() {} - - public static Document createNew(final String parentEntityType, final Long parentEntityId, final String name, final String fileName, - final Long size, final String type, final String description, final String location, final StorageType storageType) { - return new Document(parentEntityType, parentEntityId, name, fileName, size, type, description, location, storageType); - } - - private Document(final String parentEntityType, final Long parentEntityId, final String name, final String fileName, final Long size, - final String type, final String description, final String location, final StorageType storageType) { - this.parentEntityType = StringUtils.defaultIfEmpty(parentEntityType, null); - this.parentEntityId = parentEntityId; - this.name = StringUtils.defaultIfEmpty(name, null); - this.fileName = StringUtils.defaultIfEmpty(fileName, null); - this.size = size; - this.type = StringUtils.defaultIfEmpty(type, null); - this.description = StringUtils.defaultIfEmpty(description, null); - this.location = StringUtils.defaultIfEmpty(location, null); - this.storageType = storageType.getValue(); - } - - public void update(final DocumentCommand command) { - if (command.isDescriptionChanged()) { - this.description = command.getDescription(); - } - if (command.isFileNameChanged()) { - this.fileName = command.getFileName(); - } - if (command.isFileTypeChanged()) { - this.type = command.getType(); - } - if (command.isLocationChanged()) { - this.location = command.getLocation(); - } - if (command.isNameChanged()) { - this.name = command.getName(); - } - if (command.isSizeChanged()) { - this.size = command.getSize(); - } - } - - public String getParentEntityType() { - return this.parentEntityType; - } - - public void setParentEntityType(final String parentEntityType) { - this.parentEntityType = parentEntityType; - } - - public Long getParentEntityId() { - return this.parentEntityId; - } - - public void setParentEntityId(final Long parentEntityId) { - this.parentEntityId = parentEntityId; - } - - public String getName() { - return this.name; - } - - public void setName(final String name) { - this.name = name; - } - - public String getFileName() { - return this.fileName; - } - - public void setFileName(final String fileName) { - this.fileName = fileName; - } - - public Long getSize() { - return this.size; - } - - public void setSize(final Long size) { - this.size = size; - } - - public String getType() { - return this.type; - } - - public void setType(final String type) { - this.type = type; - } - - public String getDescription() { - return this.description; - } - - public void setDescription(final String description) { - this.description = description; - } - - public String getLocation() { - return this.location; - } - - public void setLocation(final String location) { - this.location = location; - } - - public StorageType storageType() { - return StorageType.fromInt(this.storageType); - } } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/DocumentRepository.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/DocumentRepository.java index 2f4a2b16c..327777663 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/DocumentRepository.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/DocumentRepository.java @@ -18,9 +18,14 @@ */ package org.apache.fineract.infrastructure.documentmanagement.domain; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import java.util.List; +import java.util.Optional; +import org.springframework.data.repository.ListCrudRepository; +import org.springframework.data.repository.query.QueryByExampleExecutor; -public interface DocumentRepository extends JpaRepository, JpaSpecificationExecutor { - // no added behaviour +public interface DocumentRepository extends ListCrudRepository, QueryByExampleExecutor { + + List findAllByParentEntityTypeAndParentEntityId(String parentEntityType, Long parentEntityId); + + Optional findByIdAndParentEntityTypeAndParentEntityId(Long id, String entityType, Long entityId); } diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Image.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Image.java similarity index 51% rename from fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Image.java rename to fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Image.java index 190137a84..90bef819a 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Image.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Image.java @@ -18,44 +18,37 @@ */ package org.apache.fineract.infrastructure.documentmanagement.domain; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Table; -import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; +import java.io.Serial; +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.Accessors; +import lombok.experimental.FieldNameConstants; +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; -@Entity -@Table(name = "m_image") -public final class Image extends AbstractPersistableCustom { +@Table("m_image") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +@FieldNameConstants +public final class Image implements Serializable { - @Column(name = "location", length = 500) + @Serial + private static final long serialVersionUID = 1L; + + @Id + @Column("id") + private Long id; + + @Column("location") private String location; - @Column(name = "storage_type_enum") + @Column("storage_type_enum") private Integer storageType; - - public Image(final String location, final StorageType storageType) { - this.location = location; - this.storageType = storageType.getValue(); - } - - Image() { - - } - - public String getLocation() { - return this.location; - } - - public Integer getStorageType() { - return this.storageType; - } - - public void setLocation(final String location) { - this.location = location; - } - - public void setStorageType(final Integer storageType) { - this.storageType = storageType; - } - } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/ImageRepository.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/ImageRepository.java index fd1e051b1..023216807 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/ImageRepository.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/ImageRepository.java @@ -18,8 +18,7 @@ */ package org.apache.fineract.infrastructure.documentmanagement.domain; -import org.apache.fineract.portfolio.client.domain.Client; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.repository.ListCrudRepository; +import org.springframework.data.repository.query.QueryByExampleExecutor; -public interface ImageRepository extends JpaRepository, JpaSpecificationExecutor {} +public interface ImageRepository extends ListCrudRepository, QueryByExampleExecutor {} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/ContentManagementException.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/ContentManagementException.java deleted file mode 100644 index 7526b870a..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/ContentManagementException.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.exception; - -import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException; - -public class ContentManagementException extends AbstractPlatformDomainRuleException { - - public ContentManagementException(final String filename, final String message) { - super("error.msg.document.save", "Error while manipulating file " + filename + " due to a ContentRepository issue " + message, - filename, message); - } - - public ContentManagementException(final String name, final Long fileSize, final int maxFileSize) { - super("error.msg.document.file.too.big", "Unable to save the document with name" + name + " since its file Size of " - + fileSize / (1024 * 1024) + " MB exceeds the max permissable file size of " + maxFileSize + " MB", name, fileSize); - } - - public ContentManagementException(String filename, String message, Exception exception) { - super("error.msg.document.save", "Error while manipulating file " + filename + " due to a ContentRepository issue " + message, - filename, message, exception); - } -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/InvalidEntityTypeForImageManagementException.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/DocumentInvalidRequestException.java similarity index 70% rename from fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/InvalidEntityTypeForImageManagementException.java rename to fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/DocumentInvalidRequestException.java index cd0e21ee7..702e6c157 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/InvalidEntityTypeForImageManagementException.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/DocumentInvalidRequestException.java @@ -18,14 +18,11 @@ */ package org.apache.fineract.infrastructure.documentmanagement.exception; -import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; +import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException; -/** - * Runtime exception for invalid image types - */ -public class InvalidEntityTypeForImageManagementException extends AbstractPlatformResourceNotFoundException { +public class DocumentInvalidRequestException extends AbstractPlatformDomainRuleException { - public InvalidEntityTypeForImageManagementException(String imageType) { - super("error.imagemanagement.entitytype.invalid", "Image Management is not support for the Entity Type: " + imageType); + public DocumentInvalidRequestException(Exception e) { + super("error.msg.document.request.invalid", e.getMessage(), e); } } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/DocumentNotFoundException.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/DocumentNotFoundException.java index cbe3ced4c..578201f1d 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/DocumentNotFoundException.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/exception/DocumentNotFoundException.java @@ -18,24 +18,16 @@ */ package org.apache.fineract.infrastructure.documentmanagement.exception; -import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; -import org.springframework.dao.EmptyResultDataAccessException; -import software.amazon.awssdk.core.exception.SdkException; +import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException; -public class DocumentNotFoundException extends AbstractPlatformResourceNotFoundException { +public class DocumentNotFoundException extends AbstractPlatformDomainRuleException { + + public DocumentNotFoundException(final Long id) { + super("error.msg.document.id.invalid", "Document with identifier " + id + " does not exist", id); + } public DocumentNotFoundException(final String entityType, final Long entityId, final Long id) { super("error.msg.document.id.invalid", "Document with identifier " + id + " does not exist for the " + entityType + " with Identifier " + entityId, id); } - - public DocumentNotFoundException(String entityType, Long entityId, Long id, EmptyResultDataAccessException e) { - super("error.msg.document.id.invalid", - "Document with identifier " + id + " does not exist for the " + entityType + " with Identifier " + entityId, id, e); - } - - public DocumentNotFoundException(String entityType, Long entityId, Long id, SdkException ace) { - super("error.msg.document.id.invalid", - "Document with identifier " + id + " does not exist for the " + entityType + " with Identifier " + entityId, id, ace); - } } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/DocumentCreateCommandHandler.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/DocumentCreateCommandHandler.java new file mode 100644 index 000000000..3250e214d --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/DocumentCreateCommandHandler.java @@ -0,0 +1,51 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.handler; + +import io.github.resilience4j.retry.annotation.Retry; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.command.core.CommandHandler; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentCreateRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentCreateResponse; +import org.apache.fineract.infrastructure.documentmanagement.service.DocumentWritePlatformService; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Component +@RequiredArgsConstructor +public class DocumentCreateCommandHandler implements CommandHandler { + + private final DocumentWritePlatformService writePlatformService; + + @Retry(name = "commandDocumentCreate", fallbackMethod = "fallback") + @Transactional + @Override + public DocumentCreateResponse handle(final Command command) { + return writePlatformService.createDocument(command.getPayload()); + } + + @Override + public DocumentCreateResponse fallback(Command command, Throwable t) { + // NOTE: fallback method needs to be in the same class + return CommandHandler.super.fallback(command, t); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/DocumentDeleteCommandHandler.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/DocumentDeleteCommandHandler.java new file mode 100644 index 000000000..58d812275 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/DocumentDeleteCommandHandler.java @@ -0,0 +1,51 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.handler; + +import io.github.resilience4j.retry.annotation.Retry; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.command.core.CommandHandler; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentDeleteRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentDeleteResponse; +import org.apache.fineract.infrastructure.documentmanagement.service.DocumentWritePlatformService; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Component +@RequiredArgsConstructor +public class DocumentDeleteCommandHandler implements CommandHandler { + + private final DocumentWritePlatformService writePlatformService; + + @Retry(name = "commandDocumentDelete", fallbackMethod = "fallback") + @Transactional + @Override + public DocumentDeleteResponse handle(final Command command) { + return writePlatformService.deleteDocument(command.getPayload()); + } + + @Override + public DocumentDeleteResponse fallback(Command command, Throwable t) { + // NOTE: fallback method needs to be in the same class + return CommandHandler.super.fallback(command, t); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/DocumentUpdateCommandHandler.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/DocumentUpdateCommandHandler.java new file mode 100644 index 000000000..a55cb5d7e --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/DocumentUpdateCommandHandler.java @@ -0,0 +1,51 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.handler; + +import io.github.resilience4j.retry.annotation.Retry; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.command.core.CommandHandler; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentUpdateRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentUpdateResponse; +import org.apache.fineract.infrastructure.documentmanagement.service.DocumentWritePlatformService; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Component +@RequiredArgsConstructor +public class DocumentUpdateCommandHandler implements CommandHandler { + + private final DocumentWritePlatformService writePlatformService; + + @Retry(name = "commandDocumentUpdate", fallbackMethod = "fallback") + @Transactional + @Override + public DocumentUpdateResponse handle(final Command command) { + return writePlatformService.updateDocument(command.getPayload()); + } + + @Override + public DocumentUpdateResponse fallback(Command command, Throwable t) { + // NOTE: fallback method needs to be in the same class + return CommandHandler.super.fallback(command, t); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/ImageCreateCommandHandler.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/ImageCreateCommandHandler.java new file mode 100644 index 000000000..16eb696c0 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/ImageCreateCommandHandler.java @@ -0,0 +1,51 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.handler; + +import io.github.resilience4j.retry.annotation.Retry; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.command.core.CommandHandler; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageCreateRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageCreateResponse; +import org.apache.fineract.infrastructure.documentmanagement.service.ImageWritePlatformService; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Component +@RequiredArgsConstructor +public class ImageCreateCommandHandler implements CommandHandler { + + private final ImageWritePlatformService writePlatformService; + + @Retry(name = "commandImageCreate", fallbackMethod = "fallback") + @Transactional + @Override + public ImageCreateResponse handle(final Command command) { + return writePlatformService.createImage(command.getPayload()); + } + + @Override + public ImageCreateResponse fallback(Command command, Throwable t) { + // NOTE: fallback method needs to be in the same class + return CommandHandler.super.fallback(command, t); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/ImageDeleteCommandHandler.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/ImageDeleteCommandHandler.java new file mode 100644 index 000000000..b302b433d --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/handler/ImageDeleteCommandHandler.java @@ -0,0 +1,51 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.handler; + +import io.github.resilience4j.retry.annotation.Retry; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.command.core.Command; +import org.apache.fineract.command.core.CommandHandler; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageDeleteRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageDeleteResponse; +import org.apache.fineract.infrastructure.documentmanagement.service.ImageWritePlatformService; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Component +@RequiredArgsConstructor +public class ImageDeleteCommandHandler implements CommandHandler { + + private final ImageWritePlatformService writePlatformService; + + @Retry(name = "commandImageDelete", fallbackMethod = "fallback") + @Transactional + @Override + public ImageDeleteResponse handle(final Command command) { + return writePlatformService.deleteImage(command.getPayload()); + } + + @Override + public ImageDeleteResponse fallback(Command command, Throwable t) { + // NOTE: fallback method needs to be in the same class + return CommandHandler.super.fallback(command, t); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/mapping/DocumentMapper.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/mapping/DocumentMapper.java new file mode 100644 index 000000000..635480d97 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/mapping/DocumentMapper.java @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.mapping; + +import static org.mapstruct.InjectionStrategy.CONSTRUCTOR; +import static org.mapstruct.MappingConstants.ComponentModel.SPRING; + +import java.io.InputStream; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentContent; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData; +import org.apache.fineract.infrastructure.documentmanagement.domain.Document; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(componentModel = SPRING, injectionStrategy = CONSTRUCTOR) +public interface DocumentMapper { + + DocumentData map(Document source); + + @Mapping(source = "source.type", target = "contentType") + @Mapping(source = "source.name", target = "displayName") + @Mapping(source = "source.fileName", target = "fileName") + @Mapping(source = "source.size", target = "size") + @Mapping(ignore = true, target = "format") + @Mapping(source = "stream", target = "stream") + DocumentContent map(Document source, InputStream stream); +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentReadPlatformService.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentReadPlatformService.java index 93e791407..1dab3be03 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentReadPlatformService.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentReadPlatformService.java @@ -19,14 +19,16 @@ package org.apache.fineract.infrastructure.documentmanagement.service; import java.util.List; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentContent; import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData; -import org.apache.fineract.infrastructure.documentmanagement.data.FileData; public interface DocumentReadPlatformService { List retrieveAllDocuments(String entityType, Long entityId); - FileData retrieveFileData(String entityType, Long entityId, Long documentId); + DocumentData retrieveDocument(Long id); + + DocumentContent retrieveDocumentContent(String entityType, Long entityId, Long documentId); DocumentData retrieveDocument(String entityType, Long entityId, Long documentId); diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentReadPlatformServiceImpl.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentReadPlatformServiceImpl.java index 84c4e1260..2437d810f 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentReadPlatformServiceImpl.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentReadPlatformServiceImpl.java @@ -18,108 +18,50 @@ */ package org.apache.fineract.infrastructure.documentmanagement.service; -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.List; import lombok.RequiredArgsConstructor; -import org.apache.fineract.infrastructure.core.domain.JdbcSupport; -import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepository; -import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory; +import org.apache.fineract.infrastructure.contentstore.service.ContentStoreService; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentContent; import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData; -import org.apache.fineract.infrastructure.documentmanagement.data.FileData; +import org.apache.fineract.infrastructure.documentmanagement.domain.DocumentRepository; import org.apache.fineract.infrastructure.documentmanagement.exception.DocumentNotFoundException; -import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; +import org.apache.fineract.infrastructure.documentmanagement.mapping.DocumentMapper; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformService { - private final JdbcTemplate jdbcTemplate; - private final PlatformSecurityContext context; - private final ContentRepositoryFactory contentRepositoryFactory; + private final ContentStoreService storeService; + private final DocumentRepository documentRepository; + private final DocumentMapper documentMapper; @Override public List retrieveAllDocuments(final String entityType, final Long entityId) { + final var docs = documentRepository.findAllByParentEntityTypeAndParentEntityId(entityType, entityId); - this.context.authenticatedUser(); - - // TODO verify if the entities are valid and a user - // has data - // scope for the particular entities - final DocumentMapper mapper = new DocumentMapper(true, true); - final String sql = "select " + mapper.schema() + " order by d.id"; - return this.jdbcTemplate.query(sql, mapper, new Object[] { entityType, entityId }); // NOSONAR + return docs.stream().map(documentMapper::map).toList(); } @Override - public FileData retrieveFileData(final String entityType, final Long entityId, final Long documentId) { - try { - final DocumentMapper mapper = new DocumentMapper(false, false); - final DocumentData documentData = fetchDocumentDetails(entityType, entityId, documentId, mapper); - final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(documentData.storageType()); - return contentRepository.fetchFile(documentData); - } catch (final EmptyResultDataAccessException e) { - throw new DocumentNotFoundException(entityType, entityId, documentId, e); - } + public DocumentData retrieveDocument(final Long id) { + return documentRepository.findById(id).map(documentMapper::map).orElseThrow(() -> new DocumentNotFoundException(id)); + } + + @Override + public DocumentContent retrieveDocumentContent(final String entityType, final Long entityId, final Long documentId) { + final var doc = documentRepository.findByIdAndParentEntityTypeAndParentEntityId(documentId, entityType, entityId) + .orElseThrow(() -> new DocumentNotFoundException(entityType, entityId, documentId)); + final var is = storeService.download(doc.getLocation()); + + return documentMapper.map(doc, is); } @Override public DocumentData retrieveDocument(final String entityType, final Long entityId, final Long documentId) { - try { - final DocumentMapper mapper = new DocumentMapper(true, true); - return fetchDocumentDetails(entityType, entityId, documentId, mapper); - } catch (final EmptyResultDataAccessException e) { - throw new DocumentNotFoundException(entityType, entityId, documentId, e); - } - } + final var doc = documentRepository.findByIdAndParentEntityTypeAndParentEntityId(documentId, entityType, entityId) + .orElseThrow(() -> new DocumentNotFoundException(entityType, entityId, documentId)); - private DocumentData fetchDocumentDetails(final String entityType, final Long entityId, final Long documentId, - final DocumentMapper mapper) { - final String sql = "select " + mapper.schema() + " and d.id=? "; - return this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { entityType, entityId, documentId }); // NOSONAR - } - - private static final class DocumentMapper implements RowMapper { - - private final boolean hideLocation; - private final boolean hideStorageType; - - DocumentMapper(final boolean hideLocation, final boolean hideStorageType) { - this.hideLocation = hideLocation; - this.hideStorageType = hideStorageType; - } - - public String schema() { - return "d.id as id, d.parent_entity_type as parentEntityType, d.parent_entity_id as parentEntityId, d.name as name, " - + " d.file_name as fileName, d.size as fileSize, d.type as fileType, " - + " d.description as description, d.location as location," + " d.storage_type_enum as storageType" - + " from m_document d where d.parent_entity_type=? and d.parent_entity_id=?"; - } - - @Override - public DocumentData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - final Long id = JdbcSupport.getLong(rs, "id"); - final Long parentEntityId = JdbcSupport.getLong(rs, "parentEntityId"); - final Long fileSize = JdbcSupport.getLong(rs, "fileSize"); - final String parentEntityType = rs.getString("parentEntityType"); - final String name = rs.getString("name"); - final String fileName = rs.getString("fileName"); - final String fileType = rs.getString("fileType"); - final String description = rs.getString("description"); - String location = null; - Integer storageType = null; - if (!this.hideLocation) { - location = rs.getString("location"); - } - if (!this.hideStorageType) { - storageType = rs.getInt("storageType"); - } - return new DocumentData(id, parentEntityType, parentEntityId, name, fileName, fileSize, fileType, location, description, - storageType); - } + return documentMapper.map(doc); } } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformService.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformService.java index 807a8d977..d583fe872 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformService.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformService.java @@ -18,24 +18,18 @@ */ package org.apache.fineract.infrastructure.documentmanagement.service; -import java.io.InputStream; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; -import org.apache.fineract.infrastructure.documentmanagement.command.DocumentCommand; -import org.springframework.security.access.prepost.PreAuthorize; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentCreateRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentCreateResponse; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentDeleteRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentDeleteResponse; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentUpdateRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentUpdateResponse; public interface DocumentWritePlatformService { - @PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'CREATE_DOCUMENT')") - Long createDocument(DocumentCommand documentCommand, InputStream inputStream); + DocumentCreateResponse createDocument(DocumentCreateRequest request); - @PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'UPDATE_DOCUMENT')") - CommandProcessingResult updateDocument(DocumentCommand documentCommand, InputStream inputStream); - - @PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'DELETE_DOCUMENT')") - CommandProcessingResult deleteDocument(DocumentCommand documentCommand); - - @PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'CREATE_DOCUMENT')") - Long createInternalDocument(String entityType, Long entityId, Long fileSize, InputStream inputStream, String mimeType, String name, - String description, String fileName); + DocumentUpdateResponse updateDocument(DocumentUpdateRequest request); + DocumentDeleteResponse deleteDocument(DocumentDeleteRequest request); } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceImpl.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceImpl.java new file mode 100644 index 000000000..576781d6c --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceImpl.java @@ -0,0 +1,175 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.service; + +import static java.util.Objects.requireNonNull; + +import jakarta.validation.Valid; +import java.util.Objects; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; +import org.apache.fineract.infrastructure.contentstore.service.ContentStoreService; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.apache.fineract.infrastructure.core.exception.ErrorHandler; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentCreateRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentCreateResponse; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentDeleteRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentDeleteResponse; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentUpdateRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentUpdateResponse; +import org.apache.fineract.infrastructure.documentmanagement.domain.Document; +import org.apache.fineract.infrastructure.documentmanagement.domain.DocumentRepository; +import org.apache.fineract.infrastructure.documentmanagement.exception.DocumentNotFoundException; +import org.apache.fineract.infrastructure.documentmanagement.mapping.DocumentMapper; +import org.apache.fineract.infrastructure.event.business.domain.document.DocumentCreatedBusinessEvent; +import org.apache.fineract.infrastructure.event.business.domain.document.DocumentDeletedBusinessEvent; +import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@RequiredArgsConstructor +@Service +public class DocumentWritePlatformServiceImpl implements DocumentWritePlatformService { + + private static final String STORE_PREFIX = "documents"; + + private final DocumentRepository documentRepository; + private final DocumentMapper documentMapper; + private final ContentStoreService storeService; + private final BusinessEventNotifierService businessEventNotifierService; + private final FineractProperties properties; + + @Transactional + @Override + public DocumentCreateResponse createDocument(@Valid final DocumentCreateRequest request) { + try { + requireNonNull(request, "Request parameter required"); + requireNonNull(request.getFileName(), "File name parameter required"); + requireNonNull(request.getStream(), "Document content required"); + + // TODO: make "prefix" configurable + var path = getPath(STORE_PREFIX, request.getEntityType(), request.getEntityId(), request.getFileName(), + storeService.getDelimiter()); + + path = storeService.upload(path, request.getStream(), request.getType()); + + final var doc = new Document().setParentEntityType(request.getEntityType()).setParentEntityId(request.getEntityId()) + .setName(Optional.ofNullable(request.getName()).orElse(request.getFileName())).setFileName(request.getFileName()) + .setSize(request.getSize()).setType(request.getType()).setDescription(request.getDescription()).setLocation(path) + .setStorageType(storeService.getType().getValue()); + + documentRepository.save(doc); + + businessEventNotifierService.notifyPostBusinessEvent(new DocumentCreatedBusinessEvent(documentMapper.map(doc))); + + return DocumentCreateResponse.builder().resourceId(doc.getId()).resourceIdentifier(request.getEntityType()).build(); + } catch (final Exception e) { + throw ErrorHandler.getMappable(e, "error.msg.document.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); + } + } + + @Transactional + @Override + public DocumentUpdateResponse updateDocument(@Valid final DocumentUpdateRequest request) { + try { + requireNonNull(request, "Request parameter required"); + + String path = null; + + if (StringUtils.isNotEmpty(request.getFileName())) { + // TODO: make "prefix" configurable + path = getPath(STORE_PREFIX, request.getEntityType(), request.getEntityId(), request.getFileName(), + storeService.getDelimiter()); + } + + final var doc = this.documentRepository.findById(request.getId()) + .orElseThrow(() -> new DocumentNotFoundException(request.getEntityType(), request.getEntityId(), request.getId())); + + doc.setStorageType(storeService.getType().getValue()); + + if (StringUtils.isNotEmpty(request.getFileName())) { + // these two only make sense if we have an actual file + + if (request.getStream() != null && StringUtils.isNotEmpty(path) && !Strings.CI.equals(doc.getLocation(), path)) { + storeService.delete(doc.getLocation()); + storeService.upload(path, request.getStream(), request.getType()); + doc.setLocation(path); + doc.setFileName(FilenameUtils.getName(path)); + } + } else if (request.getStream() != null) { + storeService.upload(doc.getLocation(), request.getStream(), request.getType()); + } + if (StringUtils.isNotEmpty(request.getDescription()) && !Strings.CI.equals(doc.getDescription(), request.getDescription())) { + doc.setDescription(request.getDescription()); + } + if (StringUtils.isNotEmpty(request.getName()) && !Strings.CI.equals(doc.getName(), request.getName())) { + doc.setName(request.getName()); + } + if (Objects.requireNonNullElse(request.getSize(), 0L) > 1L && !Objects.equals(doc.getSize(), request.getSize())) { + doc.setSize(request.getSize()); + } + + documentRepository.save(doc); + + // TODO: shouldn't we send a business event? + // businessEventNotifierService.notifyPostBusinessEvent(new DocumentUpdateBusinessEvent(doc)); + + return DocumentUpdateResponse.builder().resourceId(doc.getId()).resourceIdentifier(request.getEntityType()).build(); + } catch (final Exception e) { + throw ErrorHandler.getMappable(e, "error.msg.document.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); + } + } + + @Transactional + @Override + public DocumentDeleteResponse deleteDocument(@Valid final DocumentDeleteRequest request) { + try { + final var doc = this.documentRepository.findById(request.getId()) + .orElseThrow(() -> new DocumentNotFoundException(request.getEntityType(), request.getEntityId(), request.getId())); + + storeService.delete(doc.getLocation()); + + documentRepository.deleteById(request.getId()); + + businessEventNotifierService.notifyPostBusinessEvent(new DocumentDeletedBusinessEvent(documentMapper.map(doc))); + + return DocumentDeleteResponse.builder().resourceId(doc.getId()).resourceIdentifier(request.getEntityType()).build(); + } catch (final Exception e) { + throw ErrorHandler.getMappable(e, "error.msg.document.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); + } + } + + private String getPath(final String prefix, final String entityType, final Long entityId, final String fileName, String delimiter) { + requireNonNull(prefix); + requireNonNull(entityType); + requireNonNull(entityId); + requireNonNull(fileName); + requireNonNull(delimiter); + + return String.join(delimiter, prefix, entityType, String.valueOf(entityId), fileName); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java deleted file mode 100644 index 0ae4f5998..000000000 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/DocumentWritePlatformServiceJpaRepositoryImpl.java +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.fineract.infrastructure.documentmanagement.service; - -import java.io.InputStream; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; -import org.apache.fineract.infrastructure.core.exception.ErrorHandler; -import org.apache.fineract.infrastructure.documentmanagement.command.DocumentCommand; -import org.apache.fineract.infrastructure.documentmanagement.command.DocumentCommandValidator; -import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepository; -import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory; -import org.apache.fineract.infrastructure.documentmanagement.domain.Document; -import org.apache.fineract.infrastructure.documentmanagement.domain.DocumentRepository; -import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType; -import org.apache.fineract.infrastructure.documentmanagement.exception.ContentManagementException; -import org.apache.fineract.infrastructure.documentmanagement.exception.DocumentNotFoundException; -import org.apache.fineract.infrastructure.documentmanagement.exception.InvalidEntityTypeForDocumentManagementException; -import org.apache.fineract.infrastructure.event.business.domain.document.DocumentCreatedBusinessEvent; -import org.apache.fineract.infrastructure.event.business.domain.document.DocumentDeletedBusinessEvent; -import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService; -import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.orm.jpa.JpaSystemException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWritePlatformService { - - private static final Logger LOG = LoggerFactory.getLogger(DocumentWritePlatformServiceJpaRepositoryImpl.class); - - private final PlatformSecurityContext context; - private final DocumentRepository documentRepository; - private final ContentRepositoryFactory contentRepositoryFactory; - private final BusinessEventNotifierService businessEventNotifierService; - - @Autowired - public DocumentWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final DocumentRepository documentRepository, - final ContentRepositoryFactory documentStoreFactory, BusinessEventNotifierService businessEventNotifierService) { - this.context = context; - this.documentRepository = documentRepository; - this.contentRepositoryFactory = documentStoreFactory; - this.businessEventNotifierService = businessEventNotifierService; - } - - @Transactional - @Override - public Long createDocument(final DocumentCommand documentCommand, final InputStream inputStream) { - try { - this.context.authenticatedUser(); - - final DocumentCommandValidator validator = new DocumentCommandValidator(documentCommand); - - validateParentEntityType(documentCommand); - - validator.validateForCreate(); - - final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(); - - final String fileLocation = contentRepository.saveFile(inputStream, documentCommand); - - final Document document = Document.createNew(documentCommand.getParentEntityType(), documentCommand.getParentEntityId(), - documentCommand.getName(), documentCommand.getFileName(), documentCommand.getSize(), documentCommand.getType(), - documentCommand.getDescription(), fileLocation, contentRepository.getStorageType()); - - this.documentRepository.saveAndFlush(document); - businessEventNotifierService.notifyPostBusinessEvent(new DocumentCreatedBusinessEvent(document)); - - return document.getId(); - } catch (final JpaSystemException | DataIntegrityViolationException dve) { - LOG.error("Error occured.", dve); - throw ErrorHandler.getMappable(dve, "error.msg.document.unknown.data.integrity.issue", - "Unknown data integrity issue with resource."); - } - } - - @Transactional - @Override - public Long createInternalDocument(final String entityType, final Long entityId, final Long fileSize, final InputStream inputStream, - final String mimeType, final String name, final String description, final String fileName) { - - final DocumentCommand documentCommand = new DocumentCommand(null, null, entityType, entityId, name, fileName, fileSize, mimeType, - description, null); - - return createDocument(documentCommand, inputStream); - - } - - @Transactional - @Override - public CommandProcessingResult updateDocument(final DocumentCommand documentCommand, final InputStream inputStream) { - try { - this.context.authenticatedUser(); - - String oldLocation = null; - final DocumentCommandValidator validator = new DocumentCommandValidator(documentCommand); - validator.validateForUpdate(); - // TODO check if entity id is valid and within data scope for the - // user - final Document documentForUpdate = this.documentRepository.findById(documentCommand.getId()) - .orElseThrow(() -> new DocumentNotFoundException(documentCommand.getParentEntityType(), - documentCommand.getParentEntityId(), documentCommand.getId())); - - final StorageType documentStoreType = documentForUpdate.storageType(); - oldLocation = documentForUpdate.getLocation(); - if (inputStream != null && documentCommand.isFileNameChanged()) { - final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(); - documentCommand.setLocation(contentRepository.saveFile(inputStream, documentCommand)); - documentCommand.setStorageType(contentRepository.getStorageType().getValue()); - } - - documentForUpdate.update(documentCommand); - - if (inputStream != null && documentCommand.isFileNameChanged()) { - final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(documentStoreType); - contentRepository.deleteFile(oldLocation); - } - - this.documentRepository.saveAndFlush(documentForUpdate); - - return CommandProcessingResult.resourceResult(documentForUpdate.getId()); - } catch (final JpaSystemException | DataIntegrityViolationException dve) { - LOG.error("Error occured.", dve); - throw ErrorHandler.getMappable(dve, "error.msg.document.unknown.data.integrity.issue", - "Unknown data integrity issue with resource."); - } catch (final ContentManagementException cme) { - LOG.error("Error occured.", cme); - throw new ContentManagementException(documentCommand.getName(), cme.getMessage(), cme); - } - } - - @Transactional - @Override - public CommandProcessingResult deleteDocument(final DocumentCommand documentCommand) { - this.context.authenticatedUser(); - - validateParentEntityType(documentCommand); - // TODO: Check document is present under this entity Id - final Document document = this.documentRepository.findById(documentCommand.getId()) - .orElseThrow(() -> new DocumentNotFoundException(documentCommand.getParentEntityType(), documentCommand.getParentEntityId(), - documentCommand.getId())); - this.documentRepository.delete(document); - - final ContentRepository contentRepository = this.contentRepositoryFactory.getRepository(document.storageType()); - contentRepository.deleteFile(document.getLocation()); - businessEventNotifierService.notifyPostBusinessEvent(new DocumentDeletedBusinessEvent(document)); - return CommandProcessingResult.resourceResult(document.getId()); - } - - private void validateParentEntityType(final DocumentCommand documentCommand) { - if (!checkValidEntityType(documentCommand.getParentEntityType())) { - throw new InvalidEntityTypeForDocumentManagementException(documentCommand.getParentEntityType()); - } - } - - private static boolean checkValidEntityType(final String entityType) { - for (final DocumentManagementEntity entities : DocumentManagementEntity.values()) { - if (entities.name().equalsIgnoreCase(entityType)) { - return true; - } - } - return false; - } - - /*** Entities for document Management **/ - public enum DocumentManagementEntity { - - CLIENTS, // - CLIENT_IDENTIFIERS, // - STAFF, // - LOANS, // - SAVINGS, // - GROUPS, // - IMPORT; // - - @Override - public String toString() { - return name().toLowerCase(); - } - } -} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageReadPlatformService.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageReadPlatformService.java index 608f64762..9684e77e8 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageReadPlatformService.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageReadPlatformService.java @@ -18,10 +18,10 @@ */ package org.apache.fineract.infrastructure.documentmanagement.service; -import org.apache.fineract.infrastructure.documentmanagement.data.FileData; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentContent; public interface ImageReadPlatformService { - FileData retrieveImage(String entityType, Long entityId); + DocumentContent retrieveImage(String entityType, Long entityId); } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageReadPlatformServiceImpl.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageReadPlatformServiceImpl.java new file mode 100644 index 000000000..056a11122 --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageReadPlatformServiceImpl.java @@ -0,0 +1,69 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.service; + +import java.util.List; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.apache.fineract.infrastructure.contentstore.detector.ContentDetectorContext; +import org.apache.fineract.infrastructure.contentstore.detector.ContentDetectorManager; +import org.apache.fineract.infrastructure.contentstore.service.ContentStoreService; +import org.apache.fineract.infrastructure.documentmanagement.adapter.EntityImageIdAdapter; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentContent; +import org.apache.fineract.infrastructure.documentmanagement.domain.ImageRepository; +import org.apache.fineract.infrastructure.documentmanagement.exception.DocumentInvalidRequestException; +import org.apache.fineract.infrastructure.documentmanagement.exception.DocumentNotFoundException; +import org.springframework.stereotype.Service; + +@Slf4j +@RequiredArgsConstructor +@Service +public class ImageReadPlatformServiceImpl implements ImageReadPlatformService { + + @Deprecated + private final List imageIdAdapters; + private final ContentStoreService storeService; + private final ImageRepository imageRepository; + private final ContentDetectorManager contentDetectorManager; + + @Override + public DocumentContent retrieveImage(final String entityType, final Long entityId) { + try { + return imageIdAdapters.stream().filter(imageIdAdapter -> imageIdAdapter.accept(entityType)).findFirst() + .flatMap(imageIdAdapter -> imageIdAdapter.get(entityId)) + .flatMap( + imageIdResult -> imageRepository.findById(imageIdResult.getId()) + .map(image -> DocumentContent + .builder().fileName( + FilenameUtils.getName(image.getLocation())) + .format(FilenameUtils.getExtension(image.getLocation())) + .displayName(imageIdResult.getDisplayName()) + .contentType( + contentDetectorManager + .detect(ContentDetectorContext.builder() + .fileName(FilenameUtils.getName(image.getLocation())).build()) + .getMimeType()) + .stream(storeService.download(image.getLocation())).build())) + .orElseThrow(() -> new DocumentNotFoundException(entityType, entityId, -1L)); + } catch (final Exception e) { + throw new DocumentInvalidRequestException(e); + } + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformService.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformService.java index 4b30b59b6..f976338ff 100755 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformService.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformService.java @@ -18,19 +18,14 @@ */ package org.apache.fineract.infrastructure.documentmanagement.service; -import java.io.InputStream; -import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; -import org.apache.fineract.infrastructure.core.domain.Base64EncodedImage; -import org.springframework.security.access.prepost.PreAuthorize; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageCreateRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageCreateResponse; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageDeleteRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageDeleteResponse; public interface ImageWritePlatformService { - @PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE','CREATE_STAFFIMAGE')") - CommandProcessingResult saveOrUpdateImage(String entityName, Long entityId, String imageName, InputStream inputStream, Long fileSize); + ImageCreateResponse createImage(ImageCreateRequest request); - @PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'CREATE_CLIENTIMAGE','CREATE_STAFFIMAGE')") - CommandProcessingResult saveOrUpdateImage(String entityName, Long entityId, Base64EncodedImage encodedImage); - - @PreAuthorize(value = "hasAnyAuthority('ALL_FUNCTIONS', 'DELETE_CLIENTIMAGE','DELETE_STAFFIMAGE')") - CommandProcessingResult deleteImage(String entityName, Long entityId); + ImageDeleteResponse deleteImage(ImageDeleteRequest request); } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformServiceImpl.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformServiceImpl.java new file mode 100644 index 000000000..1538788be --- /dev/null +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/documentmanagement/service/ImageWritePlatformServiceImpl.java @@ -0,0 +1,147 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.documentmanagement.service; + +import static java.util.Objects.requireNonNull; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.fineract.infrastructure.contentstore.detector.ContentDetectorContext; +import org.apache.fineract.infrastructure.contentstore.detector.ContentDetectorManager; +import org.apache.fineract.infrastructure.contentstore.service.ContentStoreService; +import org.apache.fineract.infrastructure.documentmanagement.adapter.EntityImageIdAdapter; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageCreateRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageCreateResponse; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageDeleteRequest; +import org.apache.fineract.infrastructure.documentmanagement.data.ImageDeleteResponse; +import org.apache.fineract.infrastructure.documentmanagement.domain.Image; +import org.apache.fineract.infrastructure.documentmanagement.domain.ImageRepository; +import org.apache.fineract.infrastructure.documentmanagement.exception.DocumentInvalidRequestException; +import org.apache.fineract.infrastructure.documentmanagement.exception.DocumentNotFoundException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@RequiredArgsConstructor +@Service +public class ImageWritePlatformServiceImpl implements ImageWritePlatformService { + + private static final String STORE_PREFIX = "images"; + private static final String DEFAULT_ENTITY_TYPE = "clients"; + private static final String DEFAULT_EXTENSION = ".jpg"; + + @Deprecated + private final List imageIdAdapters; + private final ContentStoreService storeService; + private final ImageRepository imageRepository; + private final ContentDetectorManager contentDetectorManager; + + @Transactional + @Override + public ImageCreateResponse createImage(final ImageCreateRequest request) { + try { + if (StringUtils.isEmpty(request.getEntityType())) { + // TODO: keeping the path segment always "clients" not consistent how this works with documents + request.setEntityType(DEFAULT_ENTITY_TYPE); + } + + if (StringUtils.isEmpty(request.getFileName())) { + // NOTE: defacto limiting the uploads to JPEG files, same behavior as before + request.setFileName(UUID.randomUUID() + DEFAULT_EXTENSION); + } + + if (StringUtils.isEmpty(request.getType())) { + final var type = Optional + .of(contentDetectorManager.detect(ContentDetectorContext.builder().fileName(request.getFileName()).build())) + .filter(contentDetectorContext -> StringUtils.isNotEmpty(contentDetectorContext.getMimeType())) + .filter(contentDetectorContext -> !APPLICATION_OCTET_STREAM_VALUE + .equalsIgnoreCase(contentDetectorContext.getMimeType())) + .map(ContentDetectorContext::getMimeType).orElse(APPLICATION_OCTET_STREAM_VALUE); + + request.setType(type); + } + + // TODO: make "prefix" configurable? + var path = getPath(STORE_PREFIX, request.getEntityType(), request.getEntityId(), request.getFileName(), + storeService.getDelimiter()); + + final var imagePath = storeService.upload(path, request.getStream(), request.getType()); + + final var result = imageIdAdapters.stream().filter(imageIdAdapter -> imageIdAdapter.accept(request.getEntityType())).findFirst() + .flatMap(imageIdAdapter -> imageIdAdapter.get(request.getEntityId())) + .flatMap(imageIdResult -> imageRepository.findById(imageIdResult.getId())).map(image -> { + // delete old image + storeService.delete(image.getLocation()); + + return image; + }).or(() -> Optional.of(new Image())) + .map(image -> image.setLocation(imagePath).setStorageType(storeService.getType().getValue())).map(imageRepository::save) + .map(image -> ImageCreateResponse.builder().resourceId(image.getId()).build()); + + imageIdAdapters.stream().filter(imageIdAdapter -> imageIdAdapter.accept(request.getEntityType())).findFirst() + .ifPresent(imageIdAdapter -> result.ifPresent( + imageCreateResponse -> imageIdAdapter.set(request.getEntityId(), imageCreateResponse.getResourceId()))); + + return result.orElseThrow(() -> new DocumentNotFoundException(request.getEntityType(), request.getEntityId(), -1L)); + } catch (final Exception e) { + throw new DocumentInvalidRequestException(e); + } + } + + @Transactional + @Override + public ImageDeleteResponse deleteImage(final ImageDeleteRequest request) { + try { + return delete(request.getEntityType(), request.getEntityId()) + .orElseThrow(() -> new DocumentNotFoundException(request.getEntityType(), request.getEntityId(), -1L)); + } catch (final Exception e) { + throw new DocumentInvalidRequestException(e); + } + } + + private Optional delete(final String entityType, final Long entityId) { + return imageIdAdapters.stream().filter(imageIdAdapter -> imageIdAdapter.accept(entityType)).findFirst() + .flatMap(imageIdAdapter -> imageIdAdapter.set(entityId, null)) + .flatMap(imageIdResult -> imageRepository.findById(imageIdResult.getId())).map(image -> { + requireNonNull(image.getId(), "Image ID required"); + requireNonNull(image.getLocation(), "Image location required"); + + storeService.delete(image.getLocation()); + + imageRepository.deleteById(image.getId()); + + return ImageDeleteResponse.builder().resourceId(entityId).resourceIdentifier(entityType).build(); + }); + } + + private String getPath(final String prefix, final String entityType, final Long entityId, final String fileName, String delimiter) { + requireNonNull(prefix); + requireNonNull(entityType); + requireNonNull(entityId); + requireNonNull(fileName); + requireNonNull(delimiter); + + return String.join(delimiter, prefix, entityType, String.valueOf(entityId), fileName); + } +} diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentBusinessEvent.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentBusinessEvent.java index dc0aca7d4..0993476dc 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentBusinessEvent.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentBusinessEvent.java @@ -18,14 +18,14 @@ */ package org.apache.fineract.infrastructure.event.business.domain.document; -import org.apache.fineract.infrastructure.documentmanagement.domain.Document; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData; import org.apache.fineract.infrastructure.event.business.domain.AbstractBusinessEvent; -public abstract class DocumentBusinessEvent extends AbstractBusinessEvent { +public abstract class DocumentBusinessEvent extends AbstractBusinessEvent { private static final String CATEGORY = "Document"; - protected DocumentBusinessEvent(Document value) { + protected DocumentBusinessEvent(DocumentData value) { super(value); } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentCreatedBusinessEvent.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentCreatedBusinessEvent.java index b323857e7..1c9c5bb9b 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentCreatedBusinessEvent.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentCreatedBusinessEvent.java @@ -18,13 +18,13 @@ */ package org.apache.fineract.infrastructure.event.business.domain.document; -import org.apache.fineract.infrastructure.documentmanagement.domain.Document; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData; public class DocumentCreatedBusinessEvent extends DocumentBusinessEvent { private static final String TYPE = "DocumentCreatedBusinessEvent"; - public DocumentCreatedBusinessEvent(Document value) { + public DocumentCreatedBusinessEvent(DocumentData value) { super(value); } diff --git a/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentDeletedBusinessEvent.java b/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentDeletedBusinessEvent.java index 14184b59e..fb2d4c47e 100644 --- a/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentDeletedBusinessEvent.java +++ b/fineract-document/src/main/java/org/apache/fineract/infrastructure/event/business/domain/document/DocumentDeletedBusinessEvent.java @@ -18,13 +18,13 @@ */ package org.apache.fineract.infrastructure.event.business.domain.document; -import org.apache.fineract.infrastructure.documentmanagement.domain.Document; +import org.apache.fineract.infrastructure.documentmanagement.data.DocumentData; public class DocumentDeletedBusinessEvent extends DocumentBusinessEvent { private static final String TYPE = "DocumentDeletedBusinessEvent"; - public DocumentDeletedBusinessEvent(Document value) { + public DocumentDeletedBusinessEvent(DocumentData value) { super(value); } diff --git a/fineract-document/src/main/resources/jpa/static-weaving/module/fineract-document/persistence.xml b/fineract-document/src/main/resources/jpa/static-weaving/module/fineract-document/persistence.xml deleted file mode 100644 index 7b0325007..000000000 --- a/fineract-document/src/main/resources/jpa/static-weaving/module/fineract-document/persistence.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - org.eclipse.persistence.jpa.PersistenceProvider - - - org.apache.fineract.useradministration.domain.Role - org.apache.fineract.portfolio.fund.domain.Fund - org.apache.fineract.infrastructure.documentmanagement.domain.Image - org.apache.fineract.organisation.workingdays.domain.WorkingDays - org.apache.fineract.useradministration.domain.Permission - org.apache.fineract.useradministration.domain.AppUserClientMapping - org.apache.fineract.commands.domain.CommandSource - org.apache.fineract.useradministration.domain.AppUser - org.apache.fineract.accounting.glaccount.domain.GLAccount - org.apache.fineract.organisation.monetary.domain.OrganisationCurrency - org.apache.fineract.organisation.staff.domain.Staff - org.apache.fineract.portfolio.rate.domain.Rate - org.apache.fineract.organisation.monetary.domain.ApplicationCurrency - org.apache.fineract.portfolio.calendar.domain.CalendarInstance - org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail - org.apache.fineract.portfolio.calendar.domain.Calendar - org.apache.fineract.portfolio.calendar.domain.CalendarHistory - org.apache.fineract.portfolio.client.domain.ClientIdentifier - org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucket - org.apache.fineract.portfolio.delinquency.domain.DelinquencyRange - org.apache.fineract.portfolio.group.domain.StaffAssignmentHistory - org.apache.fineract.portfolio.group.domain.Group - org.apache.fineract.portfolio.client.domain.Client - org.apache.fineract.infrastructure.event.external.repository.domain.ExternalEventConfiguration - org.apache.fineract.portfolio.group.domain.GroupRole - org.apache.fineract.portfolio.paymenttype.domain.PaymentType - org.apache.fineract.portfolio.group.domain.GroupLevel - org.apache.fineract.infrastructure.event.external.repository.domain.ExternalEvent - org.apache.fineract.organisation.office.domain.Office - org.apache.fineract.organisation.holiday.domain.Holiday - org.apache.fineract.infrastructure.cache.domain.PlatformCache - org.apache.fineract.infrastructure.codes.domain.Code - org.apache.fineract.infrastructure.businessdate.domain.BusinessDate - org.apache.fineract.infrastructure.codes.domain.CodeValue - - - org.apache.fineract.infrastructure.documentmanagement.domain.Document - - false - - - - - diff --git a/fineract-document/src/test/java/org/apache/fineract/infrastructure/TestConfiguration.java b/fineract-document/src/test/java/org/apache/fineract/infrastructure/TestConfiguration.java new file mode 100644 index 000000000..32cafe977 --- /dev/null +++ b/fineract-document/src/test/java/org/apache/fineract/infrastructure/TestConfiguration.java @@ -0,0 +1,44 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure; + +import static org.apache.fineract.infrastructure.contentstore.processor.ContentProcessor.BEAN_NAME_EXECUTOR; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +@Configuration +@EnableConfigurationProperties({ FineractProperties.class }) +@PropertySource("classpath:application-test.properties") +@ComponentScan({ "org.apache.fineract.infrastructure.contentstore.util", "org.apache.fineract.infrastructure.contentstore.detector", + "org.apache.fineract.infrastructure.contentstore.processor", "org.apache.fineract.infrastructure.contentstore.policy", + "org.apache.fineract.infrastructure.contentstore.service" }) +public class TestConfiguration { + + @Bean(BEAN_NAME_EXECUTOR) + public ExecutorService contentProcessorExecutor() { + return Executors.newCachedThreadPool(); + } +} diff --git a/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/detector/FileContentDetectorTest.java b/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/detector/FileContentDetectorTest.java new file mode 100644 index 000000000..1c6830828 --- /dev/null +++ b/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/detector/FileContentDetectorTest.java @@ -0,0 +1,52 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.detector; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.TestConfiguration; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@Slf4j +@SpringBootTest +@ContextConfiguration(classes = TestConfiguration.class) +class FileContentDetectorTest { + + @Autowired + private FileContentDetector fileContentDetector; + + @Test + void detectByFileName() { + var ctx = fileContentDetector.detect(ContentDetectorContext.builder().fileName("test.png").build()); + + assertEquals("png", ctx.getFormat()); + assertEquals(".png", ctx.getExtension()); + assertEquals("image/png", ctx.getMimeType()); + + ctx = fileContentDetector.detect(ContentDetectorContext.builder().fileName("test.jpg").build()); + + assertEquals("jpg", ctx.getFormat()); + assertEquals(".jpg", ctx.getExtension()); + assertEquals("image/jpeg", ctx.getMimeType()); + } +} diff --git a/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/detector/TikaContentDetectorTest.java b/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/detector/TikaContentDetectorTest.java new file mode 100644 index 000000000..d283c6806 --- /dev/null +++ b/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/detector/TikaContentDetectorTest.java @@ -0,0 +1,134 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.detector; + +import static com.github.romankh3.image.comparison.model.ImageComparisonState.MATCH; +import static java.util.Objects.requireNonNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.github.romankh3.image.comparison.ImageComparison; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import javax.imageio.ImageIO; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.apache.fineract.infrastructure.TestConfiguration; +import org.apache.fineract.infrastructure.contentstore.exception.ContentDetectorException; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@Slf4j +@SpringBootTest +@ContextConfiguration(classes = TestConfiguration.class) +class TikaContentDetectorTest { + + @Autowired + private TikaContentDetector tikaContentDetector; + + @Test + void detectByFileName() { + var ctx = tikaContentDetector.detect(ContentDetectorContext.builder().fileName("test.png").build()); + + assertEquals("png", ctx.getFormat()); + assertEquals(".png", ctx.getExtension()); + assertEquals("image/png", ctx.getMimeType()); + + ctx = tikaContentDetector.detect(ContentDetectorContext.builder().fileName("test.jpg").build()); + + assertEquals("jpg", ctx.getFormat()); + assertEquals(".jpg", ctx.getExtension()); + assertEquals("image/jpeg", ctx.getMimeType()); + } + + @Test + void detectByInputStream() { + var ctx = tikaContentDetector.detect( + ContentDetectorContext.builder().inputStream(TikaContentDetectorTest.class.getClassLoader().getResourceAsStream("test.png")) + .inputStreamEnabled(true).build()); + + assertEquals("png", ctx.getFormat()); + assertEquals(".png", ctx.getExtension()); + assertEquals("image/png", ctx.getMimeType()); + + write(ctx); // make sure we can still consume the input stream + + ctx = tikaContentDetector.detect( + ContentDetectorContext.builder().inputStream(TikaContentDetectorTest.class.getClassLoader().getResourceAsStream("test.jpg")) + .inputStreamEnabled(true).build()); + + assertEquals("jpg", ctx.getFormat()); + assertEquals(".jpg", ctx.getExtension()); + assertEquals("image/jpeg", ctx.getMimeType()); + + write(ctx); + } + + @Test + void reuseStream() throws IOException { + var ctx = tikaContentDetector.detect( + ContentDetectorContext.builder().inputStream(TikaContentDetectorTest.class.getClassLoader().getResourceAsStream("test.png")) + .inputStreamEnabled(true).build()); + + // we can run the detection again with the same stream + + ctx = tikaContentDetector + .detect(ContentDetectorContext.builder().inputStream(ctx.getInputStream()).inputStreamEnabled(true).build()); + + assertEquals("image/png", ctx.getMimeType()); + + IOUtils.copy(ctx.getInputStream(), new FileOutputStream("build/test.png")); + + try (var expectedIs = TikaContentDetectorTest.class.getClassLoader().getResourceAsStream("test.png"); + var actualIs = new FileInputStream("build/test.png")) { + requireNonNull(expectedIs); + + var expectedImage = ImageIO.read(expectedIs); + var actualImage = ImageIO.read(actualIs); + + var result = new ImageComparison(expectedImage, actualImage).setAllowingPercentOfDifferentPixels(0).compareImages(); + + log.info("Image diff percentage: {}", result.getDifferencePercent()); + + assertEquals(MATCH, result.getImageComparisonState(), "The images should be identical"); + } + } + + @Test + void illegalArguments() { + var exception = assertThrows(ContentDetectorException.class, () -> { + tikaContentDetector.detect(ContentDetectorContext.builder() + .inputStream(TikaContentDetectorTest.class.getClassLoader().getResourceAsStream("test.png")).build()); + }); + + assertNotNull(exception); + } + + private void write(ContentDetectorContext ctx) { + try (var is = ctx.getInputStream()) { + IOUtils.copy(is, new FileOutputStream("build/detector" + ctx.getExtension())); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/policy/MimeContentPolicyTest.java b/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/policy/MimeContentPolicyTest.java new file mode 100644 index 000000000..ff68039b1 --- /dev/null +++ b/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/policy/MimeContentPolicyTest.java @@ -0,0 +1,56 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.policy; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.TestConfiguration; +import org.apache.fineract.infrastructure.contentstore.exception.ContentPolicyException; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@Slf4j +@SpringBootTest +@ContextConfiguration(classes = TestConfiguration.class) +class MimeContentPolicyTest { + + @Autowired + private MimeContentPolicy mimeContentPolicy; + + @Test + void mimeTypeMismatch() { + var path = "tmp/test-gif.png"; + var mime = "image/png"; + + var ctx = ContentPolicyContext.builder().path(path).mimeType(mime) + .inputStream(MimeContentPolicyTest.class.getClassLoader().getResourceAsStream("test-gif.png")).build(); + + var exception = assertThrows(ContentPolicyException.class, () -> { + mimeContentPolicy.check(ctx); + }); + + assertThat(exception).isNotNull(); + + log.info("Error message: {}", exception.getMessage()); + } +} diff --git a/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/policy/TraversalContentPolicyTest.java b/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/policy/TraversalContentPolicyTest.java new file mode 100644 index 000000000..d7064c482 --- /dev/null +++ b/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/policy/TraversalContentPolicyTest.java @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.policy; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.TestConfiguration; +import org.apache.fineract.infrastructure.contentstore.exception.ContentPolicyException; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@Slf4j +@SpringBootTest +@ContextConfiguration(classes = TestConfiguration.class) +class TraversalContentPolicyTest { + + @Autowired + private TraversalContentPolicy traversalContentPolicy; + + @Test + void pathTraversal() { + var paths = List.of("/tmp/../17/michael.vorburger-crepes.jpg", "../17/michael.vorburger-crepes.jpg", + "/tmp/..//17//michael.vorburger-crepes.jpg", "/tmp/..//17/michael.vorburger-crepes.jpg", + "..//17/michael.vorburger-crepes.jpg", "../../../../../../../../../../tmp/michael.vorburger-crepes.jpg", + "/tmp/../../../../../../../../../../tmp/image-text-wrong-content.jsp", + "../../../../../../../../../../tmp/image-text-wrong-content.jsp", "/test/../tmp/image-text-wrong-content.jsp"); + + paths.forEach(path -> { + log.info("Checking path: {}", path); + + var exception = assertThrows(ContentPolicyException.class, () -> { + var ctx = ContentPolicyContext.builder().path(path).mimeType("image/jpeg").build(); + + traversalContentPolicy.check(ctx); + }); + + assertThat(exception).isNotNull(); + + assertThat(exception.getMessage()).startsWith("Trying to overwrite a sibling file:"); + }); + } +} diff --git a/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/processor/ContentProcessorTest.java b/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/processor/ContentProcessorTest.java new file mode 100644 index 000000000..353bfc0c1 --- /dev/null +++ b/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/processor/ContentProcessorTest.java @@ -0,0 +1,170 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.processor; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.apache.fineract.infrastructure.contentstore.processor.DataUrlDecoderContentProcessor.DATA_URL_DECODE_RESULT_CONTENT_TYPE; +import static org.apache.fineract.infrastructure.contentstore.processor.DataUrlEncoderContentProcessor.DATA_URL_ENCODE_PARAM_CONTENT_TYPE; +import static org.apache.fineract.infrastructure.contentstore.processor.DataUrlEncoderContentProcessor.DATA_URL_ENCODE_PARAM_ENCODING; +import static org.apache.fineract.infrastructure.contentstore.processor.ImageResizeContentProcessor.IMAGE_RESIZE_PARAM_FORMAT; +import static org.apache.fineract.infrastructure.contentstore.processor.ImageResizeContentProcessor.IMAGE_RESIZE_PARAM_MAX_HEIGHT; +import static org.apache.fineract.infrastructure.contentstore.processor.ImageResizeContentProcessor.IMAGE_RESIZE_PARAM_MAX_WIDTH; +import static org.apache.fineract.infrastructure.contentstore.processor.SizeContentProcessor.SIZE_RESULT_VALUE; + +import java.io.ByteArrayInputStream; +import java.io.FileOutputStream; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.apache.fineract.infrastructure.TestConfiguration; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@Slf4j +@SpringBootTest +@ContextConfiguration(classes = TestConfiguration.class) +class ContentProcessorTest { + + @Autowired + private Base64EncoderContentProcessor base64EncoderContentProcessor; + + @Autowired + private Base64DecoderContentProcessor base64DecoderContentProcessor; + + @Autowired + private DataUrlEncoderContentProcessor dataUrlEncoderContentProcessor; + + @Autowired + private DataUrlDecoderContentProcessor dataUrlDecoderContentProcessor; + + @Autowired + private ImageResizeContentProcessor imageResizeContentProcessor; + + @Autowired + private SizeContentProcessor sizeContentProcessor; + + static final byte[] DATA_BASE64 = """ + iVBORw0KGgoAAAANSUhEUgAAANwAAADcCAYAAAAbWs+BAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ + bWFnZVJlYWR5ccllPAAAAodJREFUeNrs3NFtg0AQRVGPRRNWyoCeUhM9LWWkjUw6iIQyCRvmnAKQ + F3S1/nqRmQ/gbzy9AhAcCA4QHAgOEBwIDgQHCA4EBwgOBAeCAwQHggMEB4IDBAeCg/tbvAJuJaJ2 + pCcz3HDgLyUgOBAcCA4QHAgOEBwIDhAcCA4EBwgOBAcIDgQHggMEB4IDTmm3aRKxlW5erOva6v2N + sUft96jdIMndDQcIDgQHggMEB4IDBAeCA8EBggPBAYIDwQGCA8GB4ADBgeAAwcHFpt806bZBMvvv + 27b32g2SzOgUnBsOBAeCAwQHggMEB4IDwQGCA8EBggPBgeAAwYHgAMGB4ADBgeCggcjM2gcWb5BU + m30zpNt5j+Mofd4Y+9QbKW44EBwIDhAcCA4QHAgOBAcIDgQHCA4EB4IDBAeCAwQHggMEB4KDBpZu + B67e0Oi2GdJtE8YNB4IDBAeCA8EBggPBAYIDwQGCA8GB4ADBgeAAwYHgQHCA4EBwwGmRmbUPjLfa + Bz5erT6IzZCfGWMPNxwgOBAcCA4QHAgOEBwIDgQHCA4EBwgOBAeC8wpAcCA4QHAgOEBwcKl/sGlS + 7eWr31jmsGkCCA4EB4IDBAeCAwQHggPBAYIDwQGCA8EBggPBgeAAwYHgAMHBtco3Tcp/4PQbKdV6 + ba7MvkHihgPBAYIDwYHgAMGB4ADBgeAAwYHgQHCA4EBwgOBAcCA4QHAgOOC06TdNyg8cz+IDd9sg + +QjZuOFAcIDgQHAgOEBwIDhAcCA4EBwgOBAcIDgQHCA4EBwIDhAcCA74xtLtwJmfNjlww4HgAMGB + 4ADBgeBAcIDgQHCA4EBwgOBAcCA4QHAgOEBwIDgQHPB7vgQYAPVcRHV5+lfgAAAAAElFTkSuQmCC""".getBytes(UTF_8); + + private static final byte[] DATA_URL = """ + data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANwAAADcCAYAAAAbWs+BAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ + bWFnZVJlYWR5ccllPAAAAodJREFUeNrs3NFtg0AQRVGPRRNWyoCeUhM9LWWkjUw6iIQyCRvmnAKQ + F3S1/nqRmQ/gbzy9AhAcCA4QHAgOEBwIDgQHCA4EBwgOBAeCAwQHggMEB4IDBAeCg/tbvAJuJaJ2 + pCcz3HDgLyUgOBAcCA4QHAgOEBwIDhAcCA4EBwgOBAcIDgQHggMEB4IDTmm3aRKxlW5erOva6v2N + sUft96jdIMndDQcIDgQHggMEB4IDBAeCA8EBggPBAYIDwQGCA8GB4ADBgeAAwcHFpt806bZBMvvv + 27b32g2SzOgUnBsOBAeCAwQHggMEB4IDwQGCA8EBggPBgeAAwYHgAMGB4ADBgeCggcjM2gcWb5BU + m30zpNt5j+Mofd4Y+9QbKW44EBwIDhAcCA4QHAgOBAcIDgQHCA4EB4IDBAeCAwQHggMEB4KDBpZu + B67e0Oi2GdJtE8YNB4IDBAeCA8EBggPBAYIDwQGCA8GB4ADBgeAAwYHgQHCA4EBwwGmRmbUPjLfa + Bz5erT6IzZCfGWMPNxwgOBAcCA4QHAgOEBwIDgQHCA4EBwgOBAeC8wpAcCA4QHAgOEBwcKl/sGlS + 7eWr31jmsGkCCA4EB4IDBAeCAwQHggPBAYIDwQGCA8EBggPBgeAAwYHgAMHBtco3Tcp/4PQbKdV6 + ba7MvkHihgPBAYIDwYHgAMGB4ADBgeAAwYHgQHCA4EBwgOBAcCA4QHAgOOC06TdNyg8cz+IDd9sg + +QjZuOFAcIDgQHAgOEBwIDhAcCA4EBwgOBAcIDgQHCA4EBwIDhAcCA74xtLtwJmfNjlww4HgAMGB + 4ADBgeBAcIDgQHCA4EBwgOBAcCA4QHAgOEBwIDgQHPB7vgQYAPVcRHV5+lfgAAAAAElFTkSuQmCC""".getBytes(UTF_8); + + @Test + void process() { + + final var ctx = sizeContentProcessor.then(base64DecoderContentProcessor).process(new ByteArrayInputStream(DATA_BASE64)); + + write(ctx, "process.png"); + + String type = ctx.getResult(DATA_URL_DECODE_RESULT_CONTENT_TYPE); + Long size = ctx.getResult(SIZE_RESULT_VALUE); + + log.info("Result: {} of size {}", type, size); + } + + @Test + void dataUrlDecode() { + final var ctx = dataUrlDecoderContentProcessor.then(base64DecoderContentProcessor).then(imageResizeContentProcessor) + .then(sizeContentProcessor).process(new ContentProcessorContext(new ByteArrayInputStream(DATA_URL), + Map.of(IMAGE_RESIZE_PARAM_MAX_WIDTH, 110, IMAGE_RESIZE_PARAM_MAX_HEIGHT, 110, IMAGE_RESIZE_PARAM_FORMAT, "png"))); + + write(ctx, "data-url-decode.png"); + + String type = ctx.getResult(DATA_URL_DECODE_RESULT_CONTENT_TYPE); + Long size = ctx.getResult(SIZE_RESULT_VALUE); + + log.info("Result: {} of size {}", type, size); + } + + @Test + void dataUrlEncodePng() { + final var ctx = imageResizeContentProcessor.then(base64EncoderContentProcessor).then(dataUrlEncoderContentProcessor) + .process(new ContentProcessorContext(ContentProcessorTest.class.getClassLoader().getResourceAsStream("test.png"), + Map.of(IMAGE_RESIZE_PARAM_MAX_WIDTH, 110, IMAGE_RESIZE_PARAM_MAX_HEIGHT, 110, IMAGE_RESIZE_PARAM_FORMAT, "png", + DATA_URL_ENCODE_PARAM_CONTENT_TYPE, "image/png", DATA_URL_ENCODE_PARAM_ENCODING, "base64"))); + + write(ctx, "data-url-encode-png.txt"); + + String type = ctx.getResult(DATA_URL_DECODE_RESULT_CONTENT_TYPE); + Long size = ctx.getResult(SIZE_RESULT_VALUE); + + log.info("Result: {} of size {}", type, size); + } + + @Test + void dataUrlEncodeJpeg() { + final var ctx = imageResizeContentProcessor.then(base64EncoderContentProcessor).then(dataUrlEncoderContentProcessor) + .process(new ContentProcessorContext(ContentProcessorTest.class.getClassLoader().getResourceAsStream("test-large.jpg"), + Map.of(IMAGE_RESIZE_PARAM_MAX_WIDTH, 300, IMAGE_RESIZE_PARAM_MAX_HEIGHT, 300, IMAGE_RESIZE_PARAM_FORMAT, "jpg", + DATA_URL_ENCODE_PARAM_CONTENT_TYPE, "image/png", DATA_URL_ENCODE_PARAM_ENCODING, "base64"))); + + write(ctx, "data-url-encode-jpg.txt"); + + String type = ctx.getResult(DATA_URL_DECODE_RESULT_CONTENT_TYPE); + Long size = ctx.getResult(SIZE_RESULT_VALUE); + + log.info("Result: {} of size {}", type, size); + } + + @Test + void base64() { + final var ctx = base64DecoderContentProcessor.then(sizeContentProcessor).process(new ByteArrayInputStream(DATA_BASE64)); + + write(ctx, "base64.png"); + + String type = ctx.getResult(DATA_URL_DECODE_RESULT_CONTENT_TYPE); + Long size = ctx.getResult(SIZE_RESULT_VALUE); + + log.info("Result: {} of size {}", type, size); + } + + private void write(ContentProcessorContext ctx, String fileName) { + try (var is = ctx.getInputStream()) { + IOUtils.copy(is, new FileOutputStream("build/" + fileName)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/service/FileContentStoreServiceTest.java b/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/service/FileContentStoreServiceTest.java new file mode 100644 index 000000000..2c543d08b --- /dev/null +++ b/fineract-document/src/test/java/org/apache/fineract/infrastructure/contentstore/service/FileContentStoreServiceTest.java @@ -0,0 +1,85 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.infrastructure.contentstore.service; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.file.Files; +import java.nio.file.Path; +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.TestConfiguration; +import org.apache.fineract.infrastructure.core.config.FineractProperties; +import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant; +import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@Slf4j +@SpringBootTest +@ContextConfiguration(classes = TestConfiguration.class) +class FileContentStoreServiceTest { + + @Autowired + private FileContentStoreService fileContentStoreService; + + @Autowired + private FineractProperties properties; + + @Test + void upload() { + setTenant(); + + var path = fileContentStoreService.upload("some/path/test.jpg", + FileContentStoreServiceTest.class.getClassLoader().getResourceAsStream("test.jpg"), "image/jpeg"); + + var rootFolder = getRootFolder(); + + log.info("Path: {} ({})", path, rootFolder); + + var p = rootFolder.resolve(path); + + log.info("Complete path: {}", p); + + assertTrue(Files.exists(p)); + } + + @Test + void relativePath() { + var rootPath = Path.of("/tmp/fineract/DefaultDemoTenant"); + var fullPath = Path.of("/tmp/fineract/DefaultDemoTenant/images/staff/1/PwVhJDLHyxUppiby/michael.vorburger-crepes.jpg"); + var relativePath = rootPath.relativize(fullPath); + + assertEquals(Path.of("images/staff/1/PwVhJDLHyxUppiby/michael.vorburger-crepes.jpg"), relativePath); + + log.info("Relative path: {}", relativePath); + } + + private Path getRootFolder() { + return Path.of(properties.getContent().getFilesystem().getRootFolder(), + ThreadLocalContextUtil.getTenant().getName().replaceAll(" ", "").trim()); + } + + private void setTenant() { + ThreadLocalContextUtil + .setTenant(FineractPlatformTenant.builder().id(1L).name("Test Tenant").tenantIdentifier("test-tenant").build()); + } +} diff --git a/fineract-document/src/test/resources/application-test.properties b/fineract-document/src/test/resources/application-test.properties new file mode 100644 index 000000000..075fd5a53 --- /dev/null +++ b/fineract-document/src/test/resources/application-test.properties @@ -0,0 +1,36 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +debug=false + +fineract.content.regex-whitelist-enabled=true +fineract.content.regex-whitelist=.*\\.pdf$,.*\\.doc,.*\\.docx,.*\\.xls,.*\\.xlsx,.*\\.jpg,.*\\.jpeg,.*\\.png +fineract.content.mime-whitelist-enabled=true +fineract.content.mime-whitelist=application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,image/jpeg,image/png + +fineract.content.filesystem.enabled=true +fineract.content.filesystem.rootFolder=build/.fineract + +fineract.content.s3.enabled=false +fineract.content.s3.bucketName= +fineract.content.s3.accessKey= +fineract.content.s3.secretKey= +fineract.content.s3.region= +fineract.content.s3.endpoint= +fineract.content.s3.path-style-addressing-enabled=false diff --git a/fineract-document/src/test/resources/test-gif.png b/fineract-document/src/test/resources/test-gif.png new file mode 100644 index 0000000000000000000000000000000000000000..89b9516622dfe5ea12b37bbf0e424cf0d96dd611 GIT binary patch literal 1018890 zcmV)DK*7I9Nk%w1VbB8L0r&p^udRB za*S|coFVJbXlzn1(Yv#8neS`T;Z(8Du##`DnUOF@Bh;{RvAgf@@3l~8Zd9(ejdyI^ z?%CY#@iAw&M^kV6;4CjPDk>@tYg9>XY%Y_`(Md8FFHn@uuPIP!O^}REDsRgtiPy8Q za+9!gwb7SwjZ3nOPEU@J+U~XQ(v?qYD@aQXs?1%Hvq{do&y1PTtIaNv&9E+svTm(N zCo@cRt8sI#nb)sMX?L$KYmG%!k<64#k=^L>-Sw=Qt#_*Nt#(CgMj6eRZcvRxOlS@V z2my+Bi*?MvweIdwjcW;Qyyv=W5hMz3ZV!{qn6R`+UWo4QyN+p9X;rS7{{4y_BPZv% zQ!s#A5o?o4vEztTIIDMQ%$bZkgc>Cg2A1yb?z^r;RjnCPeMU1i5fK=`eJ6;S?gmw? zRI59MJ{YZ;%*>dtid1SNRfx>HyP~Sh$X|DQ-QE9) zh=|?Y%)7hHcbTBQs-tFRd|{cT;>^s5h@RcdyL@J5dWgNu%-xy0yWPyHKzF9h%>QPY zyS=Kryu042s?45gyWPuxyUg9)yF_NmfV;c@|LgAV|Ly<(%-y>}nZZ?=-GaNO z?*HiF%-y`I%y?#cM2Ou#n%=72=7qc6n~0st-J`0i=H1NyrQOQ^?*HA)?%my@$=&}| zX1lwp-T(jpA^!_bMO0HmK~P09E-(WD0000X`2+lJhzesC zY^k!PO_(?}cC;zeCC!R45Bf|fl%-LkK8*@Rs`O}6qBT*fWXMw_(5Y67&cxa@sneu0 zhhFWua_dd2QNad<`gN&Swr}IQl?!*S(wafns@3Z?Z(6Z^>k8icw=UnbOcQ?{d|2*W z#EYM{MamYhUBgw?at-^ptLM*cL5u!u`EFOHo>BLW8y4+lpspp47EKv&R?|gsug=S} zb!gS8K?9$Sx^(N#x@+5=9GP%(=C7R=mmaum^O2#WldT+5>*>9?xr6^7jM6c3-Q#~} ze{Mdv>C)?mTcVMrczhULT&RfX*b-E#jyXi!wsGo@qo~2@nWHt7fW-JZjqF7eK*yDB+`Z!>IR7QBDmQLdLWsFRY zrPo3XwpiAP;jNkDlVLW=W0^{t2q%v%8i{6<)SdNZodUi`7j#e#2$^$@A=u@G$eBqY z4p}m~=$V#gYM`8jLfKHI0u6$xl$X|tX~Ow zV>#NWt03Ack(g1E`68GXCTS#JH+tFXrl`_6Dp#bM8ZCX;TAL@Ay>`oItFiuyr<$Gq zn&70Hed{N%gO+MvtZYU$?VPt_O3;v;Dj6?E_m<>qwvGmj5Wd6~D(6qU`8sR9`EIIg zoN(d^t+r&2dMLMlqA8-V&r+$Yg1ml+u%hI?YwoNh+neUU9y_a`POB=qamYKZ`{eC*ij@j|^$cCNoVh!z6=B z;JWh~+%;?|VU2UWJ!?(#z8Bp(@YX!5YoCKQ^s}SDoIt{eDch>r} zuy!Brw$G(r%O%haTYccweWwgH+ktC6`B71cc`v8uvWeT_M*+ z9>%lZpA%fU*StG@GUP}%IS|X5n{Hjn#j|QO>ng)7DeOI$3-!sG8$Nun(Pz)E^VAwx%idu zasPYYNnXc51txHSgnC{5EGN1F&W~bM^HJ8O)S!xGPl2sVp8b6Hwzz@tf$f7I{T^bx z52BETn@gbjLioNHZo~?`v!M=$wJ&~|@FfW1AMO9DhqKK+&Vk3vArev8y};cy^Uz(F4n@6?+Oc#=oZBA-Nk}5@agZhX;sC6`$T12ejEjWiz!b@%23oR(_q(1J3;9Dh z`Vey+Yo5fqwYx)d(UfxAqz*rV$R(~3fSUA31zjmfHnq`{RTQGX=JPr;g0YN@RHOxP z$Vdn}vLSt#h%aGj!7S#Im$KAkEBlB?Ap#GT*i>USHzGnd*3yWrgd!_lXvsGfvWJ}f zBregZN^UwcBgZ`ELW(&6XINpFV6;FaA5#BJFb>d>%k1PV2P(~iwo#4cWM(Yc`OOEW zteu>Dqb|2u$0%-7pjK2TGsEf5ji&RR9W`h}1?oIEMu?y%9au_tsnC9*G@-~8$QYA3 zJVg=&n8O@^1yqnzmRJA>_cVwj_jx^eUSydS)M!YxInW*+w3aQ+s7jr<&_E7rsT5u1 zIVl=Vl!~;ZAmyk-7s^hsHdCppbYnx!O4gB*6>ic@t3es~RF+o6s4%>z3IyVeSNt?W zDhOj>2Y63KQc|OaZK`7Dy4H^}^p;Jn>L(#PwYN%^vfWf-R?Uf48a@`9m}M$Sx0=bi zUUi%hZEIA|no!X?^{WUat!ihR+JpbPRIRMMP^QXNfc3R9U5#HiGj>1(|@%j}Ytg}OcKQq3CK+J;rK=S6K}Tl>|Knisd} zwJTf6+g|aqma(RF?P;+}U)C;myXy^aSryx_sjgJDkY#Uy%Q{zEHaM-p3?n1O2vqAH zc#$f|@FI1f+<{a9xhl}X&ju?HOC%N{c%`Iwld8#~E_k<=L~1SNN!g)76~^v`?MF}R zQCq6_ybW&EjcfhkFXsG$GD0|@b8ae!PH7~!xua0YV0cuY%-x2OWvu1hKW(w`YN zo#ibvA*mbJ`cm1<+^w&cCp+n9*7nL`u5MjTs$}@GG`|YY?~<#WRz(*X(wOdOr~|BJ z7%!N~IA(H_@!M((YMRvd1@lX9E!SKV#Ku9z@IYXITnoHH2ap7)4v4+sWe=Mr3qbBd zG@Q?y;&}jgU1XxeoJQ3WGo@z4_P1qxFPpMD)~LQTw+F4oUe{V(PQ7q{--%FDqu0M- z-t?$@z28W;`@0Q}E3C;pW__>rhXZbRNy|KGS=+nG11I%^C64O13Yf>VPU@>y1j&2C zfSAaRGYp0agOJyB*)abY$O4ufA!aY&0CUrU4y-LEeL~iZ08_0_`jX@HN{oRYlGYA%Q=4cu3Zgq0y-Gt8Lv8ndyL;lcb(y1uC%GaK6YA1-L{Xt zIN5z{Yj)$>z_k|m+vQF5vZFo9|4wwOeeC643ObTvtioWefNU$k+0It*?XZbm=aug{ zF)T;RnwI@^CQZ}8fk?`pq0+nJ7NspJ0l=!Sap zUCr+8>%Gz2=KcSy8NS|M8f3y&U^WgG5LlM4-}1G1eEOkngyp6j2PW7vK`LLIZoPU}u&$0Dgd6CeVe$a{zaCTwCT` zCDvxw1%A4BUyd|XIK*fPhRS<0g!G3-qhV@5hVH9omw*W?95C<>-3t$2R6M52R zdRCwULbXh&CnnQ{ZMFo2lU9K;22eKDfH;6pIi*v2CSgE@R0LLcDASz1 zb2nhJ$9fP)V5m5D$Cr=S_lcs2d$Krw;I%;e*nN%|d_;JOvlxoOw`2$Tkedj1%Xf;s zCw|x$aozWh8z(`57>Sf9Z-EF@_!N!BD0BP=h3f|cePE0*@QY!@cmtpVVJHwO=Lh*G zI#vIWe+IE6aSdjHt zm6$e&D!7rmXL0;^ijX*p11X7Oxr06^cCC1k)0dI=sE_KHf<}0dW66B`HkQaYfoHjv z3OST{$(QXIaQ7&PtCw9N_=1P^NEyZw#1=*euyQ6KVkx$sP_xsR4ueMtvf$jOzUxSTq;n|(Qzrl^)MxSgMfma+dB zp3(Q4=GljdsAb_Mn7o&R+WC7q)wJvvH}EDD~!NtZ7=p5|GX1gCB1^qzS+ zq#lWtH5#NqdQuYlmQSjeVL6vLh>unZRfkDk3m8lkmXcNgppIz*W;%?-mY@CEk|G8J z2Oy0w@N$b}c?ZCZHx-6E30NZ5poV304dh~@w_7%~Qq&lLu{nQAd0fz_0>u9|g&Fo! zIYnctSb;@pnCK~)&&Ij>OIgmK1x zjF+2r*se{=d=e^(uX>fDBY+Rtk2~6yG#Z>kd9Xwpkms4B2!v@uw2zsSM^FU-+N@UK2S)I5_IaQLA+DXt5-MP)bcPVpNP!gEFUj`?7@#xBX&9pO?5lx|^pHAJFAyVvl-jBimR|{d%ajkxWdYO+AFe5I=T3}zxL~*0Bd7obhbCkn9llg z_t&!y+_RFmv^oHwX3Dy|cmRGdruhl2ktYKP!L*CSnJ;ICBwTKON@%Y~YVC@li6xti zIj`vl1Jc_EaoW1}`C%m5oc!9W*ywWt+;D7rxB@JZm}<9gd&KF;uuICgcKNRlo4E8l zs{Z@Kc{{QJT*dgy#7wNeJ1GgOSGz%VDe(fX{>`f?O(x(;ln%{riTc9Re+1L6O60N)xRFvq$Gkf&g@T%rSx zK3qY1u%*JOtgJsOiqc_HE+|1kQ#QrL1{7Q8I+@uRN zZV4gCri%b|D#)NY&W{3jATR8;yWW%9$y{(r5+H%)`{&!zx?GVBE!P+?UzhxVoIF_v^R3 ztfj%szHRK$y{x}ToXi?M#K^4DFAA_HEzA_{(yjj-xojM{Xne-WRK^kgdw$l%nQYT$ zywSe=yI6oMSIef*ftny*oP&S99&kNJf<3Bgcs zJ@d?&b&5my+@Teed5h$wy~??!)^U`9s4f4wg(KIPBe!zMor`4qg&+30lbXJ(&C%zX z+R04XL(Ongy3v3+((O&ag{|A|4d41p*!iu}0RF`ijo7U$+O7rXJ0GVB^RxB&8Ur; zn)`&ZKMl~Tc;P7<#>wR6%Zvkmjk0A-=3=78f^CVaD9t;J+S5$ne;2prE3E##(hct3 zlN;e3ec%ob;RcT9435hWUf-u3;C}zU*{zL&fKB1G-Pb)V*kdf_Xzj*gBXS4n?Ht!C z@a%Th?8Jt0AJ&8&w|e1L@ygusJDueGE#eP90MK0V7v1l@TISAt?;#7+<;LGrx}FKn z;rBk2RNxF`3Ip$O>dN()0}A6P{|5}c@+f}*P%zF_ zUGwMM+~I1cx_;~7s-Orlh1IstiPz6IMeGS!6EB&JZkm2?n(R6N2IIVJ$)Agmm)_xa zp@|LO2yfx}?bkEy_^;2Ukn1b*oqZ|&P?#<^|hS^wb;C(Sku&6B_Vt=#SHzv!ur z_X14f*Z$~^-tH0)5S9iE=rge3K!gMn4t%jtp+krW4+?yEFrvYW0~%_S*wEs_jR`|? zWQcGh#fJk?VpJHiPeY0YQ697?@a4jZ32BPNC@>^Sk0y1p#OPAx030a~T4}hEX3~PA zGT^Y{=#(rS2i&MQu)yort_xHwa05f^*#!qoKrx~AfLa)8O~^<(U@nXSZ|xpHdLStd zzX`bxv|t75Kr0sNQXOE$u@$6v3F~IO_#5KRhbtY{ z6|S79QG_#Dex!ae=X0FHQ${Q(y!Y*v+2J!+5C7nc_US_gZF;^w$m_mis6C6$yRRYy zg|q27?3VioDBUDlFG2~2(@vq?BpeAp`I-~zz{vK4$UO>kldhoYq#K0_E1Z$#l&msS z3xOHm0t>Co(sIMAx7d>Ftpj90gD=3^%B!-rDhtdCz9!SGu__QsDzU|+w8R1xAaks; zfh@zJkIgvC42QIINb9o$Ok04o1F|}xiq`x{N-@QxqX@Fu@I-Dnr^e$5yZRP;r^pagKWeRuRiDgKAj?d<_OB57s3!!WDX%BDZFt-a8 z`iMV3!S1xcDXqvrfG=b$*IXZ=Sd(29&^5s;1jagm2Gn?D%Up8rP3nLl^8&43(ewR_ zptz7y;q=B5u5vo6TqBq&gpo=rE@x09^KmoH+?eCG{CLX`*5t%9#fBhz;Y$-c!exv6eJU%!CW$+VT~dugLZWV29Ar-jzHrT8nWpCGmyc* z`URK+@QW{c0Ze5OMldV%!3qhB%<2>-Mc6ckDh&%*6S>40uAJsfCeQ(!Ha3He0SQQ# zkr0?t!aP)+EI~mtNU!9`AqCn-fh!@~g~-F429k(ENl_N54ycpqjISidl9mW{g})L# z=YDa+4T)A&kv{FmKhsj5^Xl_Q_&qXJ(HqpLlD4c{2}F@n3t!;=)IFA!#5p<12?dQ) z%4&JfliKT_gj9)}xe4-b1Hz?!GFYn(&gVS*GnHd%ft9$Z1r2d9*EH9HF3|s+t1W3k zz_@tyLwN-W3eq%^y+r4hCN{<|W{FETRiFbE6s8~+AQE99V=%*9CNXd6gJSfVIWcZ* zO=Tnv8U*?k&iKVJeYoWE))Px^-DiT1>`l#l6FBO-cx?TuQJ@qo_qKG7}dW#6gB= zm?pjEVlgys6AEGqXIdN=m$U@w0Bji&4)|pPzzFY%fzeB6HbbNZL^1y{2%An~8Y52& zSmH9V0gS`KR3^Agt~3NKC~3T+f_SRH8P4DekYFG(#kj352f@~;);2Aa{pOc@lx5k# z<`a?um~BA1qr;PUuNMJ!_F?joEFs)ghp!%sT&j zUU!vw%J)rDJx`k?aN&0x0wt|Dzl7NfW{F3QIHx#iZD0tEg0+@*h`!!gR3V{z$+21Q zYV;|jM<2S=OqmK%T{Bcl%|~AmLA1+y+-co{1wOPA4Qg2ZDoR(S!lKAgkwDdzQ)SAN3GU=; z;d76iWol@SfbLKc6s*UG6;DU%sEi`-AHy^e@k%4nQ{eG3r{ zYitwvL5NU*%wA`gy4gi$Gt*gJA5;JX3l!!roShudD(H zvK7v@l85py| znq)}BdzDK79o{g<;zAlIjFVn*`Gbt;HCV?5mYPV40}jR+!_N2x2Z&7z!Tc})86%}L zGuF(tv8^Y;gAp{NxQxHlGH%l3bz|pV02nL}h9huT0J3=UF`n#<*I1N!#^N`fZJ+cgc!i}x2tvqe^3zSG zt={~Wsd?v$Hhr&V3F(tsB7n!qc|#9Hw_EPKJ(dJ|_-WcH`H8=)mZE5U13Ywz*V01` zj<}cmD^oD@eovtU>!_{3)~s-hxuB-GfC2Jh+$f+|=5CHWUF!2vj_i`g+eXONB4*$jkvm&nSCS2%!clbqin4Rbky zBD1_aV7F`Q3LV%yCsToAh^LXk6Q5vaZv6r3W)A=8G?Y`@WRgtxBRB0@E5n zqa>U;CZXxQ49O2cLA^Kg9)ANG=cpdzlc@ipqB!^KIH-feDRh=j3M48-o6-}yi|eld z1Dcxj;a`k_=#hS9paCuoozhp&40#0^opjnH(Y;KxzWEAXyU&Jb<>F7a&0Z zD2M}mDMq`KCLj?VB73a9Sd73>Cmc|LS6F~oc!vx)o`DDr8hi`9AQKaa92+zN$uj{R zJc7$(H`kCS!P9|vI|eK%3=6;xJXxOQP@X({FY`GL@?t)mtHVtkIat|~@Cp<~Lm`>b zM`iIUgNa``iA>WdVW~n`c@Y2jik0*_kcm1e@j@Z60+mUGu#V6&rDop#EqGP$0bQ=S!xc~#d zLvy)aI?D6WAXID&M@R-)XrVGBFgo>tbL;xHb$Gn;WG}6J#TZ_ZX ztj1`aSNObm$~GLh5IsRKFOx&MIW+}hs#77!tGTG8TR!K>B#tbf!7-*t%D0>vE3r{3 zi7F92>%RV&z7J{&EPR{SgTMc!nzZ;3Dzie$q+88N1Qo9#rrmTz-zY!&3CW|eGf8ZZ zGGrF-=t+wcs)^#m(knPTTu$+1NxZQ{=Cdk0JE@h^J`4#Uzp=FDu^UGcHL9G--^0y8 zk|IZVhgz71cMyOBJV0Qh0RadCtnfx>@Vc)95^8eG!P+n)OS`pryR-wM!9s&%%s{>4 zHE)ChC4t7e;0nM^)kzWJKB8nd_?H1x%v7&;cU&F3pq(6zMGnw|C5SZ5Caw{ zfK#Z2Q&1BVpn(OTffosaSaY(nB%&nB&|T~i8Y#dUii^1H5w|#ix=SKi+$%qT0%b#@ z(!mzJ=!0WDI}QUGDQcJ~x&_b(Cnk9d9W<9S$}2GVooLNWEJ6vYU@fgnjDDI802v@g zD$YY(KZ+zEHEk9@q*v!!!#3IwXVFjCQ>nV)%_@zgOC&EYJ5JYgua`(Uri?F1&Bv09 z#L_b>IAw?}ExrGglth#ix=0LFon+JUoX&}@SUq(^`Z-RE4XK`7xr_q3SAt1PmClhp z6b?yLmZjN9#Mt7Sm5cN^+dD`;jg@V=v^p|5Gv&vF#Go=`J*p&-#9*yfq=8dlfm#?l z(?Eb55P%w}fC4ChAP|dVFpILJ7r>A!S?m!Uq@iE+RmTyhy^=e$q!+qSqrD5!ZEO-G zQnn;pfOvb19P0xrKulkwOVZFma?C5jB@Hlmg;NlKYkQ5j=>toMCuhij9hHdMf($K8 zPor~JgSEJn;y8d)zleHLm-9I4tI8~Mpp+^!ljE||l+-%v#8nZ=jH)Ttok=J>Md;zv z>8nXHGgSXgwZcMu&ReR}IUUrEWmDvBh;cyK;5A7+J>519zb#!lpS@Gojnm!zxtpNb z0kGMTUApdtLhz+ijNRGs`Hh#2ub_inN%T!C#3V>0CMnerptz3_Qn^5M48vQ1w$t0T zVi&?i0H_Uu9Vh@6NQSXETfaC~xk@`A`8pY*rfZGMwt&zG^@?#Cr)g4)WCRiv>r1`J z3ua?Lbpsi1o1#%D48in9U&|(PJfq1&T+2fj8c2q9oU))DfNXPyTbM`L&@9QY4Xy%} zmy|+D!`(?UtJh3D{N2Ro3?) zE4u%R4G!<*MC7ehZUJBKEno6%uATE2IsRTr zOk^~MDoG1OjZ=x#lh2D>Px^IZEUil7Oc^wdUo$3X?O(~a8-19 zRap>#0?>g|C;-zy7uT>mG_X~`h|9T}rV)G4dx=1}f?&sayAA}=WaAjU%$FuP)*@jy zh0->v*orB7H5*xzt{_Lu+ZY*`fde#w8a78GXpCDNWj6dp)&Y;X=MeRwJbyNTB zJzek}--A|OJiO!J?Snav&hM2|L)Bxc3uKz{37JrEaPMG*r7pEyp@ABB<*V=t z(x3nq*gRPD7Y8oO4C@iPii0?az#0s@xO_XmibV^2)(y6TW9^c@TrssU0t9dj(0dG3 zE+Wo|26^$THJO2LJzH@8of?iNBh=y5RF1?D2tD!9hmdSS2~^_jjg1^gh#k685>4&Z zzk{_&*F|bmQzVZxse2CDqh`*SwOExM-jh99@;p@6cG)_nA4+c1f=E=^*4Y24sp+2! z>6-T5iJoJao#@>jN!}jgNL+5{-Q%DuN+GF3Zkj+-1(3pt7u6GHPrg#btq0SX?9c03)aY9pG=V7*HChMK#$X7!nd= zbWpmIA+!z>xV;w#rzReWp|iZewgAy_VrC^F7cv?X$s*-y1dOdX05M35$>~LNENly| zWfRDQGy)C2oyW~A2_#gAE8Ci<$2Ez&ea;AKMS)4n)GPoF*Sfm_K+6G*JV%`$bW z=ltY8OKdLW^Z5m8(H-rUaIf61XCzJNM>Gy6 zE^0$=RGrAQIJ}9%&}*}}HqL4#j(i{JrKXGN^M@X!r+4J~RB)o_MU01eivg=6pvGm(MAm5XsKY>vqc zILWqbJIx3Yh#HR!_|_AmE$@{jmZ}RDNFGG#He>iba_VGRl><04mh?evxSdY)P`>RU zFX`BJ*)hNEo94GO?_=%0*?{kwHfP_J&W}HD#OzLPn-)qu@8192zT-EKc@hFO=E_?!OTkB4(S7w-0!73L;(wwhO*M zwHvHt>xx*Zy0EHt-iqsMSyRF z!-Y4=gLib0U-RIt>4-0Lj?Z}I_VdqYdDSO<28#3cSor@lU->R|X)8}@j3#c4ZfQZ! z{Ykw2LjkiL&Q#GB8cKG~+Q#0Eh2u&sZ|_|6oqoTUn6lV8Jjrr|C7Xt;M?!mwfm#sL^AbS%)J1Iz*%CRUnAIFaQ_FeZ$cgaPA~EDJiV4Cph!5)Pj) zdRFf{3loycLZ;ofwB(_cUB^zHTQcv;vr`Y=U0F6^*0pgT zue$VS;}@2qPG_4GX;{V3Kc}^R*Q@L9fXQ;V&YHX6yUyJbJ^!?iPb+;qTCiftiUns@ zR5%k!LjZs@=zxF`Ml5h30t3l#L=Y4mbN~)GSaCocaiD>Qg&AUq1{4JuBtskrAq3I_ zahMR|0Wu(z&;Sp?V8Medh4c{)K$&0@gd!~f14KG}a0(a*=&;fZElq?#ktWCl1{gFQ zuz(S=sBm8&RK~>pR9fsU! zkWFS`vpW3-M-k5|srskv6P36&i^I1~md=|h!gMqJn^wEJvARr`yDJuC9wsDWzzYlnMN1Dtp%FqBr0B;$D?u?zeGn!j;l(z&VMLQO zC79q5DlJomS~X}^$$DERTy$lHCTQK6 zx97Ig#`Ruytes_7uh@+aAaH~cK?tzGg9#0M zVufe~Tu?+3iFlBT5*cIy!YRVAFb+^S6o>EvnXrH}$4m%CM+Zz8QR@XZ35G1@!<3=` zCM0P>9`Gv(hRPB;bN?vz_0j+3d{dc~CFWkhlWhITPoIfPmc}xjv9zf=a=Fu<)KfG` zX-;(1vQwdq_MOmC&`=$m90)HJnzRkeDa}b+sXE2D$ff60bL&Ilc9l2VkT6kuJB+X9 zqPD^b3s=5M6sh2&8xkHTQ$Ea9T8>B@9uAH%vN{akOeI4{IkAd41mYAGrNh7_4Nea{ zmUOVTEypxwYLUYX)}q4~FnLXjiYd%yWQMbz=)?lDvqb7d0)wo8WF`rc*Gi61gHyO6 zBlijs!4RS%5MAhB2iXvYAkq@!Apjvz=mSDlvwFxW|; zFl|ONyLFLgW>nf+40AydMyHx|QzIF{qQ=>T4N`C8RAv;XDZ-ghHtbAQRREX5w>8mJ zq=F(nfq1vU;ZSUj63naA_9#-^_q97@ok zw1;z+s$AzH2to<=igB|6U8X`9y3(NqQ!La@SBQcikBo~oxwHukkdn(k@-&b;_`&o< zB)ktb@VmX&{(@qeEx|m(&n>=iz5};yyip340kwB$&%K-(?+aFEu11mBS)19$H<6HT4(AS z3&G->X}Kq7Kame}@i>5+zDTE>1lhYn_AVM^?%hA z=G9MAf#&~M{PY&6M-U2wK=x*h!+8c(=U-O`4ntCiy0 zj_5XqqAfR5bSRM5mPOzqF{8Y)a<`N$(X>@rio;Q;;+%+@%>2zXTNYMk%e+O0=IS(6 z{_<~q$TXoz&VnPwnT=7JX3b5iTNJFVKY3<4bS5qL{mbkVGEuc=-a6iVW7FmPij_&=bhQtZ>y82@j{+n+cRS21}M4VFnSI29jn; z%l;~GZjkawlffbSd17PSn-V|zmwQuI9!eYlg$9NM6f@r~Wmw{r_)V;+NUqN}Mfe9p+W zAhxhIn30;d1X!POO$R7X3Q0!}1jv;bL6AF;g-2EmA@>R|VN)eF!t(V8<(Y^>14+?J z;?NO?93(=*Gngz##-y2qY}VTwiG*3AJ>Ahn1&(N)>txX%k8EitFPokIdbTELYO^VL zY2e+%S;mzD*0Ev{`QN`r@@R2%tseCPXY!^N z7^u&IaN2g8oT^CsW7ZP?il91Aa6Ah(%H1g}=9=rcj$x6A?8qj6w4Fc@Q0Zx?IzoN8 z*M6r;-$ceYdCZdm8cHVB7irq+oYbB0{;0c1yKj3p$@NO)!G%beOqksT!(mUTepqSX8|6jRF-w&kU7y9W)YwC z0a-y^-o(Y(WxN@~!5|b-l%4^L;mFqM*$M8c*>2gJY88&AVAN#X7Fr}>!vX(VnUP-Y zC5Ncg8%62OaJgHYwHuT%p{r~WvFwm@Sdm3}oR1M+;IWVif)-_&+&9JG5z*7u=#8rA z8y!kuRD1+~;87KD)y=8EC&`QLyh|GF00&G6Pl(S~%m;qtN9*VjeOPS+3A`a`Z8F1iAZn*zm>4D)xCES?# zQ|ysm6$TN-z1~Av;k-$f^tlEye#+)>$_u_=4Gx_2J>>LBW1}QgX_*v$d=d_fgC$gf z&K(GjP-4k^z|RFmgltKsIS;CBNbzWh3?KkVAcTa0&s7PGd%apL$q0}1U;n|<0U#hu zpn*)#5|PlvkGuj6yaTaygfmdVT+x*k2++8EU@tLHFE&%(u?a#}q)TyNtxy{a@)$`Opvs=9R2y34 zX|j+#V$>Xdo8WDu;^|-;Syn?91%CWQLfFR(z<}+<5=OAZZ-PM()B@2#Plp7IOU}Si zbsDH4PfLtlz*vtY4&CrnA}7rN_{hMJEWrD`&jOI5DWW1Rnc@t%3xNoLDY%Xp9E1HF zLoj&+%g{#zMxg(U(J+lk$A!^E?j1>O%Hu`jY!X@uejHyg2Z8RG;4SD9Mbu#68@u&j z#!XyjV$@w~)Maj2zxk7JpqUVwO%dMS$(dOYZf5C8(S`!y5~3E7e1-Q)hKB0P<3Tn^x+#@wvmNe2U_wa3N8QS@#&DS93%!YsaoiweN2aG zxK~bHRmsRCNCw5e$gC44V#2gK?Uvs(D1C(v*Bq;LQj{Q0ylN*4eQDXk!hE zpE(ZCG!_fGA@Om?S!yPsl^_p-D&h#-r*PKfZPey zdE;KvUS{5wMdhQ7G90kB)Iz}@UT89_>7|xLZ6>f=1_8vgKTbik*lG>$kIcSio6R{pLf} zkv+;>AO(Hc1Stgt9t}l8Wa<5p4EX5|0&xF8M%YA}>VOe^0O^{9!6?r_ELB7xj0|We zg;-4gDXc`GfkXfd)Rjyr7Ktl`CnpZ&D^Ub2(ZDN^%mH9TM~K8bAmHe_feNHtrrK50 zXk|?x*T${fqOIK0=&l~z zLILiqMyZ0rQAgR64FU(O21gGWYH!g`!)|-XP1d#p7Jc4Hg#_ z4#s^1Q!YhF3}1}Zy~y-LS|yr*4hTR;B!evA6e;n?CzVpZu$sZ%*M~q_kwD#`Vn`_& ziSY^3Lz4QzwZBtjZA4_#|AVnQ{M2{!zS)Id$G|#74CBbfB*aAk z&;GH55fnfzIO;~=oap-IP(i`H3`|56gvbm8$u!c6Fpr6($b}GgVw->)yaG}IFDO>h zf`CB{7y*M5M8s@QNgyB;{J|eU0ry$NizJ17^hvZ;n+sN?t5#!{DavV?YOLTToRcXyTx z_d0GS59p(mpY4_7sBrtQcIPy78+TFzDWmWJj`F}wH>-CSWB?2GB$xDp{&tw{(?x0R zMD?+2$>WG_bhNf>(jpm3U!lZtAW&f1O6qrhKM4YA&kYPj4HSSUIymQo;_LPwb2879 zxUP|C&xKeLQTdngBvpk&&+81}DT3la{6W`Igq@Ds7;`R3$inergrnL7No2%l9Q1uM z6KqE5Mu%lnFT0`>otomE!rGAh zK`k7J@Z8ja%$4-c3}XkU`Nor@;hMLc>FU{-szNsW+0W|U68RPxjz?4Z zXZrj9IHWEaLrxl0Y5qO=03F`It zoF9q!G@vfkyTrbVg#MgZPaqf3WLG;`*3VuvqSMX0UUk@SypoS!1(dwMv);aj&n$mBTAJfH8%Ws z@npe}CRv($)^rJyXwIH4TiOH}^aT%`GLK%&m@s3Pxb4drkg8E7WYKy&1X zi5VtjxRGUha`4G$X5=OKiu8Y?B8D4NKsnnrRdEe|yeYO0q^ENaB3j54YxrCw^0#iMp|aHR`9REVh*YvhUl zDi~qRF{c=V+E6e6!zvQ1_pr)nJ_U=2;gQ5YU2%!2MNv&0JZzPfeH z1k*FfuKoKA?YynwN zeMN-h%uecH}Xjo>C zJV_wrD+;UR?JmR9PsdVr?1(rglkA8JUJ02n&(8M4RoHMYv^3NrMU78D6P*-lq9V@v z7Qlg|K}}P`0o9xir2;@r=2EYaMRpDlwgc$Ee4T;82E)?_3-rMXAGE~u1ml+%_@ygL zLKeY@^{f^$j6YZ*9h?Q;K$n5z@`1ChNjiLw=_(Ecy#}=qeo;b=SL(bTN!Q>EbwkSEDP!izRD}kxzWJ zpt{v?dv773^vrU+in&K{HiQ#X(m^COTRx zj@FFu3O^8LG>736pZS+pG;BI!4r{Tx| z2AG1(0ZJn>$n@+nm$3p2RB#!-m~a5P!qt90cD(*%>~F@B2@WAa8;%iXf?uHwJmN0`%m*? zO2dOZDh;&yZ z=<4EVk~S(dTcUlPL@z2u*E)2yT#TrUL^NB|+7`EPd}C4C!@?|S^Nz_QSh4CdJ$9bc zd7B#~hA4N_!G$SI3>hICdqt$2T44Yd2$`#_@Ho$`Y*msmpJW8^rs>3qt!q_pVIV_Q zLCFRIv(cYzq)IfbzVc|IqJa*a7O7nN_c&6+>I`uI7B%gdV5(5)8K9s5S3s8;lRXY$0z}YcH5gLT^N~9k~k!Z zr=x7XXlu|Pjj<^LwVmvATgKUr*0w)l9cwk4y4qIJD8G}VkrRrdHCFV==jsaIw!~46 z%0!#xf#;Ew2c=_i#hMix9!*P%m%!NM%OIBV<7jjcfy|9$2(bXIF!Ly9e6YfvF^q7^ zw;0I8Ne7atL7h0LgSf6KF^PE;p#bGdG$clqvbpaoohA$8Bn=ID2y0kBwKB8%Of@=~ z&B|bd7$~?(gM>=iTK#}RzgR$;CN$x2uUSX`{$MPzAl1v6w^Zz{eA&44T=BBR+-sFS zXv|=iN{W6mZ50(%p{#>qz?xjU9G$kvRhDg%*?8M9f}6-nhO$K0EjxrpRLJ5Uowvj7 z65N%0w(o8b-+qY4!ueWp>3lH|tpY^nM$gRQWXYUs3@&(<*%G6$z{JZm!ih%`JR+k> zA7J38BTT2zj-f$xf@8Ey%f?SrmCa zq7gKp{Dj>NhR_Oh6=B=R!@?O3PH*0nvqZEc-Efwevc$d%?YP-ogezHpHY0!WDmB|zJqVDcIcX+e^JGZp0;=2d>S~A`p%4*bm-rJpbB4<0G6!}Wi zodxyeT_v#(ANKRUiLk)I5KLG~B;@=?!wo%mEsZ0{2(McO?QT$#m>C7>Fw=(&T!v6e zGw)&&otxdnOucc1fp&;Ksl-Ip(gPIm(Oj7|SyT$ZU?nwjVvYt>tL8Mcfda}Ab(rof zQ^9QI;H>&kg~yGFFX0#VMgy0u)4k%H$H`G)74@ z3}ez3pir=DZIW(3-r~Zjgl?#*Z&Ir2umtL$$MF&_vJ8ux^dph{1I3QWONivTDg@zV zYFzqBUATy!sEgi^EMOW6wGeOcvTVv8ipu8h@cfV7EXwXGu@f~g?=JBZb4w*ikA(UI z&71^Dnx_UIF9tae%&w%Gu*7c3#R@3tyo_*`1c=c8SnXyyrNN}|m4@%qjONm8qxt+~zl`Hk0O)|A1`xgw`UK_D zPD3{O$JL?%Y;@-LqLCGJkh69o?fVJF>0L;xAk0xuBXY>O1nC89_Xq4=&8OS0ZfQWPn0 z-r%U|Ag=>cu_1GEKd@rDfYEYhQA_SdO8ROiXs1D#>mo;w2F)cS`oR*SlJuf-;+CmQ zlFkv1ftZF#y%697j6esnLp!3QQWgk;Zce^z1~J?!_y~+5%p?dXTcCTFmmk z3GU*~6>@MpUFN%huQzPbvOswDs zO(3q+Y5`~E|(7qxiJoQ z!%zH&HvscyB5ghgvpcRr4c+Ee+Cs2e%6SOO7FVo77m3-xi4ae!nwDkEaH2{Ut|g@F zGc}}*N(2-Cx9B9hXvz{W6kUX(^iDT z2C5dN!H7vxwJ&7Yux)Y$h2l_#Fto4Q=|KeN!w959Tq?x$DKDPQ17jkcOoZxA>LRYF zdT!()ZVM?*3)@C3wHz@3y(pt5@gsfJ?|$^i2yZxhQ&@kKNQG2cl~h@qm03-~NQX2? zk#t)BlN4I5RarB&>5!BB<^nmRlsN+g&#odW3j!5!$0sEMSd0gx3U07ejHDz>C7DH@ z$V4;jq%dg3FkrwL!X`Qr%?K(5X{5$!CPTp>D8OijXMm4SW9j9ra2<&wV7*}&u?V)b2LOFake!XkTokRNYF?%N0Hoc^jKdqYH3nfs})GE6W%tda05Y4V)L2k4BNmg54(86*CZ|jmGm=g!+2|^}r~R1HLnkr?%@ia5 z4KZ)(AhdxY5!i7aXz11ZuztnopPR zGEv15g03plT+a9WPAUvdO=(4Lm@dNrQjeDF{0Qf-#xJIpOV~)Y zI!ok{I`f?-(`Fqhx`?)N<_X&3309fnw9qZ^T5}U~b4QJJecu<2pB0U>7Ja>Twzl?K zqcwfy*nQ==T8H#}$Kia{m?rW#IQMuQ+V@)X*d+Woj+6Cxbdp;~uy_<1CrJnu``0ix zh<;uL*7CPA%&;)%YMDlZ3^&;lpt6R}uADv!a7E%(Wy^7Lij}ESnJl0)lrB6XY2wx< z_8tQbqYzYP00DHslc%q8v+-#7v@U5_9MRwg0ycoGF=^q^uheQ1h%*N~zMk%G2W3xWqm#3GNVwtS~0 zZ`4K;3f!Q!qIPSH$rv}u_l*zQjlVaym=%uK*Pwm#p>vCnkra?Cx{uYjkm0C(gEWr` zS&zF`L+zJ5*rQ6PM^|)mF(EltHW`F8xpntM83kBmo^fBF>XWVD7NC+9LDPvZWTsBJ z-1xU{VbuyoAp>B*J3r`zUSOFvD3appQ6ZN-YonLJFb$cN$)LCsEBvP*AUCFJdYs%6?i=m*x?v>vNRJ! z%Wj>3=w4*1?(j{EcJ)OCP@n+{HXHDI9U7tGxS`YdY9q>!%eS*JnvLD}j6eF1l@*Xb z`l3afCIlI^Py3@;yIDQjqc`r6`v~%k)0_K|T)&S!NN=SN(_FEKGeoIR7_7KqLuBfQ zruk&5Fs*;Oqg;#k{?FWNmaa!5&C`c z_{G2Xj$1pB*%xciw|!5063*AhKf0q++qFr%j#0a`gVW6Jf`oKMTQk+xoKpz>@p1a` zsoBPD)^y@VLE@OHsUM6{O-W56RWwwtxku@f*=D-DL`z>PcQ*oz-^oPT=rSfw1)6E4 zua9o8G#NwVF`Nczw5q)lv}StmG~lu=B~~{Gbq2sd)V2_4ig{AQ^oHs*n%xM%EJuuk2EiE33AQAPMx=`V^jUsOXB=POX{O_L!u#E3c z0+Dsa#aFY_myKEbYcU(O4|%qqb+%_)wT(2$Z~WN*Q#;xPnWIHp$8G%CrTu(8Dw{mY zJj^VmAy0>1S zY?X~D_=9F;R$ib?m^w3H&62>Q3IK&M{M?xx_C9BWz116qgKyJP!*gZHzw&a1vx>YU zJvH>((%W(z7mU>k1Ae;8Aa?4RRQ4e|5c2}koCzl-R!AYEn0RL}l?@KF*j%yVqKkuG z;LDA7m=`zyc{P!i60vN2i(Kk8J8V_keBns8r9GpGJXw=H+K=3`2N}pSy4t%|kPZ3A zZ#<88Jfp8Y$e-P{e>@XDI{}~sTy494nZ(xr%!3D)j#gYnG8UlDml1+=c`=MC<-UA} z!Rwe1rGEP7FccIvx{J&r(qb3~+Hk~Zg}Uxu04lxHIq8Zf>Y0rO;~wLy3AJiqVaAs~ zBamaKT4;%B-Zi;?d=~3iekiLtLHWLT>0)r%?F ztDXMIzU`xZ?61DF(>}EUV$!&A3C0N=STG^Ng$fNa9GHpV!f_EL4m=pKVL^!%HwtXn z=S829B14)aiL&I$k|izmacODPsACrYER3wFVu6kY3l1EBQN;>S7(@@4h=Wu{92rcT znm}M8DpUkbWju}g2daq!3t;qQ3Pr|&KL=z$@oB~7IFT>b_8Awl?c296B^tDFVP`6G!pOP6#Ei)^jvO%(^+z?Ep&yOiu3{ z*Cbo*Cf#oT?tR>V?;*vPAFti*-@kp?t8WjVF5bI!>CWXLpRZdUaOc|}DAHX6<=0`qiNSfDu-BA%quh7-2;aZRlZ#9DWF*h$C_s;)WZYxFSUn zws;XoA{OM~MlEL4kwgW3q~k+9@@P?xF)BplLo`~n<3u*T$Q^krrSv3u)%B4<1{OGD zg$2hjwg3V?MP-&zVOcesRZJ~~22#L{7RL-SxEYlZ2pln$34fR%!<;vma066Ul_o=1 zWrcN?A8EnGmV0&CW!GC10;nN`gT-WtVpcSkQ&gb!)YDW5fN>cDM%We=Ws^lksu2r7 z5yx<*wOZzy!LdeMajeOS*>0rn*4k~g`UdQp!p@pnt+X0<+*zOnbK<#?nF#$4f3LYq2%m&6NGhQvmtG1(O*mMw)`2d~eY8=x zp}O~EN0e$T8icmWnpL(QKAaJk?Z&uhd+&ytv0)(Y+H9)LW?ZdrLUHtR&_0I)buO`W zUFl6~TVA%Q$8});eSHPUU3Tov^*Zfkr%mAN{dG5XqWRXxU)p-fm6v?u?hA0e85X>k zh5mA=A%zJ~f8xa^URWc;FfN?E!!v%E<3Sg~T=7IHT67S}3SrzM#XS~DK9LQ@ujKm< znQXtv53v;GOVy1|v*`3eF&4;DVN@U(mq5#H1$>qzU;qUuK&ybzIt*7#00lhp=}mm% z69Te=HLH0I0jpY7azF#YWr<~kosz*HA{aNde5)?zB3`@(79qln0%!>=&tN2^w&n#- zF9XP%-Xvo=W6c065loZPXf=ai=>b``x`7d9V+1tlMmJjY6>V0d8e3hiHI(_A_ww4xLt>_{bA7>zOpG4Jh&WIO_r{65yc{F!n{ z520VmR(U^JqD+=2)2035H%I=p?j(ari%Uilolz7fTGO$>bf7gs7~m;xa1#?#koczA z{Ecdo;ZtS0Fejb}3I|XiCuqzWLC~a=bL`BUm%5gfp9sc5_t_o4T&I_q$V8cfF;Jy~ z7Br!q&?iSb%wvM~HfesbHGjkAY%qu#rnDwllp9VrG1EmYc2PIK5*BaBn3^p2+*IonUI`JJd=~AXn#|^UMyP3u;t+x;3DmGSV(Ud{-mMmLEh; z@c2$Q+N z4e0a%5)M=>aX3I6Smjw(DNRig{OnmyYeXoN<_~dO7Y*YwpXhB!Lo%^MKSuEqerD-& zeZWCbDtMU49MLK!SRCLUOGXo{>NrTToNy>A#$7>fqZTD&ttLmT;Up0?w~^CTiVKGS zIXM;$V38o+tndP30+20rG)bk_JJalt&W@|A)_NAyyVnNjlI;p=h3?fyL%#N@{F1G^ z_=`xiRg$V0qE}Qoloy0ubz;*S<%>{sVGD=Ied;@F{V2x1TWZY1cHQM&OH7b{tTJXR z{-us^iDI~-tgqX#&Vf!c9l!#RfqvbN&n%FETCjivvWSg$Nm{CIo-ry?V=|wPPy+#c zK)EM8ty02*lqNngO-^jpXtUhe2x5>aT@j3e%!btA0Z~Hzu&qoipv*~0=oS{Bv(TJ1 zP@nW82@yN=cKOqUh1*0tXOb0L0>K<2dSe(TsgVW8|oN8!&+X0W+#9 zidUY}HBq6FDFlUMv|#cilmHaYgORD~?s&TJ*cWz$tPc>!rY}q`$iMpG3xe3S>j59Q zV7i7dfB%bYsaiE*%eG`Et+zc+%E)`v_E^cd7t5B#_{41G_O|CL5SX=9u5o1yB$&RczPT@o%r}wXt7a0%x2!;}t5RD&7=bJQI?zGqK=YK# z`e`Z3f`K2LiC+JSuBHq`pfb%4-|uWEk4*}X&D_E*L(Vj>MQtQ}dR?J?!M0p?G~2lP z<;Xz>zFrf0USA@WYz9M8*(Q>(Cr3OH5rO!^7>0byB-T}5db>xPm$8cz@{y0smE5l^ z_qYin`gON^^}S3$>rHPEcFSH`sfJQXs`EepEoMuyn1%p$q64bn$%zp>3l2WxS<&3! z0~H{0)g{iSlehNEGj6Vjda|d6vS)fN7H+7wdS?h@=@y6bW_!rQ z9e-ssLX%jsAPWK@3$GvxR!0;Q)JA?#TAvjs3&4L(krjMG1E(MW3!nmoHh!Iz6n^ko zg5zb~*L_^3Wotq>PBa=^rWB*~Gz$P{XI6Mr^&tH~i=%M=3!^|Ot+p4tbs$wxOjYn{ zx1j?Ar$KPiO_uf>lXEO+Aatk^9Km7&VDM15(M8(CIAIhxh%*~HA&fjBG|;jDG|&Yf zkOmY`jytde6;K0FRs+Ci1OTT40^kgXs46OO3_NjAaCQuhVF8apXIXMHlah9)GZJp` zF6nY$ap7S4fpYXQA@cDkM`%OE<}byTFH9JOO^A1RSCI>*Nf_oAjz?if@<}j4N@hhe zVYM+4l0KcMdfz67@B@de_hK&wZ|4SM?_-BVqJ}TFVxs46tOtkgHk3FSGkrBjZ&6e3 zH9$dg82-j@{Dwe`Q5b&k8LSdET+uX8&=Yq;6*tiT1uWnVuTW5Cv3-IwfY*nLfRJ&r zGH9phWq<&F--n8!*ff7oW@pwQ&2wuJMvFoyDKBv@&oVc^RY3=z0UeNX5Cmy3DrvB3 zn-*|7K$}IT6F8s(uRvsmh>t{J6Cwdv!YLv4u^{0>5{Obee&lzKVm90&Nd1s(K)8N5 zWiPoiJP?V5O7%P**=(CcJq@EU36n~Ymw7=FOX#^i*M>4~6^3?LlQRi>J6VT9*=}Yi zd+^4F$5|_e5c~g9PW)!9o zCSHMls|HlL-}Zu?1Y2P#+o33{#2szC9B#s8;b)_Uc4($j6$qdLGLb{egP`h>PlI8L%hW&z#i7q)L3{RCni*&xxD*n_ zjKYy<#o|SnX>^;JjZC*u*C-Y$Km+SoraREFW=f`-wvKxGj*w`9MuxI^paWm9Sg{d} zng#~(SPK~-2GNiK{3e0}FgJt+6K#fT2g0D@LPK^TL;oR!&hu2orbs}jgloo^23BB8 zd$h*3V3bNC5~iuMRAD04VOZ$@h5FM~qnAHsh=y^gp0 z2PI$%Ka&$+69=n88yA-*$tO5nHkp7Bqw(rx!$+5|l8UVYba>$O+dEzH7L<4RhmL(tt6QBZa zPz#^d6gjtw$rlG!aIU~nXtSbmY9g1Tp_X1&XsCN=mu1nFFhchdxfu*;R2iEHv$nsDcC1{Rw18Kko z7qA9GkOblDnn6(i1F{UWX+Wm1X$0%bv2Xgm2&7Ohs{^%Q0MSqjhbRlRFtb!Z1p(C< zju2#3B3S+^khYa(h@_p4B1w|UsCmaP-P}CwAu!#nW|Nvp+MG!z5|aNSlHU_bB&<~{ z8Dg@ep4nz3x}>TqET2W0&vaYEINY~FOt(6mx35~aa9g)?dos2<(0bIz z*#UE%r^O{I3-ARfivTd7OtPQ?KI05ka?HhC%+4UpRWiVnlGJJ^J3GkK^gL#iG2&YxE)pC(HXQi<%Kj{ z;RZZ077HMjreFYx%@ZvBG-(P)-P)c4|CNdDYm}p!4YA$Q`uYQ_9?^P)Iw@zIMTk^Q6>JrZcWMTtl4Pliw~Q+Ow3NzZ zCI48_6m11Q(SMHB(_#@8FVq!ZAx@P`0>aD~XS@K(;8{zt0C$pedhia%kS0eHx}gaF zeshevKbOa0rpG|tSyZt^qM--NcZ}I|jC69;fO!`(VI{WJ5AG+BhT*4CEKpk^$+Pi6 zE^8}*u*dKEu3`;Yjx({&=UrZ zI?wZjj!g81OfaEa)!kcw)sJ2wPX9+nT*o;?fhTu@m*EJ;-VkI&@d~FN4WH}(LgFL? zdf*KzkS3G9eV^#dFbb43A-A==v^dR^ zqD<e3m57mMEj*m?0HNbglf3^&SV+Skl|Pcx3|)c3X8qp3#?hYYRww{`#ACAx{^m9{ssB}_2$!ucb~p}d-U_` zv%f!{{`;-%&)F0{k;NEcOyEWqcjPh06+;BFM;~|8@kSkSw2{Xc zixl$2KDZlafIgn2lDj@En9>p|`_R%E>0V(DF1V^V-~bbDg24(4o7T1Vd>hn{2|tFPdQTNz#`FLSTW9KG?ws zC~)w@q>p9@Zic6xD(VjeOgLfzXZk^JJoR9;1iM>~G3yrpUEhieh650iYt;ozGa-(F z@+zt*mPXx+CCK=C42{M5l(w>#t~E?DzW7Q*wjegc?29z)s-c74daD7cFTh9_H+PQ! zV~24?I~NS97C5)J1lRbO=*Tx3JSPtgyIp&yw}9@=w0_@LNw} z^8VWxzm4}>FJtvSPVYSWDh}D=lsOKtK>G}Yd7K3cOi*S7$%F7h2sPBuLkfAu&}X58 z7W%;$UF?uXB%5?F>7{d=QO6pS{Ek5sZrB(WBf>#nQ*I_n>;gp%wmpVZPyOVrHZ z7GB-L!Pf(XT0l)-2l`b8JQpbQ*I(W6W;$mU$Y5^&g#MTSrUhhp<=~7Am-;2J_;DHxn}4h2pyoXqKeB&Cn|QRo{Ig5R-G|@v4B)kaIh zh&pSON!x zBpqLlM=esB;8b&&3Jol9pWeA=E0*9&KPIsjE3C~5W>n*u7Vrv8LM3+EYY9#CG6MuG zMGuR@i(VYln8R?dS(ls4Wp>a3*{lzKHAo+3ZlfC3oMtqt@eOO>1qRuCVF$FiAO4V+ z8g=PF0GYby{*3TOoj67Z2Rm3qeAO%evy5UCS9zewG8RIQX{=+hdg#bj2vLf@tb`!L zPYOL4QH$BEW-*iDM^$JuouS7Ubx<{Q(AUU;zx8QW_zGM785KqoUu$^p_yEsWHpD96(aAWlb=Bi!H!O@ZYrEC8$R1n32m z;N31^^|G*xV@+<5g$~LTFs88ovM9|;R$qF87wsiRT63uuW02XC!n8yWM<~~9@=$|3 ztj1iYVGTKZQ<`%H!8N#9=ltaLK6v`3RLJ|63HC>uS2S(`RMALh2Xe=`9DuC%%^w0~ zA&cl3RCfu*SOp(iu>i4bEEm%tMLQZ%5iVF{=b0@>Z$?s(jgc*7u4 z=@Btx!=agorbVQXkAx^A72&99JDQOa!=^>BxuS|h?a?G`d{i7cbxBqbCvZAx$c%oLTYorijoWtuQzS8r(3D zKRCk;6EMj^{(z7L=s^ts3qS)R++kUsc+Mx5)TBY`x|7cN1i7%AK^^;a$vc*DAdb?T z=~x1oWCe#Yr6LsqKA?h8bWAM0>jzji#uY97(u{IjKoI7F5M%z9FUeA7QI55jXXY<2 z$3WSfUfx9Cr;9=CJ2nl*LKBK&I)`N*sFOBJ2wMPBOE)Orwxj}5TJts z=%BrPYo<_+hmtV&?ErDB!UE0W3=2fZ8E*6MfBus)4oVoo6D^Ru1!PftYqW$GmLb4N z+CmCz$ioB2nTI(26KM=oFg5ml}9MJh2cs|+-CA4c&d6;#0rTrQK{D%Yzw;qhCUIoo0_NAx3J4xuvUdL5OaYC%f21C0dmBBsD2hJ>%{rDbb7G z=dKlo8>HbfX;|ND%=Nzey{6c?DK=7$VC~y1=Go)CKxq7xu6nU%zT4J;EZz%)SGb{a zdP7OEZgP_~;((3D_d}X;wewq$+B>$?cY@#J?}wV~`2!lyd8A)5d}jq#6}E7CMEX&Y zS{TC+LVv>lRT`lW5z*o*o_L9MSW~2x=tW1G8q$(9)SNo8r$kyg8xgq^aVn7;GOQ^; zCL+M6%8?*bDg#`i0YtJbqPeT$A`5T?w>X=2%K!s_o4x@nE0`lR>Kr|)BVWlA8i0#A zS}c)ZoHvUzH*h1%LL?cu1A91t8-TM%Sr$NJ9WKO=4;NCQnbE}#i$xA2sRTeNlybPBc`1l%I1}rk7JD%uYB4Ng#;0Mw|AQ(VW5BOr zs-`lsrBSK{Ou&)jv6nlNmTM9qLpdut5~j+=2DCu4vA`=~H!NwGoogEl7=SbiIxab- zpnHqTS-}(ZvIB5~S0FkWfTU@FfuL{$H{gZNS^ydJh&js$LkI^Gpn*`JFQJf$JGuxN z5WxfZxr>NGPdpx)fC3BHx+J6tN6;-xkc*8J2^c7>;~5O0C<=gC9yCA|Qb8?BbO!AI zFb`PCgnkf1h6x_t$tt8H2pu3T#*nqWxXB}^7QLv6p=iTCv6fr=i#`zyjG!JsxPfB> zgKwFiG%x|X7^i2;gZ!zNbD1u6Y8PMwj^6;b*n1}dkcAyUCul>S+$)GXBCExb2)Xf` zj=Uol>>C)s0k#+biP?@^(msr-kI1CH0VzLOR4@UF%!xV=QM0#z15FLXMPS6RlFG0S zL%14RMi_Z9qp`o&EFutbv533B8M93uF|r$*z>pKbACbVIqLBl<#^E$a9(yWtEY9Oh zD&6$PZM>1>yvF3LDlVduTFF2z;gWU>i(gVBu;Pw={H0Lemx?~JNWEG@Xj2d8-LWDNZV2#g! zwz-Tp6WD>-`xnk|4IM}x*U+CDs2oeg7nH~oUkN^x5I3|szH?K)E32&oBQSr{H}eQM z{t&4;rKrk8IP#03Tns;5JUD{WMPR%T32CVkbH>m^G7L1!2!3n&x0c`IP;6^fvT{!BCYWPyg9f%=pPG!Pi969ra?11&g)KLAjopaEB@ z2}Ga*)^VMhKmfhEoHCh-1xO>-5!RC!g=3&BoA9#2QWOS#2}rVxOGB-b5QyNyJ6NJb z8W;uHf~{B?p4ys(Nw|f%_!q^KwTEpAsYDD|1Fgx!N{Ee&pm?;%UpwR%eg_Z#V!%IEIn%20Ty&naC91 z)0D-T0Ynf53;2U=H~<;|R=cVNHvp_Z5UeI-P=g#dG(cB_TvrGs-cfLd#~?mCI;&&x zG8o_s1h}+nAzr=ei^h9crywmOP_3-81QTt({KzVSSrq~QP(xV4pQ$Xa9KEbe@=@y{ zuA00oAVq^N7@zkkA22W%*GnFDk)Nc1mw3t-FgTvhxVA-Hj0@09*4P1A2$%qx7BKiH zBM<;1xZMR%3KP(XVeK-MxQGMr12&2>XJC#r=_Ol&7+V@J%@jXC6;$vWDPGiCd<)GQ z-bMARVPE{y4Jj$H1!AHRVw^&f{FBrVLED;InrZaE95dCv?GYkU$51WKbp%czyRni> z)h$k{BfHxL9Mu3^xd0?p=3KybqQmm-)3_t@r5Q7pRhmSyrS1=QT7zr)^zy%nffl7b^7D%8OaL-zRf7O7kohX0o)sivwR773~c!+UYw4 zID!vAn46m|T(X2+$||_XAKplwC%xFD(8{7XEmfK?8eJx>1X4g49a_5#u_VjwLN??n z(zPr$hOMrXwF}B(7qR?})mRMMkr(#~0#e|B#i7zwIf7Hz4fGwRJ{bzV8M@yizP`B$ z9QY0fDnn9iEr}AL2Yca&#zoBBMLwnBSd?fO7R{Lv+k#8DAchbdBC!$kVHAU!8#yAj z9g-LWn-{s%mR7(aX`&+gV&4Q~zf}?~CRM!u1!La4Tb)j-Z5-Sx_FFN&X`vEax(!^V zrcSeYptQkGIMv5rdJ^LUNrQ3*g6t(>b(IAW19}jHRmcE(IEJ^%05OP$P51+P*dqf- zBr!MysEdPcRe||pvqSKN19*oCkO5hk2pJFq7|?JB%Wym@RR#~Q2b0t{10qW(Aqum{4hL}l+h~#OFdn%Yd zX_dK4j7qCQY|GK$+HI~Jt|2uQ+9Qq9=z!Hr=axN70j91Qc(&G41JsH3 zQ>q2O7{1zG^r-YBI2aOJV%(6ED(SJUkW4`06{EO|bE0XKnwC!D*^H`}K5DNaeRO&J2;==XDbaY2ph1IpG&ep+!sX8?)7zHYzf?99}XP|;x z5U97JhiG7dWe|gHFaTh61Tm17Ih**m!qLP}W`1Xw0)!?dXXz$|^{jm@=!TTobC+87J?r&akEiTJ00fq|re^oR|P z(%QCFYM$QC(VTEK!H|K?$OCxU40ZYz&Mx(1LoXvh1L|F8+*oJRK?6yAXSrh8Hku!06H4;ph}LVl{}jlbO9Zta7XRLdq(cmnEyl;>pdR|mDsGbe zj@>vW3x*(={Ews%4Jzw>Dh?ds#rG)hA1^e+yb|15e}Xx(!mnm6in_yE9(D0|$r$x1D1f z06Y!?YLOR0TK;tI)zmz=>OahuoE>u)Gdw`MU#NpbRZq#9c@ilsq7u=Oj?nSZa~>2A zZ)GdoBIoNywjB-8SLfgin=wE`)U_<*Ie$najS(_oWTU}OdOl>D+Q;hK-xs4Eb5lYJ zj{up6Ljmj6Nu(rbo@q?pG1Y)a6@9`#vt`QCw^4e-#hjrusd;JFF>%A{;vH zKTc)UG9}aLoWTq(^UoFM4O!x(7L6QSyQHBG8TyQ>iz&h+y_XszdA!aRo2(Xfv7L;F zcV9ZDEf+1k%x;9WAu_cM$n5|##KwCj@~m4@9JBzfKuuFf~h2 z#4CRYt-T@krZ1mbscO&mr<~d-WZ;!xxozyBgz;U6 z7M6w*Stjkr*I3HpiV&c=*PGCwlMk%r;+>7hX-o)>@ANS*bE6HoQthJ+{frkFh*0H8 z>?jLX>`iG{lCXNky*NHaA`Ab@0x-bztRC*=ZwDLo{dD`Md)$W8&4<%9mB}BNzSXjP zoSpxQ8M%Ae@kMAx8bu|HdqA@iP7exM(f_8%^82%pmx(ESi^!_$XcX)~!2*-X@v*rn zl8-blQkq`Vie@zO>+Wo+XnokpRFToFNzpvKsL7I*=>_E#Tz_C0cV)`9Q0J0I319&0ZJ>>c(0XWCGa@_XuU#k_K$|JgFQ zY#+d46li^(>ltZX$G!zPOt$l0xGlFh&}rHH&Q65H%GUF2TIS7>&820zP{*_i+o)nD z?@WUblS%_M4W|&1I&qhOgLVu!dYld(7y&S(j8nN)QCW{xiO-NHl$1hgL;NfGtJctn z0&MGLV5ATCNE?psw;HeFfC2RAn96f4ih)XV5@dYvMlfrsSY}k1soZ+jho=rfLe2U! z{jrFUSmguq?QnL($C42$d71LjZg*-AtOj33g8n082xGr)?_R7{BXVi_nC#HTbVl;~Zym{iw|y69ldj5+5l>(}z}b zn%oZ2lA_2mkwN@&6mErnbD{+nIWPpEVefMxov#WrU``AKwOmujt0gh!w6$>W zusxlm8~9+){BXit;0INd6#B$8?j+bkI*^a^KTu13ia8Hl4+rgq-W{%@(7VUJ3{+>KOibi}N@F_la9+2hOB)A<8 zz+*uaID;k0aJDfzG>|!;!N859$0+MiV%1T}6cv+jn$Nxgdl!a4*Lj>0=q=2!N1OZr z4Fs!ebnza+sAVfEL6?&dX@^N!kKa{caaf9{~bt$7}rYrWiXPpAgHo|1!nXP zNsFxt05wFPK)2GVH-s2sUQ}^nDvKpO0A&i19x{wt6mJ;v+JG2Z{gSzVh`PX+54phN zi)|U=vfG>d##gDs&=R>MZ(%&2%5iqANi=%+%qVs1iyO6z~02nrbt> zBlihsha*m~1q)&t0I4$^^V%GW6S0~msLS4RLB{~#|C?`$QC#Uq1d*aj&ztPtGVJs`LA|uakBXAw2L3|9HFO*yR5Byye&# zV%uqrx(EHvGRNlxKN8#Syw-01i0~>~tpYVm`Y~JOMn9}xSIo$7RF(&_Fl@SSomnI$ z%ACprhM%&WPUU;!7Ve!1Utz>S5CJ%=0GM%$4=Lz-24qSYSqELm( zzU^wxp1Ux7)e=i=l|l(V*&J6YSYYx_sp9{QDAuvVrQDv3k;oi?;|kYHb$;jR7SWAQz6TyByVccx)-^yHrC2*VX=G zNYoi-ZrM>i()pV6j@6<(Vt%sudWBbdT4Ms z`mUP27Lvvy+frgsEhK0nfnksj^#UEGk7|GDX5i!_RQETax` zrbr;f1pUs;h{3>6pEqO^4e46Q^#4L29&M7OnpnJF-V~ktI;oGya%Q}@Kk_X?Em;#Df?}zf&c5Cbm>UHuusz#_qf#=ZE%@{q1ANu@p4@%L z#K^g0D7sIE)N3RuTgm(LCy0TcTH`rD+LyfW**+L8j=({tjEi2~lAa+5^{UItY+^1x z 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%0D|3Opu8UG> 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 z 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%0DxCHtl}Iqkk-CJ4lZe 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%0DJ(#v>s?ByzUOJ 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

5RHN*Pj2np8rgR2E8z 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