FINERACT-2246: New command processing - document management
This commit is contained in:
committed by
Aleksandar Vidakovic
parent
8a61e30a45
commit
2ff0c62f40
+44
@@ -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();
|
||||
}
|
||||
}
|
||||
+52
@@ -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());
|
||||
}
|
||||
}
|
||||
+134
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
@@ -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());
|
||||
}
|
||||
}
|
||||
+63
@@ -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:");
|
||||
});
|
||||
}
|
||||
}
|
||||
+170
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+85
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 995 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 741 B |
Reference in New Issue
Block a user