mirror of https://github.com/poanetwork/quorum.git
325 lines
11 KiB
Solidity
325 lines
11 KiB
Solidity
|
pragma solidity ^0.5.3;
|
||
|
|
||
|
import "./RoleManager.sol";
|
||
|
import "./AccountManager.sol";
|
||
|
import "./VoterManager.sol";
|
||
|
import "./NodeManager.sol";
|
||
|
import "./OrgManager.sol";
|
||
|
|
||
|
contract PermissionsImplementation {
|
||
|
AccountManager private accounts;
|
||
|
RoleManager private roles;
|
||
|
VoterManager private voter;
|
||
|
NodeManager private nodes;
|
||
|
OrgManager private org;
|
||
|
|
||
|
string private adminOrg;
|
||
|
string private adminRole;
|
||
|
string private orgAdminRole;
|
||
|
|
||
|
uint private fullAccess = 3;
|
||
|
|
||
|
// checks if first time network boot up has happened or not
|
||
|
bool private networkBoot = false;
|
||
|
|
||
|
// Checks if the given network boot up is pending exists
|
||
|
modifier networkBootUpPending()
|
||
|
{
|
||
|
require(networkBoot == false, "Network boot up completed");
|
||
|
_;
|
||
|
}
|
||
|
|
||
|
// 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");
|
||
|
_;
|
||
|
}
|
||
|
|
||
|
modifier orgAdmin(address _account, string memory _orgId) {
|
||
|
require(isOrgAdmin(_account, _orgId) == true, "Not an org admin");
|
||
|
_;
|
||
|
}
|
||
|
|
||
|
modifier orgNotExists(string memory _orgId) {
|
||
|
require(org.checkOrgExists(_orgId) == false, "Org already exists");
|
||
|
_;
|
||
|
}
|
||
|
|
||
|
modifier orgExists(string memory _orgId) {
|
||
|
require(org.checkOrgExists(_orgId) == true, "Org does not exists");
|
||
|
_;
|
||
|
}
|
||
|
|
||
|
modifier orgApproved(string memory _orgId) {
|
||
|
require(org.checkOrgStatus(_orgId, 2) == true, "Org not approved");
|
||
|
_;
|
||
|
}
|
||
|
|
||
|
|
||
|
function setPolicy(string calldata _nwAdminOrg, string calldata _nwAdminRole, string calldata _oAdminRole) external
|
||
|
networkBootUpPending()
|
||
|
{
|
||
|
adminOrg = _nwAdminOrg;
|
||
|
adminRole = _nwAdminRole;
|
||
|
orgAdminRole = _oAdminRole;
|
||
|
}
|
||
|
|
||
|
function init(address _orgManager, address _rolesManager, address _acctManager, address _voterManager, address _nodeManager) external
|
||
|
networkBootUpPending()
|
||
|
{
|
||
|
org = OrgManager(_orgManager);
|
||
|
roles = RoleManager(_rolesManager);
|
||
|
accounts = AccountManager(_acctManager);
|
||
|
voter = VoterManager(_voterManager);
|
||
|
nodes = NodeManager(_nodeManager);
|
||
|
|
||
|
org.addAdminOrg(adminOrg);
|
||
|
roles.addRole(adminRole, adminOrg, fullAccess, true);
|
||
|
accounts.setDefaults(adminRole, orgAdminRole);
|
||
|
}
|
||
|
|
||
|
function addAdminNodes(string calldata _enodeId) external
|
||
|
networkBootUpPending()
|
||
|
{
|
||
|
nodes.addNode(_enodeId, adminOrg);
|
||
|
nodes.approveNode(_enodeId);
|
||
|
}
|
||
|
|
||
|
function addAdminAccounts(address _acct) external
|
||
|
networkBootUpPending()
|
||
|
{
|
||
|
// add the account as a voter for the admin org
|
||
|
voter.addVoter(adminOrg, _acct);
|
||
|
// add the account as an account with full access into the admin org
|
||
|
accounts.addNWAdminAccount(_acct, adminOrg);
|
||
|
}
|
||
|
|
||
|
// update the network boot status as true
|
||
|
function updateNetworkBootStatus() external
|
||
|
networkBootUpPending()
|
||
|
returns (bool)
|
||
|
{
|
||
|
networkBoot = true;
|
||
|
return networkBoot;
|
||
|
}
|
||
|
|
||
|
// // Get network boot status
|
||
|
function getNetworkBootStatus() external view returns (bool)
|
||
|
{
|
||
|
return networkBoot;
|
||
|
}
|
||
|
|
||
|
// function for adding a new master org
|
||
|
function addOrg(string calldata _orgId, string calldata _enodeId) external
|
||
|
networkBootUpDone()
|
||
|
orgNotExists(_orgId)
|
||
|
networkAdmin(msg.sender)
|
||
|
{
|
||
|
org.addOrg(_orgId);
|
||
|
// add the node to permissioned node list
|
||
|
nodes.addNode(_enodeId, _orgId);
|
||
|
// org add has to be approved by network admin org. create an item for approval
|
||
|
voter.addVotingItem(adminOrg, _orgId, _enodeId, address(0), 1);
|
||
|
}
|
||
|
|
||
|
function approveOrg(string calldata _orgId, string calldata _enodeId) external
|
||
|
networkBootUpDone()
|
||
|
networkAdmin(msg.sender)
|
||
|
{
|
||
|
require(org.checkOrgStatus(_orgId, 1) == true, "Nothing to approve");
|
||
|
if ((voter.processVote(adminOrg, msg.sender, 1))) {
|
||
|
org.approveOrg(_orgId);
|
||
|
nodes.approveNode(_enodeId);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function updateOrgStatus(string calldata _orgId, uint _status) external
|
||
|
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
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
// returns org and master org details based on org index
|
||
|
function getOrgInfo(uint _orgIndex) external view returns (string memory, uint)
|
||
|
{
|
||
|
return org.getOrgInfo(_orgIndex);
|
||
|
}
|
||
|
|
||
|
// Role related functions
|
||
|
function addNewRole(string calldata _roleId, string calldata _orgId, uint _access, bool _voter) external
|
||
|
orgApproved(_orgId)
|
||
|
orgAdmin(msg.sender, _orgId)
|
||
|
{
|
||
|
//add new roles can be created by org admins only
|
||
|
roles.addRole(_roleId, _orgId, _access, _voter);
|
||
|
}
|
||
|
|
||
|
function removeRole(string calldata _roleId, string calldata _orgId) external
|
||
|
orgApproved(_orgId)
|
||
|
orgAdmin(msg.sender, _orgId)
|
||
|
{
|
||
|
roles.removeRole(_roleId, _orgId);
|
||
|
}
|
||
|
|
||
|
function getRoleDetails(string calldata _roleId, string calldata _orgId) external view returns (string memory, string memory, uint, bool, bool)
|
||
|
{
|
||
|
return roles.getRoleDetails(_roleId, _orgId);
|
||
|
|
||
|
}
|
||
|
|
||
|
// Org voter related functions
|
||
|
function getNumberOfVoters(string calldata _orgId) external view returns (uint){
|
||
|
|
||
|
return voter.getNumberOfValidVoters(_orgId);
|
||
|
}
|
||
|
|
||
|
function checkIfVoterExists(string calldata _orgId, address _acct) external view returns (bool)
|
||
|
{
|
||
|
return voter.checkIfVoterExists(_orgId, _acct);
|
||
|
}
|
||
|
|
||
|
function getVoteCount(string calldata _orgId) external view returns (uint, uint)
|
||
|
{
|
||
|
return voter.getVoteCount(_orgId);
|
||
|
}
|
||
|
|
||
|
function getPendingOp(string calldata _orgId) external view returns (string memory, string memory, address, uint)
|
||
|
{
|
||
|
return voter.getPendingOpDetails(_orgId);
|
||
|
}
|
||
|
|
||
|
function assignOrgAdminAccount(string calldata _orgId, address _account) external
|
||
|
networkBootUpDone()
|
||
|
networkAdmin(msg.sender)
|
||
|
orgExists(_orgId)
|
||
|
{
|
||
|
// check if orgAdmin already exists if yes then op cannot be performed
|
||
|
require(accounts.orgAdminExists(_orgId) != true, "org admin exists");
|
||
|
// assign the account org admin role and propose voting
|
||
|
accounts.assignAccountRole(_account, _orgId, orgAdminRole);
|
||
|
//add voting item
|
||
|
voter.addVotingItem(adminOrg, _orgId, "", _account, 4);
|
||
|
}
|
||
|
|
||
|
function approveOrgAdminAccount(address _account) external
|
||
|
networkBootUpDone()
|
||
|
networkAdmin(msg.sender)
|
||
|
{
|
||
|
require(isNetworkAdmin(msg.sender) == true, "can be called from network admin only");
|
||
|
if ((voter.processVote(adminOrg, msg.sender, 4))) {
|
||
|
accounts.approveOrgAdminAccount(_account);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
function assignAccountRole(address _acct, string memory _orgId, string memory _roleId) public
|
||
|
networkBootUpDone()
|
||
|
orgApproved(_orgId)
|
||
|
orgAdmin(msg.sender, _orgId)
|
||
|
{
|
||
|
// 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
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
bool currRoleVoter = roles.isVoterRole(acctRole, _orgId);
|
||
|
if (!(currRoleVoter && newRoleVoter)) {
|
||
|
if (newRoleVoter) {
|
||
|
// add to voter list
|
||
|
voter.addVoter(_orgId, _acct);
|
||
|
}
|
||
|
else {
|
||
|
// delete from voter list
|
||
|
voter.deleteVoter(_orgId, _acct);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
accounts.assignAccountRole(_acct, _orgId, _roleId);
|
||
|
}
|
||
|
|
||
|
function addNode(string calldata _orgId, string calldata _enodeId) external
|
||
|
networkBootUpDone()
|
||
|
orgApproved(_orgId)
|
||
|
orgAdmin(msg.sender, _orgId)
|
||
|
{
|
||
|
// check that the node is not part of another org
|
||
|
require(getNodeStatus(_enodeId) == 0, "Node present already");
|
||
|
nodes.addOrgNode(_enodeId, _orgId);
|
||
|
}
|
||
|
|
||
|
function getNodeStatus(string memory _enodeId) public view returns (uint)
|
||
|
{
|
||
|
return (nodes.getNodeStatus(_enodeId));
|
||
|
}
|
||
|
|
||
|
function isNetworkAdmin(address _account) public view returns (bool)
|
||
|
{
|
||
|
return (keccak256(abi.encodePacked(accounts.getAccountRole(_account))) == keccak256(abi.encodePacked(adminRole)));
|
||
|
}
|
||
|
|
||
|
function isOrgAdmin(address _account, string memory _orgId) public view returns (bool)
|
||
|
{
|
||
|
return (accounts.checkOrgAdmin(_account, _orgId));
|
||
|
}
|
||
|
|
||
|
function validateAccount(address _account, string memory _orgId) public view returns (bool)
|
||
|
{
|
||
|
return (accounts.valAcctAccessChange(_account, _orgId));
|
||
|
}
|
||
|
|
||
|
function getAccountDetails(address _acct) external view returns (address, string memory, string memory, uint, bool)
|
||
|
{
|
||
|
return accounts.getAccountDetails(_acct);
|
||
|
}
|
||
|
|
||
|
}
|