@ -3,10 +3,12 @@ package org.qortal.api.resource;
import io.swagger.v3.oas.annotations.Operation ;
import io.swagger.v3.oas.annotations.media.Content ;
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.tags.Tag ;
import org.qortal.api.* ;
import org.qortal.api.model.AddressListRequest ;
import org.qortal.crypto.Crypto ;
import org.qortal.data.account.AccountData ;
import org.qortal.list.ResourceListManager ;
@ -50,7 +52,7 @@ public class ListsResource {
throw ApiExceptionFactory . INSTANCE . createException ( request , ApiError . ADDRESS_UNKNOWN ) ;
// 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" ;
} 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
@Path ( "/blacklist/address/{address}" )
@ -82,7 +156,7 @@ public class ListsResource {
throw ApiExceptionFactory . INSTANCE . createException ( request , ApiError . ADDRESS_UNKNOWN ) ;
// 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" ;
} 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
@Path ( "/blacklist/address/{address}" )
@Operation (
summary = "Checks if an address is present in the local blacklist" ,
summary = "Check if an address is present in the local blacklist" ,
responses = {
@ApiResponse (
description = "Returns true or false if the list was queried, or an exception on failure" ,