Rework of "Service" types to allow for validation

Each service supports basic validation params, plus has the option for an entirely custom validation function.

Initial validation settings:
- IMAGE must be less than 10MiB
- THUMBNAIL must be less than 500KiB
- METADATA must be less than 10KiB and must contain JSON keys "title", "description", and "tags"
This commit is contained in:
CalDescent
2021-11-16 19:28:25 +00:00
parent 9c952785e6
commit fb09d77cdc
25 changed files with 266 additions and 51 deletions

View File

@@ -6,8 +6,7 @@ import org.junit.Before;
import org.junit.Test;
import org.qortal.api.resource.ArbitraryResource;
import org.qortal.api.resource.TransactionsResource.ConfirmationStatus;
import org.qortal.data.transaction.ArbitraryTransactionData;
import org.qortal.data.transaction.ArbitraryTransactionData.Service;
import org.qortal.arbitrary.misc.Service;
import org.qortal.test.common.ApiCommon;
public class ArbitraryApiTests extends ApiCommon {
@@ -24,7 +23,7 @@ public class ArbitraryApiTests extends ApiCommon {
Integer[] startingBlocks = new Integer[] { null, 0, 1, 999999999 };
Integer[] blockLimits = new Integer[] { null, 0, 1, 999999999 };
Integer[] txGroupIds = new Integer[] { null, 0, 1, 999999999 };
ArbitraryTransactionData.Service[] services = new Service[] { Service.WEBSITE, Service.GIT_REPOSITORY, Service.BLOG_COMMENT };
Service[] services = new Service[] { Service.WEBSITE, Service.GIT_REPOSITORY, Service.BLOG_COMMENT };
String[] names = new String[] { null, "Test" };
String[] addresses = new String[] { null, this.aliceAddress };
ConfirmationStatus[] confirmationStatuses = new ConfirmationStatus[] { ConfirmationStatus.UNCONFIRMED, ConfirmationStatus.CONFIRMED, ConfirmationStatus.BOTH };

View File

@@ -9,6 +9,7 @@ import org.qortal.arbitrary.ArbitraryDataReader;
import org.qortal.arbitrary.ArbitraryDataTransactionBuilder;
import org.qortal.arbitrary.exception.MissingDataException;
import org.qortal.arbitrary.metadata.ArbitraryDataMetadataPatch;
import org.qortal.arbitrary.misc.Service;
import org.qortal.crypto.Crypto;
import org.qortal.data.transaction.ArbitraryTransactionData;
import org.qortal.data.transaction.ArbitraryTransactionData.*;

View File

@@ -0,0 +1,67 @@
package org.qortal.test.arbitrary;
import org.junit.Before;
import org.junit.Test;
import org.qortal.arbitrary.misc.Service;
import org.qortal.arbitrary.misc.Service.ValidationResult;
import org.qortal.repository.DataException;
import org.qortal.test.common.Common;
import java.util.Random;
import static org.junit.Assert.*;
public class ArbitraryServiceTests extends Common {
@Before
public void beforeTest() throws DataException {
Common.useDefaultSettings();
}
@Test
public void testDefaultValidation() {
// We don't validate websites yet, but we still want to test the default validation method
byte[] data = new byte[1024];
new Random().nextBytes(data);
Service service = Service.WEBSITE;
assertFalse(service.isValidationRequired());
// Test validation anyway to ensure that no exception is thrown
assertEquals(ValidationResult.OK, service.validate(data, data.length));
}
@Test
public void testValidMetadata() {
// Metadata is to describe an arbitrary resource (title, description, tags, etc)
String dataString = "{\"title\":\"Test Title\", \"description\":\"Test description\", \"tags\":[\"test\"]}";
byte[] data = dataString.getBytes();
Service service = Service.METADATA;
assertTrue(service.isValidationRequired());
assertEquals(ValidationResult.OK, service.validate(data, data.length));
}
@Test
public void testMetadataMissingKeys() {
// Metadata is to describe an arbitrary resource (title, description, tags, etc)
String dataString = "{\"description\":\"Test description\", \"tags\":[\"test\"]}";
byte[] data = dataString.getBytes();
Service service = Service.METADATA;
assertTrue(service.isValidationRequired());
assertEquals(ValidationResult.MISSING_KEYS, service.validate(data, data.length));
}
@Test
public void testMetadataTooLarge() {
// Metadata is to describe an arbitrary resource (title, description, tags, etc)
String dataString = "{\"title\":\"Test Title\", \"description\":\"Test description\", \"tags\":[\"test\"]}";
byte[] data = dataString.getBytes();
long totalResourceSize = 11*1024L; // Larger than allowed 10kiB
Service service = Service.METADATA;
assertTrue(service.isValidationRequired());
assertEquals(ValidationResult.EXCEEDS_SIZE_LIMIT, service.validate(data, totalResourceSize));
}
}

View File

@@ -3,6 +3,7 @@ package org.qortal.test.arbitrary;
import org.junit.Before;
import org.junit.Test;
import org.qortal.arbitrary.misc.Service;
import org.qortal.data.PaymentData;
import org.qortal.data.transaction.ArbitraryTransactionData;
import org.qortal.repository.DataException;
@@ -36,7 +37,7 @@ public class ArbitraryTransactionTests extends Common {
TestAccount alice = Common.getTestAccount(repository, "alice");
ArbitraryTransactionData.DataType dataType = ArbitraryTransactionData.DataType.DATA_HASH;
ArbitraryTransactionData.Service service = ArbitraryTransactionData.Service.ARBITRARY_DATA;
Service service = Service.ARBITRARY_DATA;
ArbitraryTransactionData.Method method = ArbitraryTransactionData.Method.PUT;
ArbitraryTransactionData.Compression compression = ArbitraryTransactionData.Compression.NONE;
List<PaymentData> payments = new ArrayList<>();

View File

@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import org.qortal.account.PrivateKeyAccount;
import org.qortal.arbitrary.misc.Service;
import org.qortal.asset.Asset;
import org.qortal.data.PaymentData;
import org.qortal.data.transaction.ArbitraryTransactionData;
@@ -17,7 +18,7 @@ public class ArbitraryTestTransaction extends TestTransaction {
public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException {
final int version = 5;
final ArbitraryTransactionData.Service service = ArbitraryTransactionData.Service.ARBITRARY_DATA;
final Service service = Service.ARBITRARY_DATA;
final int nonce = 0;
final int size = 4 * 1024 * 1024;
final String name = "TEST";