forked from Qortal/qortal
When validating an ARBITRARY transaction, ensure that the supplied name exists and is registered to the account that is signing the transaction.
This ensures that only the owner of a name is able to update data associated with that name. Note that this doesn't take into account the ability for group members to update a resource, so this will need modifying when that feature is ultimately introduced (likely after v3.0)
This commit is contained in:
parent
35a7a70b93
commit
a55fc4fff9
@ -2,12 +2,14 @@ package org.qortal.transaction;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.qortal.account.Account;
|
||||
import org.qortal.crypto.Crypto;
|
||||
import org.qortal.crypto.MemoryPoW;
|
||||
import org.qortal.data.PaymentData;
|
||||
import org.qortal.data.naming.NameData;
|
||||
import org.qortal.data.transaction.ArbitraryTransactionData;
|
||||
import org.qortal.data.transaction.TransactionData;
|
||||
import org.qortal.payment.Payment;
|
||||
@ -147,6 +149,21 @@ public class ArbitraryTransaction extends Transaction {
|
||||
}
|
||||
}
|
||||
|
||||
// Check name if one has been included
|
||||
if (arbitraryTransactionData.getName() != null) {
|
||||
NameData nameData = this.repository.getNameRepository().fromName(arbitraryTransactionData.getName());
|
||||
|
||||
// Check the name is registered
|
||||
if (nameData == null) {
|
||||
return ValidationResult.NAME_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
// Check that the transaction signer owns the name
|
||||
if (!Objects.equals(this.getCreator().getAddress(), nameData.getOwner())) {
|
||||
return ValidationResult.INVALID_NAME_OWNER;
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap and delegate final payment validity checks to Payment class
|
||||
return new Payment(this.repository).isValid(arbitraryTransactionData.getSenderPublicKey(), arbitraryTransactionData.getPayments(),
|
||||
arbitraryTransactionData.getFee());
|
||||
|
@ -10,12 +10,14 @@ import org.qortal.arbitrary.ArbitraryDataTransactionBuilder;
|
||||
import org.qortal.arbitrary.metadata.ArbitraryDataMetadataPatch;
|
||||
import org.qortal.data.transaction.ArbitraryTransactionData;
|
||||
import org.qortal.data.transaction.ArbitraryTransactionData.*;
|
||||
import org.qortal.data.transaction.RegisterNameTransactionData;
|
||||
import org.qortal.repository.DataException;
|
||||
import org.qortal.repository.Repository;
|
||||
import org.qortal.repository.RepositoryManager;
|
||||
import org.qortal.test.common.BlockUtils;
|
||||
import org.qortal.test.common.Common;
|
||||
import org.qortal.test.common.TransactionUtils;
|
||||
import org.qortal.test.common.transaction.TestTransaction;
|
||||
import org.qortal.transaction.Transaction;
|
||||
import org.qortal.utils.Base58;
|
||||
|
||||
@ -41,6 +43,10 @@ public class ArbitraryDataTests extends Common {
|
||||
String name = "TEST"; // Can be anything for this test
|
||||
Service service = Service.WEBSITE; // Can be anything for this test
|
||||
|
||||
// Register the name to Alice
|
||||
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "");
|
||||
TransactionUtils.signAndMint(repository, transactionData, alice);
|
||||
|
||||
// Create PUT transaction
|
||||
Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
|
||||
this.createAndMintTxn(repository, publicKey58, path1, name, Method.PUT, service, alice);
|
||||
@ -98,6 +104,59 @@ public class ArbitraryDataTests extends Common {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNameDoesNotExist() throws DataException, IOException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
PrivateKeyAccount alice = Common.getTestAccount(repository, "alice");
|
||||
String publicKey58 = Base58.encode(alice.getPublicKey());
|
||||
String name = "TEST"; // Can be anything for this test
|
||||
Service service = Service.WEBSITE; // Can be anything for this test
|
||||
|
||||
// Ensure the name doesn't exist
|
||||
assertNull(repository.getNameRepository().fromName(name));
|
||||
|
||||
// Create PUT transaction, ensuring that an exception is thrown
|
||||
try {
|
||||
Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
|
||||
this.createAndMintTxn(repository, publicKey58, path1, name, Method.PUT, service, alice);
|
||||
fail("Creating transaction should fail due to the name being unregistered");
|
||||
|
||||
} catch (DataException expectedException) {
|
||||
assertEquals("Arbitrary transaction invalid: NAME_DOES_NOT_EXIST", expectedException.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateResourceOwnedByAnotherCreator() throws DataException, IOException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
PrivateKeyAccount alice = Common.getTestAccount(repository, "alice");
|
||||
String name = "TEST"; // Can be anything for this test
|
||||
Service service = Service.WEBSITE; // Can be anything for this test
|
||||
|
||||
// Register the name to Alice
|
||||
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "");
|
||||
TransactionUtils.signAndMint(repository, transactionData, alice);
|
||||
|
||||
// Create PUT transaction
|
||||
Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
|
||||
this.createAndMintTxn(repository, Base58.encode(alice.getPublicKey()), path1, name, Method.PUT, service, alice);
|
||||
|
||||
// Bob attempts to update Alice's data
|
||||
PrivateKeyAccount bob = Common.getTestAccount(repository, "bob");
|
||||
|
||||
// Create PATCH transaction, ensuring that an exception is thrown
|
||||
try {
|
||||
Path path2 = Paths.get("src/test/resources/arbitrary/demo2");
|
||||
this.createAndMintTxn(repository, Base58.encode(bob.getPublicKey()), path2, name, Method.PATCH, service, bob);
|
||||
fail("Creating transaction should fail due to the name being registered to Alice instead of Bob");
|
||||
|
||||
} catch (DataException expectedException) {
|
||||
assertEquals("Arbitrary transaction invalid: INVALID_NAME_OWNER", expectedException.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createAndMintTxn(Repository repository, String publicKey58, Path path, String name,
|
||||
Method method, Service service, PrivateKeyAccount account) throws DataException {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user