mirror of
https://github.com/Qortal/qortal.git
synced 2025-04-23 19:37:51 +00:00
Rework of service validation, to allow a service to be specified as a single file resource.
This removes some complexity and duplication from custom validation functions. Q-Chat QDN functionality will need a re-test.
This commit is contained in:
parent
ac60ef30a3
commit
d6ab9eb066
@ -19,9 +19,9 @@ import static java.util.Arrays.stream;
|
|||||||
import static java.util.stream.Collectors.toMap;
|
import static java.util.stream.Collectors.toMap;
|
||||||
|
|
||||||
public enum Service {
|
public enum Service {
|
||||||
AUTO_UPDATE(1, false, null, null),
|
AUTO_UPDATE(1, false, null, false, null),
|
||||||
ARBITRARY_DATA(100, false, null, null),
|
ARBITRARY_DATA(100, false, null, false, null),
|
||||||
QCHAT_ATTACHMENT(120, true, 1024*1024L, null) {
|
QCHAT_ATTACHMENT(120, true, 1024*1024L, true, null) {
|
||||||
@Override
|
@Override
|
||||||
public ValidationResult validate(Path path) throws IOException {
|
public ValidationResult validate(Path path) throws IOException {
|
||||||
ValidationResult superclassResult = super.validate(path);
|
ValidationResult superclassResult = super.validate(path);
|
||||||
@ -29,37 +29,24 @@ public enum Service {
|
|||||||
return superclassResult;
|
return superclassResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom validation function to require a single file, with a whitelisted extension
|
|
||||||
int fileCount = 0;
|
|
||||||
File[] files = path.toFile().listFiles();
|
File[] files = path.toFile().listFiles();
|
||||||
// If already a single file, replace the list with one that contains that file only
|
// If already a single file, replace the list with one that contains that file only
|
||||||
if (files == null && path.toFile().isFile()) {
|
if (files == null && path.toFile().isFile()) {
|
||||||
files = new File[] { path.toFile() };
|
files = new File[] { path.toFile() };
|
||||||
}
|
}
|
||||||
if (files != null) {
|
// Now validate the file's extension
|
||||||
for (File file : files) {
|
if (files != null && files[0] != null) {
|
||||||
if (file.getName().equals(".qortal")) {
|
final String extension = FilenameUtils.getExtension(files[0].getName()).toLowerCase();
|
||||||
continue;
|
// We must allow blank file extensions because these are used by data published from a plaintext or base64-encoded string
|
||||||
}
|
final List<String> allowedExtensions = Arrays.asList("zip", "pdf", "txt", "odt", "ods", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "");
|
||||||
if (file.isDirectory()) {
|
if (extension == null || !allowedExtensions.contains(extension)) {
|
||||||
return ValidationResult.DIRECTORIES_NOT_ALLOWED;
|
return ValidationResult.INVALID_FILE_EXTENSION;
|
||||||
}
|
|
||||||
final String extension = FilenameUtils.getExtension(file.getName()).toLowerCase();
|
|
||||||
// We must allow blank file extensions because these are used by data published from a plaintext or base64-encoded string
|
|
||||||
final List<String> allowedExtensions = Arrays.asList("zip", "pdf", "txt", "odt", "ods", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "");
|
|
||||||
if (extension == null || !allowedExtensions.contains(extension)) {
|
|
||||||
return ValidationResult.INVALID_FILE_EXTENSION;
|
|
||||||
}
|
|
||||||
fileCount++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fileCount != 1) {
|
|
||||||
return ValidationResult.INVALID_FILE_COUNT;
|
|
||||||
}
|
|
||||||
return ValidationResult.OK;
|
return ValidationResult.OK;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
WEBSITE(200, true, null, null) {
|
WEBSITE(200, true, null, false, null) {
|
||||||
@Override
|
@Override
|
||||||
public ValidationResult validate(Path path) throws IOException {
|
public ValidationResult validate(Path path) throws IOException {
|
||||||
ValidationResult superclassResult = super.validate(path);
|
ValidationResult superclassResult = super.validate(path);
|
||||||
@ -81,23 +68,23 @@ public enum Service {
|
|||||||
return ValidationResult.MISSING_INDEX_FILE;
|
return ValidationResult.MISSING_INDEX_FILE;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
GIT_REPOSITORY(300, false, null, null),
|
GIT_REPOSITORY(300, false, null, false, null),
|
||||||
IMAGE(400, true, 10*1024*1024L, null),
|
IMAGE(400, true, 10*1024*1024L, true, null),
|
||||||
THUMBNAIL(410, true, 500*1024L, null),
|
THUMBNAIL(410, true, 500*1024L, true, null),
|
||||||
QCHAT_IMAGE(420, true, 500*1024L, null),
|
QCHAT_IMAGE(420, true, 500*1024L, true, null),
|
||||||
VIDEO(500, false, null, null),
|
VIDEO(500, false, null, true, null),
|
||||||
AUDIO(600, false, null, null),
|
AUDIO(600, false, null, true, null),
|
||||||
QCHAT_AUDIO(610, true, 10*1024*1024L, null),
|
QCHAT_AUDIO(610, true, 10*1024*1024L, true, null),
|
||||||
QCHAT_VOICE(620, true, 10*1024*1024L, null),
|
QCHAT_VOICE(620, true, 10*1024*1024L, true, null),
|
||||||
BLOG(700, false, null, null),
|
BLOG(700, false, null, false, null),
|
||||||
BLOG_POST(777, false, null, null),
|
BLOG_POST(777, false, null, true, null),
|
||||||
BLOG_COMMENT(778, false, null, null),
|
BLOG_COMMENT(778, false, null, true, null),
|
||||||
DOCUMENT(800, false, null, null),
|
DOCUMENT(800, false, null, true, null),
|
||||||
LIST(900, true, null, null),
|
LIST(900, true, null, true, null),
|
||||||
PLAYLIST(910, true, null, null),
|
PLAYLIST(910, true, null, true, null),
|
||||||
APP(1000, false, null, null),
|
APP(1000, false, null, false, null),
|
||||||
METADATA(1100, false, null, null),
|
METADATA(1100, false, null, true, null),
|
||||||
JSON(1110, true, 25*1024L, null) {
|
JSON(1110, true, 25*1024L, true, null) {
|
||||||
@Override
|
@Override
|
||||||
public ValidationResult validate(Path path) throws IOException {
|
public ValidationResult validate(Path path) throws IOException {
|
||||||
ValidationResult superclassResult = super.validate(path);
|
ValidationResult superclassResult = super.validate(path);
|
||||||
@ -105,13 +92,6 @@ public enum Service {
|
|||||||
return superclassResult;
|
return superclassResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
File[] files = path.toFile().listFiles();
|
|
||||||
|
|
||||||
// Require a single file
|
|
||||||
if (files != null || !path.toFile().isFile()) {
|
|
||||||
return ValidationResult.INVALID_FILE_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Require valid JSON
|
// Require valid JSON
|
||||||
String json = Files.readString(path);
|
String json = Files.readString(path);
|
||||||
try {
|
try {
|
||||||
@ -122,7 +102,7 @@ public enum Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
GIF_REPOSITORY(1200, true, 25*1024*1024L, null) {
|
GIF_REPOSITORY(1200, true, 25*1024*1024L, false, null) {
|
||||||
@Override
|
@Override
|
||||||
public ValidationResult validate(Path path) throws IOException {
|
public ValidationResult validate(Path path) throws IOException {
|
||||||
ValidationResult superclassResult = super.validate(path);
|
ValidationResult superclassResult = super.validate(path);
|
||||||
@ -162,6 +142,7 @@ public enum Service {
|
|||||||
public final int value;
|
public final int value;
|
||||||
private final boolean requiresValidation;
|
private final boolean requiresValidation;
|
||||||
private final Long maxSize;
|
private final Long maxSize;
|
||||||
|
private final boolean single;
|
||||||
private final List<String> requiredKeys;
|
private final List<String> requiredKeys;
|
||||||
|
|
||||||
private static final Map<Integer, Service> map = stream(Service.values())
|
private static final Map<Integer, Service> map = stream(Service.values())
|
||||||
@ -170,10 +151,11 @@ public enum Service {
|
|||||||
// For JSON validation
|
// For JSON validation
|
||||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
Service(int value, boolean requiresValidation, Long maxSize, List<String> requiredKeys) {
|
Service(int value, boolean requiresValidation, Long maxSize, boolean single, List<String> requiredKeys) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.requiresValidation = requiresValidation;
|
this.requiresValidation = requiresValidation;
|
||||||
this.maxSize = maxSize;
|
this.maxSize = maxSize;
|
||||||
|
this.single = single;
|
||||||
this.requiredKeys = requiredKeys;
|
this.requiredKeys = requiredKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,6 +174,11 @@ public enum Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate file count if needed
|
||||||
|
if (this.single && data == null) {
|
||||||
|
return ValidationResult.INVALID_FILE_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
// Validate required keys if needed
|
// Validate required keys if needed
|
||||||
if (this.requiredKeys != null) {
|
if (this.requiredKeys != null) {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
|
@ -241,7 +241,9 @@ public class FilesystemUtils {
|
|||||||
String[] files = ArrayUtils.removeElement(path.toFile().list(), ".qortal");
|
String[] files = ArrayUtils.removeElement(path.toFile().list(), ".qortal");
|
||||||
if (files.length == 1) {
|
if (files.length == 1) {
|
||||||
Path filePath = Paths.get(path.toString(), files[0]);
|
Path filePath = Paths.get(path.toString(), files[0]);
|
||||||
data = Files.readAllBytes(filePath);
|
if (filePath.toFile().isFile()) {
|
||||||
|
data = Files.readAllBytes(filePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,17 +319,15 @@ public class ArbitraryServiceTests extends Common {
|
|||||||
// Write the data to several files in a temp path
|
// Write the data to several files in a temp path
|
||||||
Path path = Files.createTempDirectory("testValidateMultiLayerQChatAttachment");
|
Path path = Files.createTempDirectory("testValidateMultiLayerQChatAttachment");
|
||||||
path.toFile().deleteOnExit();
|
path.toFile().deleteOnExit();
|
||||||
Files.write(Paths.get(path.toString(), "file1.txt"), data, StandardOpenOption.CREATE);
|
|
||||||
|
|
||||||
Path subdirectory = Paths.get(path.toString(), "subdirectory");
|
Path subdirectory = Paths.get(path.toString(), "subdirectory");
|
||||||
Files.createDirectories(subdirectory);
|
Files.createDirectories(subdirectory);
|
||||||
Files.write(Paths.get(subdirectory.toString(), "file2.txt"), data, StandardOpenOption.CREATE);
|
Files.write(Paths.get(subdirectory.toString(), "file.txt"), data, StandardOpenOption.CREATE);
|
||||||
Files.write(Paths.get(subdirectory.toString(), "file3.txt"), data, StandardOpenOption.CREATE);
|
|
||||||
|
|
||||||
Service service = Service.QCHAT_ATTACHMENT;
|
Service service = Service.QCHAT_ATTACHMENT;
|
||||||
assertTrue(service.isValidationRequired());
|
assertTrue(service.isValidationRequired());
|
||||||
|
|
||||||
assertEquals(ValidationResult.DIRECTORIES_NOT_ALLOWED, service.validate(path));
|
assertEquals(ValidationResult.INVALID_FILE_COUNT, service.validate(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user