forked from Qortal/qortal
Added generic PUT, PATCH, and GET /arbitrary API endpoints
These will likely avoid the need for some of the /site APIs.
This commit is contained in:
parent
c9356d0ff5
commit
f1939fdc2b
@ -25,6 +25,7 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.qortal.api.*;
|
import org.qortal.api.*;
|
||||||
import org.qortal.api.resource.TransactionsResource.ConfirmationStatus;
|
import org.qortal.api.resource.TransactionsResource.ConfirmationStatus;
|
||||||
|
import org.qortal.arbitrary.ArbitraryDataReader;
|
||||||
import org.qortal.arbitrary.ArbitraryDataTransactionBuilder;
|
import org.qortal.arbitrary.ArbitraryDataTransactionBuilder;
|
||||||
import org.qortal.data.transaction.ArbitraryTransactionData;
|
import org.qortal.data.transaction.ArbitraryTransactionData;
|
||||||
import org.qortal.data.transaction.ArbitraryTransactionData.*;
|
import org.qortal.data.transaction.ArbitraryTransactionData.*;
|
||||||
@ -220,16 +221,51 @@ public class ArbitraryResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@GET
|
||||||
@Path("/upload/creator/{publickey}")
|
@Path("/{service}/{name}")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Build raw, unsigned, ARBITRARY transaction, based on a user-supplied path to a single file",
|
summary = "Fetch local file path for data with supplied service and name",
|
||||||
|
description = "An optional rebuild boolean can be supplied. If true, any existing cached data will be invalidated.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(
|
||||||
|
description = "Path to file structure containing requested data",
|
||||||
|
content = @Content(
|
||||||
|
mediaType = MediaType.TEXT_PLAIN,
|
||||||
|
schema = @Schema(
|
||||||
|
type = "string"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public String get(@PathParam("service") String serviceString,
|
||||||
|
@PathParam("name") String name,
|
||||||
|
@QueryParam("rebuild") boolean rebuild) {
|
||||||
|
Security.checkApiCallAllowed(request);
|
||||||
|
|
||||||
|
Service service = Service.valueOf(serviceString);
|
||||||
|
ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service);
|
||||||
|
try {
|
||||||
|
arbitraryDataReader.loadSynchronously(rebuild);
|
||||||
|
return arbitraryDataReader.getFilePath().toAbsolutePath().toString();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.info(String.format("Unable to load %s %s: %s", service, name, e.getMessage()));
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{service}/{name}/{publickey}")
|
||||||
|
@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.",
|
||||||
requestBody = @RequestBody(
|
requestBody = @RequestBody(
|
||||||
required = true,
|
required = true,
|
||||||
content = @Content(
|
content = @Content(
|
||||||
mediaType = MediaType.TEXT_PLAIN,
|
mediaType = MediaType.TEXT_PLAIN,
|
||||||
schema = @Schema(
|
schema = @Schema(
|
||||||
type = "string", example = "qortal.jar"
|
type = "string", example = "/Users/user/Documents/MyDirectoryOrFile"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@ -245,21 +281,60 @@ public class ArbitraryResource {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ApiErrors({ApiError.REPOSITORY_ISSUE})
|
public String put(@PathParam("service") String serviceString,
|
||||||
public String uploadFileAtPath(@PathParam("method") String methodString,
|
|
||||||
@PathParam("publickey") String publicKey58,
|
|
||||||
@PathParam("name") String name,
|
@PathParam("name") String name,
|
||||||
|
@PathParam("publickey") String publicKey58,
|
||||||
String path) {
|
String path) {
|
||||||
Security.checkApiCallAllowed(request);
|
Security.checkApiCallAllowed(request);
|
||||||
|
|
||||||
// It's too dangerous to allow user-supplied filenames in weaker security contexts
|
return this.upload(Method.PUT, Service.valueOf(serviceString), publicKey58, name, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PATCH
|
||||||
|
@Path("/{service}/{name}/{publickey}")
|
||||||
|
@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, " +
|
||||||
|
"and then publishes only the differences.",
|
||||||
|
requestBody = @RequestBody(
|
||||||
|
required = true,
|
||||||
|
content = @Content(
|
||||||
|
mediaType = MediaType.TEXT_PLAIN,
|
||||||
|
schema = @Schema(
|
||||||
|
type = "string", example = "/Users/user/Documents/MyDirectoryOrFile"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(
|
||||||
|
description = "raw, unsigned, ARBITRARY transaction encoded in Base58",
|
||||||
|
content = @Content(
|
||||||
|
mediaType = MediaType.TEXT_PLAIN,
|
||||||
|
schema = @Schema(
|
||||||
|
type = "string"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String upload(Method method, Service service, String publicKey58, String name, String path) {
|
||||||
|
// It's too dangerous to allow user-supplied file paths in weaker security contexts
|
||||||
if (Settings.getInstance().isApiRestricted()) {
|
if (Settings.getInstance().isApiRestricted()) {
|
||||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.NON_PRODUCTION);
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.NON_PRODUCTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ArbitraryDataTransactionBuilder transactionBuilder = new ArbitraryDataTransactionBuilder(
|
ArbitraryDataTransactionBuilder transactionBuilder = new ArbitraryDataTransactionBuilder(
|
||||||
publicKey58, Paths.get(path), name, Method.valueOf(methodString), Service.ARBITRARY_DATA
|
publicKey58, Paths.get(path), name, method, service
|
||||||
);
|
);
|
||||||
|
|
||||||
ArbitraryTransactionData transactionData = transactionBuilder.build();
|
ArbitraryTransactionData transactionData = transactionBuilder.build();
|
||||||
|
Loading…
Reference in New Issue
Block a user