github.com/ConsenSys/Quorum@v20.10.0+incompatible/permission/contract/RoleManager.sol (about) 1 pragma solidity ^0.5.3; 2 3 import "./PermissionsUpgradable.sol"; 4 /** @title Role manager contract 5 * @notice This contract holds implementation logic for all role management 6 functionality. This can be called only by the implementation 7 contract only. there are few view functions exposed as public and 8 can be called directly. these are invoked by quorum for populating 9 permissions data in cache 10 */ 11 contract RoleManager { 12 PermissionsUpgradable private permUpgradable; 13 14 struct RoleDetails { 15 string roleId; 16 string orgId; 17 uint256 baseAccess; 18 bool isVoter; 19 bool isAdmin; 20 bool active; 21 } 22 23 RoleDetails[] private roleList; 24 mapping(bytes32 => uint256) private roleIndex; 25 uint256 private numberOfRoles; 26 27 event RoleCreated(string _roleId, string _orgId, uint256 _baseAccess, 28 bool _isVoter, bool _isAdmin); 29 event RoleRevoked(string _roleId, string _orgId); 30 31 /** @notice confirms that the caller is the address of implementation 32 contract 33 */ 34 modifier onlyImplementation { 35 require(msg.sender == permUpgradable.getPermImpl(), "invalid caller"); 36 _; 37 } 38 39 /** @notice constructor. sets the permissions upgradable address 40 */ 41 constructor (address _permUpgradable) public { 42 permUpgradable = PermissionsUpgradable(_permUpgradable); 43 } 44 45 /** @notice function to add a new role definition to an organization 46 * @param _roleId - unique identifier for the role being added 47 * @param _orgId - org id to which the role belongs 48 * @param _baseAccess - 0-ReadOnly, 1-Transact, 2-ContractDeply, 3- Full 49 * @param _isVoter - bool to indicate if voter role or not 50 * @param _isAdmin - bool to indicate if admin role or not 51 * @dev base access can have any of the following values: 52 0 - Read only 53 1 - Transact only 54 2 - Contract deploy. can transact as well 55 3 - Full access 56 */ 57 function addRole(string memory _roleId, string memory _orgId, uint256 _baseAccess, 58 bool _isVoter, bool _isAdmin) public onlyImplementation { 59 // Check if account already exists 60 require(roleIndex[keccak256(abi.encode(_roleId, _orgId))] == 0, "role exists for the org"); 61 numberOfRoles ++; 62 roleIndex[keccak256(abi.encode(_roleId, _orgId))] = numberOfRoles; 63 roleList.push(RoleDetails(_roleId, _orgId, _baseAccess, _isVoter, _isAdmin, true)); 64 emit RoleCreated(_roleId, _orgId, _baseAccess, _isVoter, _isAdmin); 65 66 } 67 68 /** @notice function to remove an existing role definition from an organization 69 * @param _roleId - unique identifier for the role being added 70 * @param _orgId - org id to which the role belongs 71 */ 72 function removeRole(string calldata _roleId, string calldata _orgId) external 73 onlyImplementation { 74 require(roleIndex[keccak256(abi.encode(_roleId, _orgId))] != 0, "role does not exist"); 75 uint256 rIndex = _getRoleIndex(_roleId, _orgId); 76 roleList[rIndex].active = false; 77 emit RoleRevoked(_roleId, _orgId); 78 } 79 80 /** @notice checks if the role is a voter role or not 81 * @param _roleId - unique identifier for the role being added 82 * @param _orgId - org id to which the role belongs 83 * @param _ultParent - master org id 84 * @return true or false 85 * @dev checks for the role existence in the passed org and master org 86 */ 87 function isVoterRole(string calldata _roleId, string calldata _orgId, 88 string calldata _ultParent) external view onlyImplementation returns (bool){ 89 if (!(roleExists(_roleId, _orgId, _ultParent))) { 90 return false; 91 } 92 uint256 rIndex; 93 if (roleIndex[keccak256(abi.encode(_roleId, _orgId))] != 0) { 94 rIndex = _getRoleIndex(_roleId, _orgId); 95 } 96 else { 97 rIndex = _getRoleIndex(_roleId, _ultParent); 98 } 99 return (roleList[rIndex].active && roleList[rIndex].isVoter); 100 } 101 102 /** @notice checks if the role is an admin role or not 103 * @param _roleId - unique identifier for the role being added 104 * @param _orgId - org id to which the role belongs 105 * @param _ultParent - master org id 106 * @return true or false 107 * @dev checks for the role existence in the passed org and master org 108 */ 109 function isAdminRole(string calldata _roleId, string calldata _orgId, 110 string calldata _ultParent) external view onlyImplementation returns (bool){ 111 if (!(roleExists(_roleId, _orgId, _ultParent))) { 112 return false; 113 } 114 uint256 rIndex; 115 if (roleIndex[keccak256(abi.encode(_roleId, _orgId))] != 0) { 116 rIndex = _getRoleIndex(_roleId, _orgId); 117 } 118 else { 119 rIndex = _getRoleIndex(_roleId, _ultParent); 120 } 121 return (roleList[rIndex].active && roleList[rIndex].isAdmin); 122 } 123 124 /** @notice returns the role details for a passed role id and org 125 * @param _roleId - unique identifier for the role being added 126 * @param _orgId - org id to which the role belongs 127 * @return role id 128 * @return org id 129 * @return access type 130 * @return bool to indicate if the role is a voter role 131 * @return bool to indicate if the role is active 132 */ 133 function getRoleDetails(string calldata _roleId, string calldata _orgId) 134 external view returns (string memory roleId, string memory orgId, 135 uint256 accessType, bool voter, bool admin, bool active) { 136 if (!(roleExists(_roleId, _orgId, ""))) { 137 return (_roleId, "", 0, false, false, false); 138 } 139 uint256 rIndex = _getRoleIndex(_roleId, _orgId); 140 return (roleList[rIndex].roleId, roleList[rIndex].orgId, 141 roleList[rIndex].baseAccess, roleList[rIndex].isVoter, 142 roleList[rIndex].isAdmin, roleList[rIndex].active); 143 } 144 145 /** @notice returns the role details for a passed role index 146 * @param _rIndex - unique identifier for the role being added 147 * @return role id 148 * @return org id 149 * @return access type 150 * @return bool to indicate if the role is a voter role 151 * @return bool to indicate if the role is active 152 */ 153 function getRoleDetailsFromIndex(uint256 _rIndex) external view returns 154 (string memory roleId, string memory orgId, uint256 accessType, 155 bool voter, bool admin, bool active) { 156 return (roleList[_rIndex].roleId, roleList[_rIndex].orgId, 157 roleList[_rIndex].baseAccess, roleList[_rIndex].isVoter, 158 roleList[_rIndex].isAdmin, roleList[_rIndex].active); 159 } 160 161 /** @notice returns the total number of roles in the network 162 * @return total number of roles 163 */ 164 function getNumberOfRoles() external view returns (uint256) { 165 return roleList.length; 166 } 167 168 /** @notice checks if the role exists for the given org or master org 169 * @param _roleId - unique identifier for the role being added 170 * @param _orgId - org id to which the role belongs 171 * @param _ultParent - master org id 172 * @return true or false 173 */ 174 function roleExists(string memory _roleId, string memory _orgId, 175 string memory _ultParent) public view returns (bool) { 176 uint256 id; 177 if (roleIndex[keccak256(abi.encode(_roleId, _orgId))] != 0) { 178 id = _getRoleIndex(_roleId, _orgId); 179 return roleList[id].active; 180 } 181 else if (roleIndex[keccak256(abi.encode(_roleId, _ultParent))] != 0) { 182 id = _getRoleIndex(_roleId, _ultParent); 183 return roleList[id].active; 184 } 185 return false; 186 } 187 188 /** @notice returns the role index based on role id and org id 189 * @param _roleId - role id 190 * @param _orgId - org id 191 * @return role index 192 */ 193 function _getRoleIndex(string memory _roleId, string memory _orgId) 194 internal view returns (uint256) { 195 return roleIndex[keccak256(abi.encode(_roleId, _orgId))] - 1; 196 } 197 }