forked from Qortal/qortal
Increased the capabilities of the service validation functions.
This commit is contained in:
parent
94b17eaff3
commit
57e82b62a1
@ -444,11 +444,7 @@ public class ArbitraryDataReader {
|
|||||||
|
|
||||||
private void validate() throws IOException, DataException {
|
private void validate() throws IOException, DataException {
|
||||||
if (this.service.isValidationRequired()) {
|
if (this.service.isValidationRequired()) {
|
||||||
|
Service.ValidationResult result = this.service.validate(this.filePath);
|
||||||
byte[] data = FilesystemUtils.getSingleFileContents(this.filePath);
|
|
||||||
long size = FilesystemUtils.getDirectorySize(this.filePath);
|
|
||||||
|
|
||||||
Service.ValidationResult result = this.service.validate(data, size);
|
|
||||||
if (result != Service.ValidationResult.OK) {
|
if (result != Service.ValidationResult.OK) {
|
||||||
throw new DataException(String.format("Validation of %s failed: %s", this.service, result.toString()));
|
throw new DataException(String.format("Validation of %s failed: %s", this.service, result.toString()));
|
||||||
}
|
}
|
||||||
|
@ -105,11 +105,7 @@ public class ArbitraryDataWriter {
|
|||||||
|
|
||||||
private void validateService() throws IOException, DataException {
|
private void validateService() throws IOException, DataException {
|
||||||
if (this.service.isValidationRequired()) {
|
if (this.service.isValidationRequired()) {
|
||||||
|
Service.ValidationResult result = this.service.validate(this.filePath);
|
||||||
byte[] data = FilesystemUtils.getSingleFileContents(this.filePath);
|
|
||||||
long size = FilesystemUtils.getDirectorySize(this.filePath);
|
|
||||||
|
|
||||||
Service.ValidationResult result = this.service.validate(data, size);
|
|
||||||
if (result != Service.ValidationResult.OK) {
|
if (result != Service.ValidationResult.OK) {
|
||||||
throw new DataException(String.format("Validation of %s failed: %s", this.service, result.toString()));
|
throw new DataException(String.format("Validation of %s failed: %s", this.service, result.toString()));
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
package org.qortal.arbitrary.misc;
|
package org.qortal.arbitrary.misc;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.qortal.arbitrary.ArbitraryDataRenderer;
|
||||||
import org.qortal.transaction.Transaction;
|
import org.qortal.transaction.Transaction;
|
||||||
|
import org.qortal.utils.FilesystemUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -44,20 +49,26 @@ public enum Service {
|
|||||||
this.requiredKeys = requiredKeys;
|
this.requiredKeys = requiredKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationResult validate(byte[] data, long size) {
|
public ValidationResult validate(Path path) throws IOException {
|
||||||
if (!this.isValidationRequired()) {
|
if (!this.isValidationRequired()) {
|
||||||
return ValidationResult.OK;
|
return ValidationResult.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] data = FilesystemUtils.getSingleFileContents(path);
|
||||||
|
long size = FilesystemUtils.getDirectorySize(path);
|
||||||
|
|
||||||
// Validate max size if needed
|
// Validate max size if needed
|
||||||
if (this.maxSize != null) {
|
if (this.maxSize != null) {
|
||||||
if (size > this.maxSize || data.length > this.maxSize) {
|
if (size > this.maxSize) {
|
||||||
return ValidationResult.EXCEEDS_SIZE_LIMIT;
|
return ValidationResult.EXCEEDS_SIZE_LIMIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate required keys if needed
|
// Validate required keys if needed
|
||||||
if (this.requiredKeys != null) {
|
if (this.requiredKeys != null) {
|
||||||
|
if (data == null) {
|
||||||
|
return ValidationResult.MISSING_KEYS;
|
||||||
|
}
|
||||||
JSONObject json = Service.toJsonObject(data);
|
JSONObject json = Service.toJsonObject(data);
|
||||||
for (String key : this.requiredKeys) {
|
for (String key : this.requiredKeys) {
|
||||||
if (!json.has(key)) {
|
if (!json.has(key)) {
|
||||||
@ -86,7 +97,8 @@ public enum Service {
|
|||||||
public enum ValidationResult {
|
public enum ValidationResult {
|
||||||
OK(1),
|
OK(1),
|
||||||
MISSING_KEYS(2),
|
MISSING_KEYS(2),
|
||||||
EXCEEDS_SIZE_LIMIT(3);
|
EXCEEDS_SIZE_LIMIT(3),
|
||||||
|
MISSING_INDEX_FILE(4);
|
||||||
|
|
||||||
public final int value;
|
public final int value;
|
||||||
|
|
||||||
|
@ -7,6 +7,11 @@ import org.qortal.arbitrary.misc.Service.ValidationResult;
|
|||||||
import org.qortal.repository.DataException;
|
import org.qortal.repository.DataException;
|
||||||
import org.qortal.test.common.Common;
|
import org.qortal.test.common.Common;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
@ -19,49 +24,94 @@ public class ArbitraryServiceTests extends Common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultValidation() {
|
public void testDefaultValidation() throws IOException {
|
||||||
// We don't validate websites yet, but we still want to test the default validation method
|
// We don't validate the ARBITRARY_DATA service specifically, so we can use it to test the default validation method
|
||||||
byte[] data = new byte[1024];
|
byte[] data = new byte[1024];
|
||||||
new Random().nextBytes(data);
|
new Random().nextBytes(data);
|
||||||
|
|
||||||
Service service = Service.WEBSITE;
|
// Write to temp path
|
||||||
|
Path path = Files.createTempFile("testDefaultValidation", null);
|
||||||
|
path.toFile().deleteOnExit();
|
||||||
|
Files.write(path, data, StandardOpenOption.CREATE);
|
||||||
|
|
||||||
|
Service service = Service.ARBITRARY_DATA;
|
||||||
assertFalse(service.isValidationRequired());
|
assertFalse(service.isValidationRequired());
|
||||||
// Test validation anyway to ensure that no exception is thrown
|
// Test validation anyway to ensure that no exception is thrown
|
||||||
assertEquals(ValidationResult.OK, service.validate(data, data.length));
|
assertEquals(ValidationResult.OK, service.validate(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidQortalMetadata() {
|
public void testValidQortalMetadata() throws IOException {
|
||||||
// Metadata is to describe an arbitrary resource (title, description, tags, etc)
|
// Metadata is to describe an arbitrary resource (title, description, tags, etc)
|
||||||
String dataString = "{\"title\":\"Test Title\", \"description\":\"Test description\", \"tags\":[\"test\"]}";
|
String dataString = "{\"title\":\"Test Title\", \"description\":\"Test description\", \"tags\":[\"test\"]}";
|
||||||
byte[] data = dataString.getBytes();
|
|
||||||
|
// Write to temp path
|
||||||
|
Path path = Files.createTempFile("testValidQortalMetadata", null);
|
||||||
|
path.toFile().deleteOnExit();
|
||||||
|
Files.write(path, dataString.getBytes(), StandardOpenOption.CREATE);
|
||||||
|
|
||||||
Service service = Service.QORTAL_METADATA;
|
Service service = Service.QORTAL_METADATA;
|
||||||
assertTrue(service.isValidationRequired());
|
assertTrue(service.isValidationRequired());
|
||||||
assertEquals(ValidationResult.OK, service.validate(data, data.length));
|
assertEquals(ValidationResult.OK, service.validate(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQortalMetadataMissingKeys() {
|
public void testQortalMetadataMissingKeys() throws IOException {
|
||||||
// Metadata is to describe an arbitrary resource (title, description, tags, etc)
|
// Metadata is to describe an arbitrary resource (title, description, tags, etc)
|
||||||
String dataString = "{\"description\":\"Test description\", \"tags\":[\"test\"]}";
|
String dataString = "{\"description\":\"Test description\", \"tags\":[\"test\"]}";
|
||||||
byte[] data = dataString.getBytes();
|
|
||||||
|
// Write to temp path
|
||||||
|
Path path = Files.createTempFile("testQortalMetadataMissingKeys", null);
|
||||||
|
path.toFile().deleteOnExit();
|
||||||
|
Files.write(path, dataString.getBytes(), StandardOpenOption.CREATE);
|
||||||
|
|
||||||
Service service = Service.QORTAL_METADATA;
|
Service service = Service.QORTAL_METADATA;
|
||||||
assertTrue(service.isValidationRequired());
|
assertTrue(service.isValidationRequired());
|
||||||
assertEquals(ValidationResult.MISSING_KEYS, service.validate(data, data.length));
|
assertEquals(ValidationResult.MISSING_KEYS, service.validate(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQortalMetadataTooLarge() {
|
public void testQortalMetadataTooLarge() throws IOException {
|
||||||
// Metadata is to describe an arbitrary resource (title, description, tags, etc)
|
// Metadata is to describe an arbitrary resource (title, description, tags, etc)
|
||||||
String dataString = "{\"title\":\"Test Title\", \"description\":\"Test description\", \"tags\":[\"test\"]}";
|
String dataString = "{\"title\":\"Test Title\", \"description\":\"Test description\", \"tags\":[\"test\"]}";
|
||||||
byte[] data = dataString.getBytes();
|
|
||||||
long totalResourceSize = 11*1024L; // Larger than allowed 10kiB
|
// Generate some large data to go along with it
|
||||||
|
int largeDataSize = 11*1024; // Larger than allowed 10kiB
|
||||||
|
byte[] largeData = new byte[largeDataSize];
|
||||||
|
new Random().nextBytes(largeData);
|
||||||
|
|
||||||
|
// Write to temp path
|
||||||
|
Path path = Files.createTempDirectory("testQortalMetadataTooLarge");
|
||||||
|
path.toFile().deleteOnExit();
|
||||||
|
Files.write(Paths.get(path.toString(), "data"), dataString.getBytes(), StandardOpenOption.CREATE);
|
||||||
|
Files.write(Paths.get(path.toString(), "large_data"), largeData, StandardOpenOption.CREATE);
|
||||||
|
|
||||||
Service service = Service.QORTAL_METADATA;
|
Service service = Service.QORTAL_METADATA;
|
||||||
assertTrue(service.isValidationRequired());
|
assertTrue(service.isValidationRequired());
|
||||||
assertEquals(ValidationResult.EXCEEDS_SIZE_LIMIT, service.validate(data, totalResourceSize));
|
assertEquals(ValidationResult.EXCEEDS_SIZE_LIMIT, service.validate(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultipleFileMetadata() throws IOException {
|
||||||
|
// Metadata is to describe an arbitrary resource (title, description, tags, etc)
|
||||||
|
String dataString = "{\"title\":\"Test Title\", \"description\":\"Test description\", \"tags\":[\"test\"]}";
|
||||||
|
|
||||||
|
// Generate some large data to go along with it
|
||||||
|
int otherDataSize = 1024; // Smaller than 10kiB limit
|
||||||
|
byte[] otherData = new byte[otherDataSize];
|
||||||
|
new Random().nextBytes(otherData);
|
||||||
|
|
||||||
|
// Write to temp path
|
||||||
|
Path path = Files.createTempDirectory("testMultipleFileMetadata");
|
||||||
|
path.toFile().deleteOnExit();
|
||||||
|
Files.write(Paths.get(path.toString(), "data"), dataString.getBytes(), StandardOpenOption.CREATE);
|
||||||
|
Files.write(Paths.get(path.toString(), "other_data"), otherData, StandardOpenOption.CREATE);
|
||||||
|
|
||||||
|
Service service = Service.QORTAL_METADATA;
|
||||||
|
assertTrue(service.isValidationRequired());
|
||||||
|
|
||||||
|
// There are multiple files, so we don't know which one to parse as JSON
|
||||||
|
assertEquals(ValidationResult.MISSING_KEYS, service.validate(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user