Added custom validation for websites.

A website must contain one of the following files in its root directory to be considered valid:

index.html
index.htm
default.html
default.htm
home.html
home.htm

This is the first page that is loaded when loading a Qortal-hosted website.
This commit is contained in:
CalDescent 2021-12-05 13:30:10 +00:00
parent 57e82b62a1
commit b592aa6a02
7 changed files with 90 additions and 13 deletions

View File

@ -134,7 +134,7 @@ public class ArbitraryDataRenderer {
private String getFilename(String directory, String userPath) { private String getFilename(String directory, String userPath) {
if (userPath == null || userPath.endsWith("/") || userPath.equals("")) { if (userPath == null || userPath.endsWith("/") || userPath.equals("")) {
// Locate index file // Locate index file
List<String> indexFiles = this.indexFiles(); List<String> indexFiles = ArbitraryDataRenderer.indexFiles();
for (String indexFile : indexFiles) { for (String indexFile : indexFiles) {
String filePath = directory + File.separator + indexFile; String filePath = directory + File.separator + indexFile;
if (Files.exists(Paths.get(filePath))) { if (Files.exists(Paths.get(filePath))) {
@ -173,7 +173,7 @@ public class ArbitraryDataRenderer {
return response; return response;
} }
private List<String> indexFiles() { public static List<String> indexFiles() {
List<String> indexFiles = new ArrayList<>(); List<String> indexFiles = new ArrayList<>();
indexFiles.add("index.html"); indexFiles.add("index.html");
indexFiles.add("index.htm"); indexFiles.add("index.htm");

View File

@ -18,7 +18,23 @@ import static java.util.stream.Collectors.toMap;
public enum Service { public enum Service {
AUTO_UPDATE(1, false, null, null), AUTO_UPDATE(1, false, null, null),
ARBITRARY_DATA(100, false, null, null), ARBITRARY_DATA(100, false, null, null),
WEBSITE(200, false, null, null), WEBSITE(200, true, null, null) {
@Override
public ValidationResult validate(Path path) {
// Custom validation function to require an index HTML file in the root directory
List<String> fileNames = ArbitraryDataRenderer.indexFiles();
String[] files = path.toFile().list();
if (files != null) {
for (String file : files) {
Path fileName = Paths.get(file).getFileName();
if (fileName != null && fileNames.contains(fileName.toString())) {
return ValidationResult.OK;
}
}
}
return ValidationResult.MISSING_INDEX_FILE;
}
},
GIT_REPOSITORY(300, false, null, null), GIT_REPOSITORY(300, false, null, null),
IMAGE(400, true, 10*1024*1024L, null), IMAGE(400, true, 10*1024*1024L, null),
THUMBNAIL(410, true, 500*1024L, null), THUMBNAIL(410, true, 500*1024L, null),

View File

@ -137,7 +137,7 @@ public class ArbitraryDataStorageCapacityTests extends Common {
public void testDeleteRandomFilesForName() throws DataException, IOException, InterruptedException { public void testDeleteRandomFilesForName() throws DataException, IOException, InterruptedException {
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
String identifier = null; // Not used for this test String identifier = null; // Not used for this test
Service service = Service.WEBSITE; // Can be anything for this test Service service = Service.ARBITRARY_DATA;
int chunkSize = 100; int chunkSize = 100;
int dataLength = 900; // Actual data length will be longer due to encryption int dataLength = 900; // Actual data length will be longer due to encryption

View File

@ -234,7 +234,7 @@ public class ArbitraryDataStoragePolicyTests extends Common {
Path path = Paths.get("src/test/resources/arbitrary/demo1"); Path path = Paths.get("src/test/resources/arbitrary/demo1");
ArbitraryDataTransactionBuilder txnBuilder = new ArbitraryDataTransactionBuilder( ArbitraryDataTransactionBuilder txnBuilder = new ArbitraryDataTransactionBuilder(
repository, publicKey58, path, name, Method.PUT, Service.WEBSITE, null); repository, publicKey58, path, name, Method.PUT, Service.ARBITRARY_DATA, null);
txnBuilder.build(); txnBuilder.build();
ArbitraryTransactionData transactionData = txnBuilder.getArbitraryTransactionData(); ArbitraryTransactionData transactionData = txnBuilder.getArbitraryTransactionData();

View File

@ -48,7 +48,7 @@ public class ArbitraryDataTests extends Common {
String publicKey58 = Base58.encode(alice.getPublicKey()); String publicKey58 = Base58.encode(alice.getPublicKey());
String name = "TEST"; // Can be anything for this test String name = "TEST"; // Can be anything for this test
String identifier = null; // Not used for this test String identifier = null; // Not used for this test
Service service = Service.WEBSITE; // Can be anything for this test Service service = Service.ARBITRARY_DATA;
// Register the name to Alice // Register the name to Alice
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, ""); RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "");
@ -96,7 +96,7 @@ public class ArbitraryDataTests extends Common {
String publicKey58 = Base58.encode(alice.getPublicKey()); String publicKey58 = Base58.encode(alice.getPublicKey());
String name = "TEST"; // Can be anything for this test String name = "TEST"; // Can be anything for this test
String identifier = null; // Not used for this test String identifier = null; // Not used for this test
Service service = Service.WEBSITE; // Can be anything for this test Service service = Service.ARBITRARY_DATA;
// Create PATCH transaction, ensuring that an exception is thrown // Create PATCH transaction, ensuring that an exception is thrown
try { try {
@ -119,7 +119,7 @@ public class ArbitraryDataTests extends Common {
String publicKey58 = Base58.encode(alice.getPublicKey()); String publicKey58 = Base58.encode(alice.getPublicKey());
String name = "TEST"; // Can be anything for this test String name = "TEST"; // Can be anything for this test
String identifier = null; // Not used for this test String identifier = null; // Not used for this test
Service service = Service.WEBSITE; // Can be anything for this test Service service = Service.ARBITRARY_DATA;
// Ensure the name doesn't exist // Ensure the name doesn't exist
assertNull(repository.getNameRepository().fromName(name)); assertNull(repository.getNameRepository().fromName(name));
@ -142,7 +142,7 @@ public class ArbitraryDataTests extends Common {
PrivateKeyAccount alice = Common.getTestAccount(repository, "alice"); PrivateKeyAccount alice = Common.getTestAccount(repository, "alice");
String name = "TEST"; // Can be anything for this test String name = "TEST"; // Can be anything for this test
String identifier = null; // Not used for this test String identifier = null; // Not used for this test
Service service = Service.WEBSITE; // Can be anything for this test Service service = Service.ARBITRARY_DATA;
// Register the name to Alice // Register the name to Alice
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, ""); RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "");
@ -174,7 +174,7 @@ public class ArbitraryDataTests extends Common {
String publicKey58 = Base58.encode(alice.getPublicKey()); String publicKey58 = Base58.encode(alice.getPublicKey());
String name = "TEST"; // Can be anything for this test String name = "TEST"; // Can be anything for this test
String identifier = null; // Not used for this test String identifier = null; // Not used for this test
Service service = Service.WEBSITE; // Can be anything for this test Service service = Service.ARBITRARY_DATA;
// Register the name to Alice // Register the name to Alice
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, ""); RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "");
@ -219,7 +219,7 @@ public class ArbitraryDataTests extends Common {
String publicKey58 = Base58.encode(alice.getPublicKey()); String publicKey58 = Base58.encode(alice.getPublicKey());
String name = "TEST"; // Can be anything for this test String name = "TEST"; // Can be anything for this test
String identifier = "test_identifier"; String identifier = "test_identifier";
Service service = Service.WEBSITE; // Can be anything for this test Service service = Service.ARBITRARY_DATA;
// Register the name to Alice // Register the name to Alice
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, ""); RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "");
@ -287,7 +287,7 @@ public class ArbitraryDataTests extends Common {
String publicKey58 = Base58.encode(alice.getPublicKey()); String publicKey58 = Base58.encode(alice.getPublicKey());
String name = "TEST"; // Can be anything for this test String name = "TEST"; // Can be anything for this test
String identifier = ""; // Blank, not null String identifier = ""; // Blank, not null
Service service = Service.WEBSITE; // Can be anything for this test Service service = Service.ARBITRARY_DATA;
// Register the name to Alice // Register the name to Alice
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, ""); RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "");

View File

@ -40,6 +40,67 @@ public class ArbitraryServiceTests extends Common {
assertEquals(ValidationResult.OK, service.validate(path)); assertEquals(ValidationResult.OK, service.validate(path));
} }
@Test
public void testValidateWebsite() throws IOException {
// Generate some random data
byte[] data = new byte[1024];
new Random().nextBytes(data);
// Write the data to several files in a temp path
Path path = Files.createTempDirectory("testValidateWebsite");
path.toFile().deleteOnExit();
Files.write(Paths.get(path.toString(), "index.html"), data, StandardOpenOption.CREATE);
Files.write(Paths.get(path.toString(), "data2"), data, StandardOpenOption.CREATE);
Files.write(Paths.get(path.toString(), "data3"), data, StandardOpenOption.CREATE);
Service service = Service.WEBSITE;
assertTrue(service.isValidationRequired());
// There is an index file in the root
assertEquals(ValidationResult.OK, service.validate(path));
}
@Test
public void testValidateWebsiteWithoutIndexFile() throws IOException {
// Generate some random data
byte[] data = new byte[1024];
new Random().nextBytes(data);
// Write the data to several files in a temp path
Path path = Files.createTempDirectory("testValidateWebsiteWithoutIndexFile");
path.toFile().deleteOnExit();
Files.write(Paths.get(path.toString(), "data1.html"), data, StandardOpenOption.CREATE);
Files.write(Paths.get(path.toString(), "data2"), data, StandardOpenOption.CREATE);
Files.write(Paths.get(path.toString(), "data3"), data, StandardOpenOption.CREATE);
Service service = Service.WEBSITE;
assertTrue(service.isValidationRequired());
// There is no index file in the root
assertEquals(ValidationResult.MISSING_INDEX_FILE, service.validate(path));
}
@Test
public void testValidateWebsiteWithoutIndexFileInRoot() throws IOException {
// Generate some random data
byte[] data = new byte[1024];
new Random().nextBytes(data);
// Write the data to several files in a temp path
Path path = Files.createTempDirectory("testValidateWebsiteWithoutIndexFileInRoot");
path.toFile().deleteOnExit();
Files.createDirectories(Paths.get(path.toString(), "directory"));
Files.write(Paths.get(path.toString(), "directory", "index.html"), data, StandardOpenOption.CREATE);
Files.write(Paths.get(path.toString(), "data2"), data, StandardOpenOption.CREATE);
Files.write(Paths.get(path.toString(), "data3"), data, StandardOpenOption.CREATE);
Service service = Service.WEBSITE;
assertTrue(service.isValidationRequired());
// There is no index file in the root
assertEquals(ValidationResult.MISSING_INDEX_FILE, service.validate(path));
}
@Test @Test
public void testValidQortalMetadata() throws IOException { 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)

View File

@ -48,7 +48,7 @@ public class ArbitraryTransactionMetadataTests extends Common {
String publicKey58 = Base58.encode(alice.getPublicKey()); String publicKey58 = Base58.encode(alice.getPublicKey());
String name = "TEST"; // Can be anything for this test String name = "TEST"; // Can be anything for this test
String identifier = null; // Not used for this test String identifier = null; // Not used for this test
Service service = Service.WEBSITE; // Can be anything for this test Service service = Service.ARBITRARY_DATA;
int chunkSize = 100; int chunkSize = 100;
int dataLength = 900; // Actual data length will be longer due to encryption int dataLength = 900; // Actual data length will be longer due to encryption