diff --git a/controls/permission/NodeManager.sol b/controls/permission/NodeManager.sol index 4407d4acb..4e83a3149 100644 --- a/controls/permission/NodeManager.sol +++ b/controls/permission/NodeManager.sol @@ -5,7 +5,7 @@ import "./PermissionsUpgradable.sol"; contract NodeManager { PermissionsUpgradable private permUpgradable; // enum and struct declaration - // changing node status to integer (0-NotInList, 1- PendingApproval, 2-Approved, + // changing node status to integer (0-NotInList, 1- PendingApproval, 2-Approved, 3-Deactivated, 4-Blacklisted) // PendingDeactivation, Deactivated, PendingActivation, PendingBlacklisting, Blacklisted) // enum NodeStatus {NotInList, PendingApproval, Approved, PendingDeactivation, Deactivated, PendingActivation, PendingBlacklisting, Blacklisted} struct NodeDetails { @@ -27,16 +27,13 @@ contract NodeManager { event NodeApproved(string _enodeId); // node permission events for node decativation - event NodePendingDeactivation (string _enodeId); event NodeDeactivated(string _enodeId); // node permission events for node activation - event NodePendingActivation(string _enodeId); event NodeActivated(string _enodeId); // node permission events for node blacklist - event NodePendingBlacklist(string _enodeId); - event NodeBlacklisted(string); + event NodeBlacklisted(string _enodeId); modifier onlyImpl { @@ -88,7 +85,14 @@ contract NodeManager { return nodeList[getNodeIndex(_enodeId)].status; } - function addNode(string calldata _enodeId, string calldata _orgId) external + function addAdminNode(string calldata _enodeId, string calldata _orgId) external + onlyImpl + enodeNotInList(_enodeId) + { + addNode(_enodeId, _orgId); + approveNode(_enodeId, _orgId); + } + function addNode(string memory _enodeId, string memory _orgId) public onlyImpl enodeNotInList(_enodeId) { @@ -109,9 +113,12 @@ contract NodeManager { } // Adds a node to the nodeList mapping and emits node added event if successfully and node exists event of node is already present - function approveNode(string calldata _enodeId) external + function approveNode(string memory _enodeId, string memory _orgId) public onlyImpl + enodeInList(_enodeId) { + // node should belong to the passed org + require(checkOrg(_enodeId, _orgId), "Node does not belong to the org"); require(getNodeStatus(_enodeId) == 1, "Node need to be in PendingApproval status"); uint nodeIndex = getNodeIndex(_enodeId); // vote node @@ -119,98 +126,43 @@ contract NodeManager { emit NodeApproved(nodeList[nodeIndex].enodeId); } -// // Propose a node for deactivation from network -// function proposeDeactivation(string calldata _enodeId) external enodeInList(_enodeId) -// { -// require(getNodeStatus(_enodeId) == NodeStatus.Approved, "Node need to be in Approved status"); -// uint nodeIndex = getNodeIndex(_enodeId); -// nodeList[nodeIndex].status = NodeStatus.PendingDeactivation; -// emit NodePendingDeactivation(_enodeId); -// -// } -// -// //deactivates a given Enode and emits the decativation event -// function deactivateNode(string calldata _enodeId) external -// { -// require(getNodeStatus(_enodeId) == NodeStatus.PendingDeactivation, "Node need to be in PendingDeactivation status"); -// uint nodeIndex = getNodeIndex(_enodeId); -// nodeList[nodeIndex].status = NodeStatus.Deactivated; -// emit NodeDeactivated(nodeList[nodeIndex].enodeId); -// -// } -// -// // Propose node for blacklisting -// function proposeNodeActivation(string calldata _enodeId) external -// { -// require(getNodeStatus(_enodeId) == NodeStatus.Deactivated, "Node need to be in Deactivated status"); -// uint nodeIndex = getNodeIndex(_enodeId); -// nodeList[nodeIndex].status = NodeStatus.PendingActivation; -// // emit event -// emit NodePendingActivation(_enodeId); -// } + function updateNodeStatus(string calldata _enodeId, string calldata _orgId, uint _status) external + onlyImpl + enodeInList(_enodeId) + { + // node should belong to the org + require(checkOrg(_enodeId, _orgId), "Node does not belong to the org"); + // changing node status to integer (0-NotInList, 1- PendingApproval, 2-Approved, 3-Deactivated, 4-Blacklisted) + // operations that can be done 3-Deactivate Node, 4-ActivateNode, 5-Blacklist nodeList + require((_status == 3 || _status == 4 || _status == 5), "invalid operation"); -// //deactivates a given Enode and emits the decativation event -// function activateNode(string calldata _enodeId) external -// { -// require(getNodeStatus(_enodeId) == NodeStatus.PendingActivation, "Node need to be in PendingActivation status"); -// uint nodeIndex = getNodeIndex(_enodeId); -// require(voteStatus[nodeIndex][msg.sender] == false, "Node can not double vote"); -// // vote node -// updateVoteStatus(nodeIndex); -// // emit event -// // check if node vote reach majority -// if (checkEnoughVotes(nodeIndex)) { -// nodeList[nodeIndex].status = NodeStatus.Approved; -// emit NodeActivated(nodeList[nodeIndex].enodeId, nodeList[nodeIndex].ipAddrPort, nodeList[nodeIndex].discPort, nodeList[nodeIndex].raftPort); -// } -// } -// -// // Propose node for blacklisting -// function proposeNodeBlacklisting(string calldata _enodeId, string calldata _ipAddrPort, string calldata _discPort, string calldata _raftPort) external -// { -// if (checkVotingAccountExist()) { -// uint nodeIndex = getNodeIndex(_enodeId); -// // check if node is in the nodeList -// if (nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] != 0) { -// // no matter what status the node is in, vote will reset and node status change to PendingBlacklisting -// nodeList[nodeIndex].status = NodeStatus.PendingBlacklisting; -// nodeIndex = getNodeIndex(_enodeId); -// } else { -// // increment node number, add node to the list -// numberOfNodes++; -// nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] = numberOfNodes; -// nodeList.push(NodeDetails(_enodeId, _ipAddrPort, _discPort, _raftPort, NodeStatus.PendingBlacklisting)); -// nodeIndex = numberOfNodes; -// } -// // add voting status, numberOfNodes is the index of current proposed node -// initNodeVoteStatus(nodeIndex); -// // emit event -// emit NodePendingBlacklist(_enodeId); -// } -// } -// -// //Approve node blacklisting -// function blacklistNode(string calldata _enodeId) external -// { -// require(getNodeStatus(_enodeId) == NodeStatus.PendingBlacklisting, "Node need to be in PendingBlacklisting status"); -// uint nodeIndex = getNodeIndex(_enodeId); -// require(voteStatus[nodeIndex][msg.sender] == false, "Node can not double vote"); -// // vote node -// voteStatus[nodeIndex][msg.sender] = true; -// voteCount[nodeIndex]++; -// // emit event -// // check if node vote reach majority -// if (checkEnoughVotes(nodeIndex)) { -// nodeList[nodeIndex].status = NodeStatus.Blacklisted; -// emit NodeBlacklisted(nodeList[nodeIndex].enodeId, nodeList[nodeIndex].ipAddrPort, nodeList[nodeIndex].discPort, nodeList[nodeIndex].raftPort); -// } -// } + if (_status == 3){ + require(getNodeStatus(_enodeId) == 2, "Op cannot be performed"); + nodeList[getNodeIndex(_enodeId)].status = 3; + emit NodeDeactivated(_enodeId); + } + else if (_status == 4){ + require(getNodeStatus(_enodeId) == 3, "Op cannot be performed"); + nodeList[getNodeIndex(_enodeId)].status = 2; + emit NodeActivated(_enodeId); + } + else { + nodeList[getNodeIndex(_enodeId)].status = 5; + emit NodeBlacklisted(_enodeId); + } + } /* private functions */ - function getNodeIndex(string memory _enodeId) internal view returns (uint) + function getNodeIndex(string memory _enodeId) internal view + returns (uint) { return nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] - 1; } + function checkOrg(string memory _enodeId, string memory _orgId) internal view + returns(bool) + { + return (keccak256(abi.encodePacked(nodeList[getNodeIndex(_enodeId)].orgId)) == keccak256(abi.encodePacked(_orgId))); + } } diff --git a/controls/permission/OrgManager.sol b/controls/permission/OrgManager.sol index 8451e0664..69007ddf8 100644 --- a/controls/permission/OrgManager.sol +++ b/controls/permission/OrgManager.sol @@ -93,13 +93,27 @@ contract OrgManager { function updateOrg(string calldata _orgId, uint _status) external onlyImpl orgExists(_orgId) + returns (uint) { + require ((_status == 3 || _status == 5), "Operation not allowed"); + uint reqStatus; + uint pendingOp; + if (_status == 3) { + reqStatus = 2; + pendingOp = 2; + } + else if (_status == 5) { + reqStatus = 4; + pendingOp = 3; + } + require(checkOrgStatus(_orgId, reqStatus) == true, "Operation not allowed"); if (_status == 3) { suspendOrg(_orgId); } else { revokeOrgSuspension(_orgId); } + return pendingOp; } function approveOrgStatusUpdate(string calldata _orgId, uint _status) external diff --git a/controls/permission/PermissionsImplementation.sol b/controls/permission/PermissionsImplementation.sol index f3c9bb097..02b8b491a 100644 --- a/controls/permission/PermissionsImplementation.sol +++ b/controls/permission/PermissionsImplementation.sol @@ -33,19 +33,11 @@ contract PermissionsImplementation { } // Checks if the given network boot up is pending exists - modifier networkBootUpPending() + modifier networkBootStatus(bool _status) { - require(networkBoot == false, "Network boot up completed"); + require(networkBoot == _status, "Incorrect network boot status"); _; } - - // Checks if the given network boot up is pending exists - modifier networkBootUpDone() - { - require(networkBoot == true, "Network boot not complete"); - _; - } - modifier networkAdmin(address _account) { require(isNetworkAdmin(_account) == true, "Not an network admin"); _; @@ -57,17 +49,17 @@ contract PermissionsImplementation { } modifier orgNotExists(string memory _orgId) { - require(org.checkOrgExists(_orgId) == false, "Org already exists"); + require(checkOrgExists(_orgId) != true, "Org already exists"); _; } modifier orgExists(string memory _orgId) { - require(org.checkOrgExists(_orgId) == true, "Org does not exists"); + require(checkOrgExists(_orgId) == true, "Org does not exists"); _; } modifier orgApproved(string memory _orgId) { - require(org.checkOrgStatus(_orgId, 2) == true, "Org not approved"); + require(checkOrgApproved(_orgId) == true, "Org not approved"); _; } @@ -77,7 +69,7 @@ contract PermissionsImplementation { function setPolicy(string calldata _nwAdminOrg, string calldata _nwAdminRole, string calldata _oAdminRole) external onlyProxy - networkBootUpPending() + networkBootStatus(false) { adminOrg = _nwAdminOrg; adminRole = _nwAdminRole; @@ -86,7 +78,7 @@ contract PermissionsImplementation { function init(address _orgManager, address _rolesManager, address _acctManager, address _voterManager, address _nodeManager) external onlyProxy - networkBootUpPending() + networkBootStatus(false) { org = OrgManager(_orgManager); roles = RoleManager(_rolesManager); @@ -101,18 +93,17 @@ contract PermissionsImplementation { function addAdminNodes(string calldata _enodeId) external onlyProxy - networkBootUpPending() + networkBootStatus(false) { - nodes.addNode(_enodeId, adminOrg); - nodes.approveNode(_enodeId); + nodes.addAdminNode(_enodeId, adminOrg); } function addAdminAccounts(address _acct) external onlyProxy - networkBootUpPending() + networkBootStatus(false) { // add the account as a voter for the admin org - voter.addVoter(adminOrg, _acct); + updateVoterList(adminOrg, _acct, true); // add the account as an account with full access into the admin org accounts.addNWAdminAccount(_acct, adminOrg); } @@ -120,7 +111,7 @@ contract PermissionsImplementation { // update the network boot status as true function updateNetworkBootStatus() external onlyProxy - networkBootUpPending() + networkBootStatus(false) returns (bool) { networkBoot = true; @@ -137,7 +128,7 @@ contract PermissionsImplementation { // function for adding a new master org function addOrg(string calldata _orgId, string calldata _enodeId, address _caller) external onlyProxy - networkBootUpDone() + networkBootStatus(true) orgNotExists(_orgId) networkAdmin(_caller) { @@ -148,57 +139,43 @@ contract PermissionsImplementation { function approveOrg(string calldata _orgId, string calldata _enodeId, address _caller) external onlyProxy - networkBootUpDone() networkAdmin(_caller) { - require(org.checkOrgStatus(_orgId, 1) == true, "Nothing to approve"); - if ((voter.processVote(adminOrg, _caller, 1))) { + require(checkOrgStatus(_orgId, 1) == true, "Nothing to approve"); + if ((processVote(adminOrg, _caller, 1))) { org.approveOrg(_orgId); - nodes.approveNode(_enodeId); + nodes.approveNode(_enodeId, _orgId); } } -// function updateOrgStatus(string calldata _orgId, uint _status) external -// onlyProxy -// networkBootUpDone() -// orgExists(_orgId) -// networkAdmin(msg.sender) -// { -// require ((_status == 3 || _status == 5), "Operation not allowed"); -// uint reqStatus; -// uint pendingOp; -// if (_status == 3) { -// reqStatus = 2; -// pendingOp = 2; -// } -// else if (_status == 5) { -// reqStatus = 4; -// pendingOp = 3; -// } -// require(org.checkOrgStatus(_orgId, reqStatus) == true, "Operation not allowed"); -// org.updateOrg(_orgId, _status); -// voter.addVotingItem(adminOrg, _orgId, "", address(0), pendingOp); -// } -// -// function approveOrgStatus(string calldata _orgId, uint _status) external -// onlyProxy -// networkBootUpDone() -// orgExists(_orgId) -// networkAdmin(msg.sender) -// { -// require ((_status == 3 || _status == 5), "Operation not allowed"); -// uint pendingOp; -// if (_status == 3) { -// pendingOp = 2; -// } -// else if (_status == 5) { -// pendingOp = 3; -// } -// require(org.checkOrgStatus(_orgId, _status) == true, "Operation not allowed"); -// if ((voter.processVote(adminOrg, msg.sender, pendingOp))) { -// org.approveOrgStatusUpdate(_orgId, _status); -// } -// } + function updateOrgStatus(string calldata _orgId, uint _status) external + onlyProxy + orgExists(_orgId) + networkAdmin(msg.sender) + { + uint pendingOp; + pendingOp = org.updateOrg(_orgId, _status); + voter.addVotingItem(adminOrg, _orgId, "", address(0), pendingOp); + } + + function approveOrgStatus(string calldata _orgId, uint _status) external + onlyProxy + orgExists(_orgId) + networkAdmin(msg.sender) + { + require ((_status == 3 || _status == 5), "Operation not allowed"); + uint pendingOp; + if (_status == 3) { + pendingOp = 2; + } + else if (_status == 5) { + pendingOp = 3; + } + require(checkOrgStatus(_orgId, _status) == true, "Operation not allowed"); + if ((processVote(adminOrg, msg.sender, pendingOp))) { + org.approveOrgStatusUpdate(_orgId, _status); + } + } // returns org and master org details based on org index function getOrgInfo(uint _orgIndex) external view returns (string memory, uint) @@ -259,12 +236,11 @@ contract PermissionsImplementation { function assignOrgAdminAccount(string calldata _orgId, address _account, address _caller) external onlyProxy - networkBootUpDone() - networkAdmin(_caller) orgExists(_orgId) + networkAdmin(_caller) { // check if orgAdmin already exists if yes then op cannot be performed - require(accounts.orgAdminExists(_orgId) != true, "org admin exists"); + require(checkOrgAdminExists(_orgId) != true, "org admin exists"); // assign the account org admin role and propose voting accounts.assignAccountRole(_account, _orgId, orgAdminRole); //add voting item @@ -273,11 +249,10 @@ contract PermissionsImplementation { function approveOrgAdminAccount(address _account, address _caller) external onlyProxy - networkBootUpDone() networkAdmin(_caller) { require(isNetworkAdmin(_caller) == true, "can be called from network admin only"); - if ((voter.processVote(adminOrg, _caller, 4))) { + if ((processVote(adminOrg, _caller, 4))) { accounts.approveOrgAdminAccount(_account); } } @@ -285,35 +260,34 @@ contract PermissionsImplementation { function assignAccountRole(address _acct, string memory _orgId, string memory _roleId, address _caller) public onlyProxy - networkBootUpDone() - orgApproved(_orgId) orgAdmin(_caller, _orgId) + orgApproved(_orgId) { - // check if the account is part of another org. If yes then op cannot be done +// // check if the account is part of another org. If yes then op cannot be done require(validateAccount(_acct, _orgId) == true, "Operation cannot be performed"); - // check if role is existing for the org. if yes the op can be done - require(roles.roleExists(_roleId, _orgId) == true, "role does not exists"); - bool newRoleVoter = roles.isVoterRole(_roleId, _orgId); - // check the role of the account. if the current role is voter and new role is also voter - // voterlist change is not required. else voter list needs to be changed +// // check if role is existing for the org. if yes the op can be done + require(roleExists(_roleId, _orgId) == true, "role does not exists"); + bool newRoleVoter = isVoterRole(_roleId, _orgId); +// // check the role of the account. if the current role is voter and new role is also voter +// // voterlist change is not required. else voter list needs to be changed string memory acctRole = accounts.getAccountRole(_acct); if (keccak256(abi.encodePacked(acctRole)) == keccak256(abi.encodePacked("NONE"))) { //new account if (newRoleVoter) { // add to voter list - voter.addVoter(_orgId, _acct); + updateVoterList(_orgId, _acct, true); } } else { - bool currRoleVoter = roles.isVoterRole(acctRole, _orgId); + bool currRoleVoter = isVoterRole(acctRole, _orgId); if (!(currRoleVoter && newRoleVoter)) { if (newRoleVoter) { // add to voter list - voter.addVoter(_orgId, _acct); + updateVoterList(_orgId, _acct, true); } else { // delete from voter list - voter.deleteVoter(_orgId, _acct); + updateVoterList(_orgId, _acct, false); } } } @@ -322,7 +296,6 @@ contract PermissionsImplementation { function addNode(string calldata _orgId, string calldata _enodeId, address _caller) external onlyProxy - networkBootUpDone() orgApproved(_orgId) orgAdmin(_caller, _orgId) { @@ -355,10 +328,68 @@ contract PermissionsImplementation { return (accounts.valAcctAccessChange(_account, _orgId)); } + function checkOrgExists(string memory _orgId) internal view + returns (bool) + { + return org.checkOrgExists(_orgId); + } + + function checkOrgApproved(string memory _orgId) internal view + returns (bool) + { + return org.checkOrgStatus(_orgId, 2); + } + + function checkOrgStatus(string memory _orgId, uint _status) internal view + returns (bool) + { + return org.checkOrgStatus(_orgId, _status); + } + function checkOrgAdminExists(string memory _orgId) internal view + returns (bool) + { + return (accounts.orgAdminExists(_orgId)); + } + + function roleExists(string memory _roleId, string memory _orgId) internal view + returns (bool) + { + return (roles.roleExists(_roleId, _orgId)); + } + function isVoterRole(string memory _roleId, string memory _orgId) internal view + returns (bool) + { + return roles.isVoterRole(_roleId, _orgId); + } + + function processVote(string memory _orgId, address _caller, uint _pendingOp) internal + returns (bool) + { + return voter.processVote(_orgId, _caller, _pendingOp); + } + + function updateVoterList(string memory _orgId, address _account, bool _add) internal + { + if (_add) { + voter.addVoter(_orgId, _account); + } + else { + voter.deleteVoter(_orgId, _account); + } + } + function getAccountDetails(address _acct) external view returns (address, string memory, string memory, uint, bool) { return accounts.getAccountDetails(_acct); } + function updateNodeStatus(string calldata _orgId, string calldata _enodeId, uint _status, address _caller) external + onlyProxy + orgExists(_orgId) + orgAdmin(_caller, _orgId) + { + nodes.updateNodeStatus(_enodeId, _orgId, _status); + } + } \ No newline at end of file diff --git a/controls/permission/PermissionsInterface.sol b/controls/permission/PermissionsInterface.sol index 6b9965983..e8b2b384f 100644 --- a/controls/permission/PermissionsInterface.sol +++ b/controls/permission/PermissionsInterface.sol @@ -75,15 +75,15 @@ contract PermissionsInterface { permImplementation.approveOrg(_orgId, _enodeId, msg.sender); } -// function updateOrgStatus(string calldata _orgId, uint _status) external -// { -// permImplementation.updateOrgStatus(_orgId, _status); -// } -// -// function approveOrgStatus(string calldata _orgId, uint _status) external -// { -// permImplementation.approveOrgStatus(_orgId, _status); -// } + function updateOrgStatus(string calldata _orgId, uint _status) external + { + permImplementation.updateOrgStatus(_orgId, _status); + } + + function approveOrgStatus(string calldata _orgId, uint _status) external + { + permImplementation.approveOrgStatus(_orgId, _status); + } // returns org and master org details based on org index function getOrgInfo(uint _orgIndex) external view returns (string memory, uint) { @@ -153,6 +153,11 @@ contract PermissionsInterface { } + function updateNodeStatus(string calldata _orgId, string calldata _enodeId, uint _status) external + { + permImplementation.updateNodeStatus(_orgId, _enodeId, _status, msg.sender); + } + function getNodeStatus(string memory _enodeId) public view returns (uint) { return permImplementation.getNodeStatus(_enodeId);