forked from Qortal/qortal
Added POST /lists/blacklist/addresses and DELETE /lists/blacklist/addresses API endpoints.
These are the same as the /lists/blacklist/address/{address} endpoints but allow a JSON array of addresses to be specified in the request body. They currently return true if
This commit is contained in:
parent
b29ae67501
commit
9fdc901b7a
18
src/main/java/org/qortal/api/model/AddressListRequest.java
Normal file
18
src/main/java/org/qortal/api/model/AddressListRequest.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package org.qortal.api.model;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
public class AddressListRequest {
|
||||||
|
|
||||||
|
@Schema(description = "A list of addresses")
|
||||||
|
public List<String> addresses;
|
||||||
|
|
||||||
|
public AddressListRequest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,10 +3,12 @@ package org.qortal.api.resource;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.media.Content;
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import org.qortal.api.*;
|
import org.qortal.api.*;
|
||||||
|
import org.qortal.api.model.AddressListRequest;
|
||||||
import org.qortal.crypto.Crypto;
|
import org.qortal.crypto.Crypto;
|
||||||
import org.qortal.data.account.AccountData;
|
import org.qortal.data.account.AccountData;
|
||||||
import org.qortal.list.ResourceListManager;
|
import org.qortal.list.ResourceListManager;
|
||||||
@ -50,7 +52,7 @@ public class ListsResource {
|
|||||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_UNKNOWN);
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_UNKNOWN);
|
||||||
|
|
||||||
// Valid address, so go ahead and blacklist it
|
// Valid address, so go ahead and blacklist it
|
||||||
boolean success = ResourceListManager.getInstance().addAddressToBlacklist(address);
|
boolean success = ResourceListManager.getInstance().addAddressToBlacklist(address, true);
|
||||||
|
|
||||||
return success ? "true" : "false";
|
return success ? "true" : "false";
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
@ -58,6 +60,78 @@ public class ListsResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/blacklist/addresses")
|
||||||
|
@Operation(
|
||||||
|
summary = "Add one or more QORT addresses to the local blacklist",
|
||||||
|
requestBody = @RequestBody(
|
||||||
|
required = true,
|
||||||
|
content = @Content(
|
||||||
|
mediaType = MediaType.APPLICATION_JSON,
|
||||||
|
schema = @Schema(
|
||||||
|
implementation = AddressListRequest.class
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(
|
||||||
|
description = "Returns true if all addresses were processed, false if any couldn't be " +
|
||||||
|
"processed, or an exception on failure. If false or an exception is returned, " +
|
||||||
|
"the list will not be updated, and the request will need to be re-issued.",
|
||||||
|
content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "boolean"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ApiErrors({ApiError.INVALID_ADDRESS, ApiError.ADDRESS_UNKNOWN, ApiError.REPOSITORY_ISSUE})
|
||||||
|
public String addAddressesToBlacklist(AddressListRequest addressListRequest) {
|
||||||
|
if (addressListRequest == null || addressListRequest.addresses == null) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA);
|
||||||
|
}
|
||||||
|
|
||||||
|
int successCount = 0;
|
||||||
|
int errorCount = 0;
|
||||||
|
|
||||||
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
|
|
||||||
|
for (String address : addressListRequest.addresses) {
|
||||||
|
|
||||||
|
if (!Crypto.isValidAddress(address)) {
|
||||||
|
errorCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountData accountData = repository.getAccountRepository().getAccount(address);
|
||||||
|
// Not found?
|
||||||
|
if (accountData == null) {
|
||||||
|
errorCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid address, so go ahead and blacklist it
|
||||||
|
boolean success = ResourceListManager.getInstance().addAddressToBlacklist(address, false);
|
||||||
|
if (success) {
|
||||||
|
successCount++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DataException e) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (successCount > 0 && errorCount == 0) {
|
||||||
|
// All were successful, so save the blacklist
|
||||||
|
ResourceListManager.getInstance().saveBlacklist();
|
||||||
|
return "true";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Something went wrong, so revert
|
||||||
|
ResourceListManager.getInstance().revertBlacklist();
|
||||||
|
return "false";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("/blacklist/address/{address}")
|
@Path("/blacklist/address/{address}")
|
||||||
@ -82,7 +156,7 @@ public class ListsResource {
|
|||||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_UNKNOWN);
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.ADDRESS_UNKNOWN);
|
||||||
|
|
||||||
// Valid address, so go ahead and blacklist it
|
// Valid address, so go ahead and blacklist it
|
||||||
boolean success = ResourceListManager.getInstance().removeAddressFromBlacklist(address);
|
boolean success = ResourceListManager.getInstance().removeAddressFromBlacklist(address, true);
|
||||||
|
|
||||||
return success ? "true" : "false";
|
return success ? "true" : "false";
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
@ -90,10 +164,83 @@ public class ListsResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/blacklist/addresses")
|
||||||
|
@Operation(
|
||||||
|
summary = "Remove one or more QORT addresses from the local blacklist",
|
||||||
|
requestBody = @RequestBody(
|
||||||
|
required = true,
|
||||||
|
content = @Content(
|
||||||
|
mediaType = MediaType.APPLICATION_JSON,
|
||||||
|
schema = @Schema(
|
||||||
|
implementation = AddressListRequest.class
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(
|
||||||
|
description = "Returns true if all addresses were processed, false if any couldn't be " +
|
||||||
|
"processed, or an exception on failure. If false or an exception is returned, " +
|
||||||
|
"the list will not be updated, and the request will need to be re-issued.",
|
||||||
|
content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "boolean"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ApiErrors({ApiError.INVALID_ADDRESS, ApiError.ADDRESS_UNKNOWN, ApiError.REPOSITORY_ISSUE})
|
||||||
|
public String removeAddressesFromBlacklist(AddressListRequest addressListRequest) {
|
||||||
|
if (addressListRequest == null || addressListRequest.addresses == null) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA);
|
||||||
|
}
|
||||||
|
|
||||||
|
int successCount = 0;
|
||||||
|
int errorCount = 0;
|
||||||
|
|
||||||
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
|
|
||||||
|
for (String address : addressListRequest.addresses) {
|
||||||
|
|
||||||
|
if (!Crypto.isValidAddress(address)) {
|
||||||
|
errorCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountData accountData = repository.getAccountRepository().getAccount(address);
|
||||||
|
// Not found?
|
||||||
|
if (accountData == null) {
|
||||||
|
errorCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid address, so go ahead and blacklist it
|
||||||
|
// Don't save as we will do this at the end of the process
|
||||||
|
boolean success = ResourceListManager.getInstance().removeAddressFromBlacklist(address, false);
|
||||||
|
if (success) {
|
||||||
|
successCount++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DataException e) {
|
||||||
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (successCount > 0 && errorCount == 0) {
|
||||||
|
// All were successful, so save the blacklist
|
||||||
|
ResourceListManager.getInstance().saveBlacklist();
|
||||||
|
return "true";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Something went wrong, so revert
|
||||||
|
ResourceListManager.getInstance().revertBlacklist();
|
||||||
|
return "false";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/blacklist/address/{address}")
|
@Path("/blacklist/address/{address}")
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Checks if an address is present in the local blacklist",
|
summary = "Check if an address is present in the local blacklist",
|
||||||
responses = {
|
responses = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
description = "Returns true or false if the list was queried, or an exception on failure",
|
description = "Returns true or false if the list was queried, or an exception on failure",
|
||||||
|
@ -17,6 +17,8 @@ import java.util.List;
|
|||||||
|
|
||||||
public class ResourceList {
|
public class ResourceList {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(ResourceList.class);
|
||||||
|
|
||||||
private String category;
|
private String category;
|
||||||
private String resourceName;
|
private String resourceName;
|
||||||
private List<String> list;
|
private List<String> list;
|
||||||
@ -84,6 +86,15 @@ public class ResourceList {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean revert() {
|
||||||
|
try {
|
||||||
|
return this.load();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.info("Unable to revert {} {}", this.resourceName, this.category);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* List management */
|
/* List management */
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package org.qortal.list;
|
|||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.eclipse.jetty.util.IO;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@ -29,10 +28,12 @@ public class ResourceListManager {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addAddressToBlacklist(String address) {
|
public boolean addAddressToBlacklist(String address, boolean save) {
|
||||||
try {
|
try {
|
||||||
this.addressBlacklist.add(address);
|
this.addressBlacklist.add(address);
|
||||||
this.addressBlacklist.save();
|
if (save) {
|
||||||
|
this.addressBlacklist.save();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} catch (IllegalStateException | IOException e) {
|
} catch (IllegalStateException | IOException e) {
|
||||||
@ -41,10 +42,13 @@ public class ResourceListManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeAddressFromBlacklist(String address) {
|
public boolean removeAddressFromBlacklist(String address, boolean save) {
|
||||||
try {
|
try {
|
||||||
this.addressBlacklist.remove(address);
|
this.addressBlacklist.remove(address);
|
||||||
this.addressBlacklist.save();
|
|
||||||
|
if (save) {
|
||||||
|
this.addressBlacklist.save();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} catch (IllegalStateException | IOException e) {
|
} catch (IllegalStateException | IOException e) {
|
||||||
@ -60,4 +64,24 @@ public class ResourceListManager {
|
|||||||
return this.addressBlacklist.contains(address);
|
return this.addressBlacklist.contains(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void saveBlacklist() {
|
||||||
|
if (this.addressBlacklist == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.addressBlacklist.save();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.info("Unable to save blacklist - reverting back to last saved state");
|
||||||
|
this.addressBlacklist.revert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void revertBlacklist() {
|
||||||
|
if (this.addressBlacklist == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.addressBlacklist.revert();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user