forked from Qortal/qortal
Modified storage code to support 2 new settings:
publicDataEnabled - whether to store decryptable data (default true) privateDataEnabled - whether to store data without a decryption key (default false)
This commit is contained in:
parent
f6b9ff50c3
commit
1b170c74c0
@ -372,6 +372,7 @@ public class ArbitraryDataReader {
|
||||
|
||||
} catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | NoSuchPaddingException
|
||||
| BadPaddingException | IllegalBlockSizeException | IOException | InvalidKeyException e) {
|
||||
// TODO: delete files and blacklist this resource if privateDataEnabled is false
|
||||
throw new DataException(String.format("Unable to decrypt file at path %s: %s", this.filePath, e.getMessage()));
|
||||
}
|
||||
} else {
|
||||
|
@ -128,9 +128,9 @@ public class ArbitraryDataCleanupManager extends Thread {
|
||||
|
||||
|
||||
// Check to see if we should be hosting data for this transaction at all
|
||||
if (!storageManager.canStoreDataForName(arbitraryTransactionData.getName())) {
|
||||
LOGGER.info("Deleting transaction {} because we can't host data for name {}",
|
||||
Base58.encode(arbitraryTransactionData.getSignature()), arbitraryTransactionData.getName());
|
||||
if (!storageManager.canStoreData(arbitraryTransactionData)) {
|
||||
LOGGER.info("Deleting transaction {} because we can't host its data",
|
||||
Base58.encode(arbitraryTransactionData.getSignature()));
|
||||
ArbitraryTransactionUtils.deleteCompleteFileAndChunks(arbitraryTransactionData);
|
||||
continue;
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ public class ArbitraryDataManager extends Thread {
|
||||
ArbitraryTransactionData arbitraryTransactionData = (ArbitraryTransactionData) arbitraryTransaction.getTransactionData();
|
||||
|
||||
// Skip transactions that we don't need to proactively store data for
|
||||
if (!storageManager.shouldPreFetchDataForName(arbitraryTransactionData.getName())) {
|
||||
if (!storageManager.shouldPreFetchData(arbitraryTransactionData)) {
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
@ -680,7 +680,7 @@ public class ArbitraryDataManager extends Thread {
|
||||
|
||||
// We may also need to broadcast to the network that we are now hosting files for this transaction,
|
||||
// but only if these files are in accordance with our storage policy
|
||||
if (ArbitraryDataStorageManager.getInstance().canStoreDataForName(arbitraryTransactionData.getName())) {
|
||||
if (ArbitraryDataStorageManager.getInstance().canStoreData(arbitraryTransactionData)) {
|
||||
// Use a null peer address to indicate our own
|
||||
Message newArbitrarySignatureMessage = new ArbitrarySignaturesMessage(null, Arrays.asList(signature));
|
||||
Network.getInstance().broadcast(broadcastPeer -> newArbitrarySignatureMessage);
|
||||
@ -863,7 +863,7 @@ public class ArbitraryDataManager extends Thread {
|
||||
if (transactionData instanceof ArbitraryTransactionData) {
|
||||
|
||||
// Check if we're even allowed to serve data for this transaction
|
||||
if (ArbitraryDataStorageManager.getInstance().canStoreDataForName(transactionData.getName())) {
|
||||
if (ArbitraryDataStorageManager.getInstance().canStoreData(transactionData)) {
|
||||
|
||||
byte[] hash = transactionData.getData();
|
||||
byte[] chunkHashes = transactionData.getChunkHashes();
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.qortal.controller.arbitrary;
|
||||
|
||||
import org.qortal.data.transaction.ArbitraryTransactionData;
|
||||
import org.qortal.list.ResourceListManager;
|
||||
import org.qortal.settings.Settings;
|
||||
|
||||
@ -25,7 +26,14 @@ public class ArbitraryDataStorageManager {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public boolean canStoreDataForName(String name) {
|
||||
public boolean canStoreData(ArbitraryTransactionData arbitraryTransactionData) {
|
||||
String name = arbitraryTransactionData.getName();
|
||||
|
||||
// Don't store data unless it's an allowed type (public/private)
|
||||
if (!this.isDataTypeAllowed(arbitraryTransactionData)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if our storage policy and blacklist allows us to host data for this name
|
||||
switch (Settings.getInstance().getStoragePolicy()) {
|
||||
case FOLLOWED_AND_VIEWED:
|
||||
@ -45,18 +53,19 @@ public class ArbitraryDataStorageManager {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNameInBlacklist(String name) {
|
||||
return ResourceListManager.getInstance().listContains("blacklist", "names", name, false);
|
||||
}
|
||||
|
||||
public boolean shouldPreFetchDataForName(String name) {
|
||||
public boolean shouldPreFetchData(ArbitraryTransactionData arbitraryTransactionData) {
|
||||
String name = arbitraryTransactionData.getName();
|
||||
if (name == null) {
|
||||
return this.shouldPreFetchDataWithoutName();
|
||||
return this.shouldPreFetchDataWithoutName(arbitraryTransactionData);
|
||||
}
|
||||
// Never fetch data from blacklisted names, even if they are followed
|
||||
if (this.isNameInBlacklist(name)) {
|
||||
return false;
|
||||
}
|
||||
// Don't store data unless it's an allowed type (public/private)
|
||||
if (!this.isDataTypeAllowed(arbitraryTransactionData)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (Settings.getInstance().getStoragePolicy()) {
|
||||
case FOLLOWED:
|
||||
@ -73,10 +82,10 @@ public class ArbitraryDataStorageManager {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldPreFetchDataWithoutName() {
|
||||
private boolean shouldPreFetchDataWithoutName(ArbitraryTransactionData arbitraryTransactionData) {
|
||||
switch (Settings.getInstance().getStoragePolicy()) {
|
||||
case ALL:
|
||||
return true;
|
||||
return this.isDataTypeAllowed(arbitraryTransactionData);
|
||||
|
||||
case NONE:
|
||||
case VIEWED:
|
||||
@ -87,6 +96,25 @@ public class ArbitraryDataStorageManager {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDataTypeAllowed(ArbitraryTransactionData arbitraryTransactionData) {
|
||||
byte[] secret = arbitraryTransactionData.getSecret();
|
||||
boolean hasSecret = (secret != null && secret.length == 32);
|
||||
|
||||
if (!Settings.getInstance().isPrivateDataEnabled() && !hasSecret) {
|
||||
// Private data isn't enabled so we can't store data without a valid secret
|
||||
return false;
|
||||
}
|
||||
if (!Settings.getInstance().isPublicDataEnabled() && hasSecret) {
|
||||
// Public data isn't enabled so we can't store data with a secret
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isNameInBlacklist(String name) {
|
||||
return ResourceListManager.getInstance().listContains("blacklist", "names", name, false);
|
||||
}
|
||||
|
||||
private boolean isFollowingName(String name) {
|
||||
return ResourceListManager.getInstance().listContains("followed", "names", name, false);
|
||||
}
|
||||
|
@ -284,6 +284,11 @@ public class Settings {
|
||||
/** Whether to validate every layer when building arbitrary data, or just the final layer */
|
||||
private boolean validateAllDataLayers = false;
|
||||
|
||||
/** Whether to allow public (decryptable) data to be stored */
|
||||
private boolean publicDataEnabled = true;
|
||||
/** Whether to allow private (non-decryptable) data to be stored */
|
||||
private boolean privateDataEnabled = false;
|
||||
|
||||
|
||||
// Domain mapping
|
||||
public static class DomainMap {
|
||||
@ -827,4 +832,12 @@ public class Settings {
|
||||
public boolean shouldValidateAllDataLayers() {
|
||||
return this.validateAllDataLayers;
|
||||
}
|
||||
|
||||
public boolean isPublicDataEnabled() {
|
||||
return this.publicDataEnabled;
|
||||
}
|
||||
|
||||
public boolean isPrivateDataEnabled() {
|
||||
return this.privateDataEnabled;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
package org.qortal.test.arbitrary;public class ArbitraryDataStoragePolicyTests {
|
||||
}
|
Loading…
Reference in New Issue
Block a user