From f4c1671079a0398b7a9d674b04de63821d458ee8 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 29 Oct 2021 17:08:26 +0100 Subject: [PATCH] Removed the need to include public key in recently added API endpoints, as it can be derived from the registered name's owner. --- .../api/resource/ArbitraryResource.java | 49 +++++++++++++------ tools/qdata | 7 +-- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 4f58fb13..c2731fc3 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -27,6 +27,8 @@ import org.qortal.api.*; import org.qortal.api.resource.TransactionsResource.ConfirmationStatus; import org.qortal.arbitrary.ArbitraryDataReader; import org.qortal.arbitrary.ArbitraryDataTransactionBuilder; +import org.qortal.data.account.AccountData; +import org.qortal.data.naming.NameData; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.ArbitraryTransactionData.*; import org.qortal.data.transaction.TransactionData; @@ -256,7 +258,7 @@ public class ArbitraryResource { } @PUT - @Path("/{service}/{name}/{publickey}") + @Path("/{service}/{name}") @Operation( summary = "Build raw, unsigned, ARBITRARY transaction, based on a user-supplied path, using the PUT method", description = "A PUT transaction replaces the data held for this name and service in its entirety.", @@ -283,15 +285,14 @@ public class ArbitraryResource { ) public String put(@PathParam("service") String serviceString, @PathParam("name") String name, - @PathParam("publickey") String publicKey58, String path) { Security.checkApiCallAllowed(request); - return this.upload(Method.PUT, Service.valueOf(serviceString), publicKey58, name, path); + return this.upload(Method.PUT, Service.valueOf(serviceString), name, path); } @PATCH - @Path("/{service}/{name}/{publickey}") + @Path("/{service}/{name}") @Operation( summary = "Build raw, unsigned, ARBITRARY transaction, based on a user-supplied path, using the PATCH method", description = "A PATCH transaction calculates the delta between the current state on the on-chain state, " + @@ -319,29 +320,47 @@ public class ArbitraryResource { ) public String patch(@PathParam("service") String serviceString, @PathParam("name") String name, - @PathParam("publickey") String publicKey58, String path) { Security.checkApiCallAllowed(request); - return this.upload(Method.PATCH, Service.valueOf(serviceString), publicKey58, name, path); + return this.upload(Method.PATCH, Service.valueOf(serviceString), name, path); } - private String upload(Method method, Service service, String publicKey58, String name, String path) { + private String upload(Method method, Service service, String name, String path) { // It's too dangerous to allow user-supplied file paths in weaker security contexts if (Settings.getInstance().isApiRestricted()) { throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.NON_PRODUCTION); } - try { - ArbitraryDataTransactionBuilder transactionBuilder = new ArbitraryDataTransactionBuilder( - publicKey58, Paths.get(path), name, method, service - ); + // Fetch public key from registered name + try (final Repository repository = RepositoryManager.getRepository()) { + NameData nameData = repository.getNameRepository().fromName(name); + if (nameData == null) { + String error = String.format("Name not registered: %s", name); + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, error); + } + + AccountData accountData = repository.getAccountRepository().getAccount(nameData.getOwner()); + if (accountData == null) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_UNKNOWN); + } + byte[] publicKey = accountData.getPublicKey(); + String publicKey58 = Base58.encode(publicKey); + + try { + ArbitraryDataTransactionBuilder transactionBuilder = new ArbitraryDataTransactionBuilder( + publicKey58, Paths.get(path), name, method, service + ); - ArbitraryTransactionData transactionData = transactionBuilder.build(); - return Base58.encode(ArbitraryTransactionTransformer.toBytes(transactionData)); + ArbitraryTransactionData transactionData = transactionBuilder.build(); + return Base58.encode(ArbitraryTransactionTransformer.toBytes(transactionData)); - } catch (DataException | TransformationException e) { - throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_DATA, e.getMessage()); + } catch (DataException | TransformationException e) { + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_DATA, e.getMessage()); + } + + } catch (DataException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE); } } diff --git a/tools/qdata b/tools/qdata index ab574926..d5658e6e 100755 --- a/tools/qdata +++ b/tools/qdata @@ -35,20 +35,15 @@ if [[ "${method}" == "PUT" || "${method}" == "PATCH" ]]; then directory=$4 private_key=$5 - public_key=$(curl --silent --url "http://localhost:${port}/utils/publickey" --data "${private_key}") - if [ -z "${directory}" ]; then echo "Error: missing directory"; exit fi if [ -z "${private_key}" ]; then echo "Error: missing private_key"; exit fi - if [ -z "${public_key}" ]; then - echo "Error: unable to convert private key to public key"; exit - fi echo "Creating transaction - this can take a while..." - tx_data=$(curl --silent --insecure -X ${method} "http://${host}:${port}/arbitrary/${service}/${name}/${public_key}" -d "${directory}") + tx_data=$(curl --silent --insecure -X ${method} "http://${host}:${port}/arbitrary/${service}/${name}" -d "${directory}") if [[ "${tx_data}" == *"error"* || "${tx_data}" == *"ERROR"* ]]; then echo "${tx_data}"; exit fi