mirror of https://github.com/hyperledger/besu
JSON RPC: Add permissioning node "allowlist" methods as alternatives equivalent to "whitelist" methods (#1094)
* added perm_getNodesAllowList RPC * added perm_addNodesToAllowList RPC * added perm_removeNodesFromAllowList RPC Signed-off-by: Sally MacFarlane <sally.macfarlane@consensys.net> Co-authored-by: mark-terry <36909937+mark-terry@users.noreply.github.com>pull/1100/head
parent
620ed461ca
commit
dab4b53601
@ -0,0 +1,96 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning; |
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.StringListParameter; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; |
||||
import org.hyperledger.besu.ethereum.p2p.network.exceptions.P2PDisabledException; |
||||
import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; |
||||
|
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
|
||||
public class PermAddNodesToAllowlist implements JsonRpcMethod { |
||||
|
||||
private final Optional<NodeLocalConfigPermissioningController> |
||||
nodeWhitelistPermissioningController; |
||||
|
||||
public PermAddNodesToAllowlist( |
||||
final Optional<NodeLocalConfigPermissioningController> nodeWhitelistPermissioningController) { |
||||
this.nodeWhitelistPermissioningController = nodeWhitelistPermissioningController; |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return RpcMethod.PERM_ADD_NODES_TO_ALLOWLIST.getMethodName(); |
||||
} |
||||
|
||||
@Override |
||||
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { |
||||
final StringListParameter enodeListParam = |
||||
requestContext.getRequiredParameter(0, StringListParameter.class); |
||||
|
||||
try { |
||||
if (nodeWhitelistPermissioningController.isPresent()) { |
||||
try { |
||||
final List<String> enodeURLs = enodeListParam.getStringList(); |
||||
final NodeLocalConfigPermissioningController.NodesWhitelistResult nodesWhitelistResult = |
||||
nodeWhitelistPermissioningController.get().addNodes(enodeURLs); |
||||
|
||||
switch (nodesWhitelistResult.result()) { |
||||
case SUCCESS: |
||||
return new JsonRpcSuccessResponse(requestContext.getRequest().getId()); |
||||
case ERROR_EMPTY_ENTRY: |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.NODE_WHITELIST_EMPTY_ENTRY); |
||||
case ERROR_EXISTING_ENTRY: |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.NODE_WHITELIST_EXISTING_ENTRY); |
||||
case ERROR_DUPLICATED_ENTRY: |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), |
||||
JsonRpcError.NODE_WHITELIST_DUPLICATED_ENTRY); |
||||
case ERROR_WHITELIST_PERSIST_FAIL: |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.WHITELIST_PERSIST_FAILURE); |
||||
case ERROR_WHITELIST_FILE_SYNC: |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.WHITELIST_FILE_SYNC); |
||||
default: |
||||
throw new Exception(); |
||||
} |
||||
} catch (IllegalArgumentException e) { |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.NODE_WHITELIST_INVALID_ENTRY); |
||||
} catch (Exception e) { |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.INTERNAL_ERROR); |
||||
} |
||||
} else { |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.NODE_WHITELIST_NOT_ENABLED); |
||||
} |
||||
} catch (P2PDisabledException e) { |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.P2P_DISABLED); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,62 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning; |
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; |
||||
import org.hyperledger.besu.ethereum.p2p.network.exceptions.P2PDisabledException; |
||||
import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; |
||||
|
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
|
||||
public class PermGetNodesAllowlist implements JsonRpcMethod { |
||||
|
||||
private final Optional<NodeLocalConfigPermissioningController> |
||||
nodeWhitelistPermissioningController; |
||||
|
||||
public PermGetNodesAllowlist( |
||||
final Optional<NodeLocalConfigPermissioningController> nodeWhitelistPermissioningController) { |
||||
this.nodeWhitelistPermissioningController = nodeWhitelistPermissioningController; |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return RpcMethod.PERM_GET_NODES_ALLOWLIST.getMethodName(); |
||||
} |
||||
|
||||
@Override |
||||
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { |
||||
try { |
||||
if (nodeWhitelistPermissioningController.isPresent()) { |
||||
final List<String> enodeList = |
||||
nodeWhitelistPermissioningController.get().getNodesWhitelist(); |
||||
|
||||
return new JsonRpcSuccessResponse(requestContext.getRequest().getId(), enodeList); |
||||
} else { |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.NODE_WHITELIST_NOT_ENABLED); |
||||
} |
||||
} catch (P2PDisabledException e) { |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.P2P_DISABLED); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,99 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning; |
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.JsonRpcMethod; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters.StringListParameter; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; |
||||
import org.hyperledger.besu.ethereum.p2p.network.exceptions.P2PDisabledException; |
||||
import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; |
||||
|
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
|
||||
public class PermRemoveNodesFromAllowlist implements JsonRpcMethod { |
||||
|
||||
private final Optional<NodeLocalConfigPermissioningController> |
||||
nodeWhitelistPermissioningController; |
||||
|
||||
public PermRemoveNodesFromAllowlist( |
||||
final Optional<NodeLocalConfigPermissioningController> nodeWhitelistPermissioningController) { |
||||
this.nodeWhitelistPermissioningController = nodeWhitelistPermissioningController; |
||||
} |
||||
|
||||
@Override |
||||
public String getName() { |
||||
return RpcMethod.PERM_REMOVE_NODES_FROM_ALLOWLIST.getMethodName(); |
||||
} |
||||
|
||||
@Override |
||||
public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { |
||||
final StringListParameter enodeListParam = |
||||
requestContext.getRequiredParameter(0, StringListParameter.class); |
||||
try { |
||||
if (nodeWhitelistPermissioningController.isPresent()) { |
||||
try { |
||||
final List<String> enodeURLs = enodeListParam.getStringList(); |
||||
final NodeLocalConfigPermissioningController.NodesWhitelistResult nodesWhitelistResult = |
||||
nodeWhitelistPermissioningController.get().removeNodes(enodeURLs); |
||||
|
||||
switch (nodesWhitelistResult.result()) { |
||||
case SUCCESS: |
||||
return new JsonRpcSuccessResponse(requestContext.getRequest().getId()); |
||||
case ERROR_EMPTY_ENTRY: |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.NODE_WHITELIST_EMPTY_ENTRY); |
||||
case ERROR_ABSENT_ENTRY: |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.NODE_WHITELIST_MISSING_ENTRY); |
||||
case ERROR_DUPLICATED_ENTRY: |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), |
||||
JsonRpcError.NODE_WHITELIST_DUPLICATED_ENTRY); |
||||
case ERROR_WHITELIST_PERSIST_FAIL: |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.WHITELIST_PERSIST_FAILURE); |
||||
case ERROR_WHITELIST_FILE_SYNC: |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.WHITELIST_FILE_SYNC); |
||||
case ERROR_FIXED_NODE_CANNOT_BE_REMOVED: |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), |
||||
JsonRpcError.NODE_WHITELIST_FIXED_NODE_CANNOT_BE_REMOVED); |
||||
default: |
||||
throw new Exception(); |
||||
} |
||||
} catch (IllegalArgumentException e) { |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.NODE_WHITELIST_INVALID_ENTRY); |
||||
} catch (Exception e) { |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.INTERNAL_ERROR); |
||||
} |
||||
} else { |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.NODE_WHITELIST_NOT_ENABLED); |
||||
} |
||||
} catch (P2PDisabledException e) { |
||||
return new JsonRpcErrorResponse( |
||||
requestContext.getRequest().getId(), JsonRpcError.P2P_DISABLED); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,200 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController.NodesWhitelistResult; |
||||
import static org.mockito.ArgumentMatchers.any; |
||||
import static org.mockito.ArgumentMatchers.eq; |
||||
import static org.mockito.Mockito.times; |
||||
import static org.mockito.Mockito.verify; |
||||
import static org.mockito.Mockito.verifyNoMoreInteractions; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; |
||||
import org.hyperledger.besu.ethereum.permissioning.AllowlistOperationResult; |
||||
import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
|
||||
import org.assertj.core.api.Assertions; |
||||
import org.assertj.core.util.Lists; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.Mock; |
||||
import org.mockito.junit.MockitoJUnitRunner; |
||||
|
||||
@RunWith(MockitoJUnitRunner.class) |
||||
public class PermAddNodesToAllowlistTest { |
||||
|
||||
private PermAddNodesToAllowlist method; |
||||
private static final String METHOD_NAME = "perm_addNodesToAllowlist"; |
||||
|
||||
private final String enode1 = |
||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; |
||||
private final String enode2 = |
||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; |
||||
private final String enode3 = |
||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; |
||||
private final String badEnode = "enod://dog@cat:fish"; |
||||
|
||||
@Mock private NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
method = new PermAddNodesToAllowlist(Optional.of(nodeLocalConfigPermissioningController)); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldReturnCorrectMethodName() { |
||||
assertThat(method.getName()).isEqualTo(METHOD_NAME); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldThrowInvalidJsonRpcParametersExceptionWhenOnlyBadEnode() { |
||||
final ArrayList<String> enodeList = Lists.newArrayList(badEnode); |
||||
final JsonRpcRequestContext request = buildRequest(enodeList); |
||||
final JsonRpcResponse expected = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_INVALID_ENTRY); |
||||
|
||||
when(nodeLocalConfigPermissioningController.addNodes(eq(enodeList))) |
||||
.thenThrow(IllegalArgumentException.class); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldThrowInvalidJsonRpcParametersExceptionWhenBadEnodeInList() { |
||||
final ArrayList<String> enodeList = Lists.newArrayList(enode2, badEnode, enode1); |
||||
final JsonRpcRequestContext request = buildRequest(enodeList); |
||||
final JsonRpcResponse expected = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_INVALID_ENTRY); |
||||
|
||||
when(nodeLocalConfigPermissioningController.addNodes(eq(enodeList))) |
||||
.thenThrow(IllegalArgumentException.class); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldThrowInvalidJsonRpcParametersExceptionWhenEmptyEnode() { |
||||
final JsonRpcRequestContext request = buildRequest(Lists.emptyList()); |
||||
final JsonRpcResponse expected = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_EMPTY_ENTRY); |
||||
|
||||
when(nodeLocalConfigPermissioningController.addNodes(eq(Lists.emptyList()))) |
||||
.thenReturn(new NodesWhitelistResult(AllowlistOperationResult.ERROR_EMPTY_ENTRY)); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
} |
||||
|
||||
@Test |
||||
public void whenRequestContainsDuplicatedNodesShouldReturnDuplicatedEntryError() { |
||||
final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1, enode1)); |
||||
final JsonRpcResponse expected = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_DUPLICATED_ENTRY); |
||||
|
||||
when(nodeLocalConfigPermissioningController.addNodes(any())) |
||||
.thenReturn(new NodesWhitelistResult(AllowlistOperationResult.ERROR_DUPLICATED_ENTRY)); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
} |
||||
|
||||
@Test |
||||
public void whenRequestContainsEmptyListOfNodesShouldReturnEmptyEntryError() { |
||||
final JsonRpcRequestContext request = buildRequest(new ArrayList<>()); |
||||
final JsonRpcResponse expected = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_EMPTY_ENTRY); |
||||
|
||||
when(nodeLocalConfigPermissioningController.addNodes(eq(new ArrayList<>()))) |
||||
.thenReturn(new NodesWhitelistResult(AllowlistOperationResult.ERROR_EMPTY_ENTRY)); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldAddSingleValidNode() { |
||||
final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1)); |
||||
final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getRequest().getId()); |
||||
|
||||
when(nodeLocalConfigPermissioningController.addNodes(any())) |
||||
.thenReturn(new NodesWhitelistResult(AllowlistOperationResult.SUCCESS)); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
|
||||
verify(nodeLocalConfigPermissioningController, times(1)).addNodes(any()); |
||||
verifyNoMoreInteractions(nodeLocalConfigPermissioningController); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldAddMultipleValidNodes() { |
||||
final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1, enode2, enode3)); |
||||
final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getRequest().getId()); |
||||
|
||||
when(nodeLocalConfigPermissioningController.addNodes(any())) |
||||
.thenReturn(new NodesWhitelistResult(AllowlistOperationResult.SUCCESS)); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
|
||||
verify(nodeLocalConfigPermissioningController, times(1)).addNodes(any()); |
||||
verifyNoMoreInteractions(nodeLocalConfigPermissioningController); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldFailWhenP2pDisabled() { |
||||
method = new PermAddNodesToAllowlist(Optional.empty()); |
||||
|
||||
final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1, enode2, enode3)); |
||||
; |
||||
final JsonRpcResponse expectedResponse = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_NOT_ENABLED); |
||||
|
||||
Assertions.assertThat(method.response(request)) |
||||
.isEqualToComparingFieldByField(expectedResponse); |
||||
} |
||||
|
||||
private JsonRpcRequestContext buildRequest(final List<String> enodeList) { |
||||
return new JsonRpcRequestContext( |
||||
new JsonRpcRequest("2.0", METHOD_NAME, new Object[] {enodeList})); |
||||
} |
||||
} |
@ -0,0 +1,121 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.Mockito.times; |
||||
import static org.mockito.Mockito.verify; |
||||
import static org.mockito.Mockito.verifyNoMoreInteractions; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; |
||||
import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; |
||||
|
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
|
||||
import org.assertj.core.api.Assertions; |
||||
import org.assertj.core.util.Lists; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.Mock; |
||||
import org.mockito.junit.MockitoJUnitRunner; |
||||
|
||||
@RunWith(MockitoJUnitRunner.class) |
||||
public class PermGetNodesAllowlistTest { |
||||
|
||||
private PermGetNodesAllowlist method; |
||||
private static final String METHOD_NAME = "perm_getNodesAllowlist"; |
||||
|
||||
private final String enode1 = |
||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; |
||||
private final String enode2 = |
||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.11:4567"; |
||||
private final String enode3 = |
||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.12:4567"; |
||||
|
||||
@Mock private NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
method = new PermGetNodesAllowlist(Optional.of(nodeLocalConfigPermissioningController)); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldReturnCorrectMethodName() { |
||||
assertThat(method.getName()).isEqualTo(METHOD_NAME); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldReturnSuccessResponseWhenListPopulated() { |
||||
final JsonRpcRequestContext request = buildRequest(); |
||||
final JsonRpcResponse expected = |
||||
new JsonRpcSuccessResponse( |
||||
request.getRequest().getId(), Lists.newArrayList(enode1, enode2, enode3)); |
||||
|
||||
when(nodeLocalConfigPermissioningController.getNodesWhitelist()) |
||||
.thenReturn(buildNodesList(enode1, enode2, enode3)); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
|
||||
verify(nodeLocalConfigPermissioningController, times(1)).getNodesWhitelist(); |
||||
verifyNoMoreInteractions(nodeLocalConfigPermissioningController); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldReturnSuccessResponseWhenListSetAndEmpty() { |
||||
final JsonRpcRequestContext request = buildRequest(); |
||||
final JsonRpcResponse expected = |
||||
new JsonRpcSuccessResponse(request.getRequest().getId(), Lists.emptyList()); |
||||
|
||||
when(nodeLocalConfigPermissioningController.getNodesWhitelist()).thenReturn(buildNodesList()); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
|
||||
verify(nodeLocalConfigPermissioningController, times(1)).getNodesWhitelist(); |
||||
verifyNoMoreInteractions(nodeLocalConfigPermissioningController); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldFailWhenP2pDisabled() { |
||||
method = new PermGetNodesAllowlist(Optional.empty()); |
||||
|
||||
final JsonRpcRequestContext request = buildRequest(); |
||||
final JsonRpcResponse expectedResponse = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_NOT_ENABLED); |
||||
|
||||
Assertions.assertThat(method.response(request)) |
||||
.isEqualToComparingFieldByField(expectedResponse); |
||||
} |
||||
|
||||
private JsonRpcRequestContext buildRequest() { |
||||
return new JsonRpcRequestContext(new JsonRpcRequest("2.0", METHOD_NAME, new Object[] {})); |
||||
} |
||||
|
||||
private List<String> buildNodesList(final String... enodes) { |
||||
return Lists.newArrayList(enodes); |
||||
} |
||||
} |
@ -0,0 +1,197 @@ |
||||
/* |
||||
* Copyright ConsenSys AG. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.permissioning; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController.NodesWhitelistResult; |
||||
import static org.mockito.ArgumentMatchers.any; |
||||
import static org.mockito.ArgumentMatchers.eq; |
||||
import static org.mockito.Mockito.times; |
||||
import static org.mockito.Mockito.verify; |
||||
import static org.mockito.Mockito.verifyNoMoreInteractions; |
||||
import static org.mockito.Mockito.when; |
||||
|
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequest; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.JsonRpcRequestContext; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcResponse; |
||||
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse; |
||||
import org.hyperledger.besu.ethereum.permissioning.AllowlistOperationResult; |
||||
import org.hyperledger.besu.ethereum.permissioning.NodeLocalConfigPermissioningController; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Optional; |
||||
|
||||
import org.assertj.core.api.Assertions; |
||||
import org.assertj.core.util.Lists; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.Mock; |
||||
import org.mockito.junit.MockitoJUnitRunner; |
||||
|
||||
@RunWith(MockitoJUnitRunner.class) |
||||
public class PermRemoveNodesFromAllowlistTest { |
||||
|
||||
private PermRemoveNodesFromAllowlist method; |
||||
private static final String METHOD_NAME = "perm_removeNodesFromAllowlist"; |
||||
|
||||
private final String enode1 = |
||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; |
||||
private final String enode2 = |
||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; |
||||
private final String enode3 = |
||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.10:4567"; |
||||
private final String badEnode = "enod://dog@cat:fish"; |
||||
|
||||
@Mock private NodeLocalConfigPermissioningController nodeLocalConfigPermissioningController; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
method = new PermRemoveNodesFromAllowlist(Optional.of(nodeLocalConfigPermissioningController)); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldReturnCorrectMethodName() { |
||||
assertThat(method.getName()).isEqualTo(METHOD_NAME); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldThrowInvalidJsonRpcParametersExceptionWhenBadEnode() { |
||||
final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(badEnode)); |
||||
final JsonRpcResponse expected = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_INVALID_ENTRY); |
||||
|
||||
when(nodeLocalConfigPermissioningController.removeNodes(eq(Lists.newArrayList(badEnode)))) |
||||
.thenThrow(IllegalArgumentException.class); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldThrowInvalidJsonRpcParametersExceptionWhenEmptyList() { |
||||
final JsonRpcRequestContext request = buildRequest(Lists.emptyList()); |
||||
final JsonRpcResponse expected = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_EMPTY_ENTRY); |
||||
|
||||
when(nodeLocalConfigPermissioningController.removeNodes(eq(Lists.emptyList()))) |
||||
.thenReturn(new NodesWhitelistResult(AllowlistOperationResult.ERROR_EMPTY_ENTRY)); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldRemoveSingleValidNode() { |
||||
final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1)); |
||||
final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getRequest().getId()); |
||||
|
||||
when(nodeLocalConfigPermissioningController.removeNodes(any())) |
||||
.thenReturn(new NodesWhitelistResult(AllowlistOperationResult.SUCCESS)); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
|
||||
verify(nodeLocalConfigPermissioningController, times(1)).removeNodes(any()); |
||||
verifyNoMoreInteractions(nodeLocalConfigPermissioningController); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldRemoveMultipleValidNodes() { |
||||
final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1, enode2, enode3)); |
||||
final JsonRpcResponse expected = new JsonRpcSuccessResponse(request.getRequest().getId()); |
||||
|
||||
when(nodeLocalConfigPermissioningController.removeNodes(any())) |
||||
.thenReturn(new NodesWhitelistResult(AllowlistOperationResult.SUCCESS)); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
|
||||
verify(nodeLocalConfigPermissioningController, times(1)).removeNodes(any()); |
||||
verifyNoMoreInteractions(nodeLocalConfigPermissioningController); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldFailWhenP2pDisabled() { |
||||
method = new PermRemoveNodesFromAllowlist(Optional.empty()); |
||||
final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1, enode2, enode3)); |
||||
final JsonRpcResponse expectedResponse = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_NOT_ENABLED); |
||||
|
||||
Assertions.assertThat(method.response(request)) |
||||
.isEqualToComparingFieldByField(expectedResponse); |
||||
} |
||||
|
||||
@Test |
||||
public void whenRequestContainsDuplicatedNodesShouldReturnDuplicatedEntryError() { |
||||
final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1, enode1)); |
||||
final JsonRpcResponse expected = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_DUPLICATED_ENTRY); |
||||
|
||||
when(nodeLocalConfigPermissioningController.removeNodes(any())) |
||||
.thenReturn(new NodesWhitelistResult(AllowlistOperationResult.ERROR_DUPLICATED_ENTRY)); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
} |
||||
|
||||
@Test |
||||
public void whenRequestContainsEmptyListOfNodesShouldReturnEmptyEntryError() { |
||||
final JsonRpcRequestContext request = buildRequest(new ArrayList<>()); |
||||
final JsonRpcResponse expected = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_EMPTY_ENTRY); |
||||
|
||||
when(nodeLocalConfigPermissioningController.removeNodes(eq(new ArrayList<>()))) |
||||
.thenReturn(new NodesWhitelistResult(AllowlistOperationResult.ERROR_EMPTY_ENTRY)); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
} |
||||
|
||||
@Test |
||||
public void shouldReturnCantRemoveBootnodeWhenRemovingBootnode() { |
||||
final JsonRpcRequestContext request = buildRequest(Lists.newArrayList(enode1)); |
||||
final JsonRpcResponse expected = |
||||
new JsonRpcErrorResponse( |
||||
request.getRequest().getId(), JsonRpcError.NODE_WHITELIST_FIXED_NODE_CANNOT_BE_REMOVED); |
||||
|
||||
when(nodeLocalConfigPermissioningController.removeNodes(any())) |
||||
.thenReturn( |
||||
new NodesWhitelistResult(AllowlistOperationResult.ERROR_FIXED_NODE_CANNOT_BE_REMOVED)); |
||||
|
||||
final JsonRpcResponse actual = method.response(request); |
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected); |
||||
} |
||||
|
||||
private JsonRpcRequestContext buildRequest(final List<String> enodeList) { |
||||
return new JsonRpcRequestContext( |
||||
new JsonRpcRequest("2.0", METHOD_NAME, new Object[] {enodeList})); |
||||
} |
||||
} |
Loading…
Reference in new issue