github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/permission/v1/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 the role access passed is valid 60 require(_baseAccess < 4, "invalid access value"); 61 // Check if account already exists 62 require(roleIndex[keccak256(abi.encode(_roleId, _orgId))] == 0, "role exists for the org"); 63 numberOfRoles ++; 64 roleIndex[keccak256(abi.encode(_roleId, _orgId))] = numberOfRoles; 65 roleList.push(RoleDetails(_roleId, _orgId, _baseAccess, _isVoter, _isAdmin, true)); 66 emit RoleCreated(_roleId, _orgId, _baseAccess, _isVoter, _isAdmin); 67 68 } 69 70 /** @notice function to remove an existing role definition from an organization 71 * @param _roleId - unique identifier for the role being added 72 * @param _orgId - org id to which the role belongs 73 */ 74 function removeRole(string calldata _roleId, string calldata _orgId) external 75 onlyImplementation { 76 require(roleIndex[keccak256(abi.encode(_roleId, _orgId))] != 0, "role does not exist"); 77 uint256 rIndex = _getRoleIndex(_roleId, _orgId); 78 roleList[rIndex].active = false; 79 emit RoleRevoked(_roleId, _orgId); 80 } 81 82 /** @notice checks if the role is a voter role or not 83 * @param _roleId - unique identifier for the role being added 84 * @param _orgId - org id to which the role belongs 85 * @param _ultParent - master org id 86 * @return true or false 87 * @dev checks for the role existence in the passed org and master org 88 */ 89 function isVoterRole(string calldata _roleId, string calldata _orgId, 90 string calldata _ultParent) external view onlyImplementation returns (bool){ 91 if (!(roleExists(_roleId, _orgId, _ultParent))) { 92 return false; 93 } 94 uint256 rIndex; 95 if (roleIndex[keccak256(abi.encode(_roleId, _orgId))] != 0) { 96 rIndex = _getRoleIndex(_roleId, _orgId); 97 } 98 else { 99 rIndex = _getRoleIndex(_roleId, _ultParent); 100 } 101 return (roleList[rIndex].active && roleList[rIndex].isVoter); 102 } 103 104 /** @notice checks if the role is an admin role or not 105 * @param _roleId - unique identifier for the role being added 106 * @param _orgId - org id to which the role belongs 107 * @param _ultParent - master org id 108 * @return true or false 109 * @dev checks for the role existence in the passed org and master org 110 */ 111 function isAdminRole(string calldata _roleId, string calldata _orgId, 112 string calldata _ultParent) external view onlyImplementation returns (bool){ 113 if (!(roleExists(_roleId, _orgId, _ultParent))) { 114 return false; 115 } 116 uint256 rIndex; 117 if (roleIndex[keccak256(abi.encode(_roleId, _orgId))] != 0) { 118 rIndex = _getRoleIndex(_roleId, _orgId); 119 } 120 else { 121 rIndex = _getRoleIndex(_roleId, _ultParent); 122 } 123 return (roleList[rIndex].active && roleList[rIndex].isAdmin); 124 } 125 126 /** @notice returns the role details for a passed role id and org 127 * @param _roleId - unique identifier for the role being added 128 * @param _orgId - org id to which the role belongs 129 * @return role id 130 * @return org id 131 * @return access type 132 * @return bool to indicate if the role is a voter role 133 * @return bool to indicate if the role is active 134 */ 135 function getRoleDetails(string calldata _roleId, string calldata _orgId) 136 external view returns (string memory roleId, string memory orgId, 137 uint256 accessType, bool voter, bool admin, bool active) { 138 if (!(roleExists(_roleId, _orgId, ""))) { 139 return (_roleId, "", 0, false, false, false); 140 } 141 uint256 rIndex = _getRoleIndex(_roleId, _orgId); 142 return (roleList[rIndex].roleId, roleList[rIndex].orgId, 143 roleList[rIndex].baseAccess, roleList[rIndex].isVoter, 144 roleList[rIndex].isAdmin, roleList[rIndex].active); 145 } 146 147 /** @notice returns the role details for a passed role index 148 * @param _rIndex - unique identifier for the role being added 149 * @return role id 150 * @return org id 151 * @return access type 152 * @return bool to indicate if the role is a voter role 153 * @return bool to indicate if the role is active 154 */ 155 function getRoleDetailsFromIndex(uint256 _rIndex) external view returns 156 (string memory roleId, string memory orgId, uint256 accessType, 157 bool voter, bool admin, bool active) { 158 return (roleList[_rIndex].roleId, roleList[_rIndex].orgId, 159 roleList[_rIndex].baseAccess, roleList[_rIndex].isVoter, 160 roleList[_rIndex].isAdmin, roleList[_rIndex].active); 161 } 162 163 /** @notice returns the total number of roles in the network 164 * @return total number of roles 165 */ 166 function getNumberOfRoles() external view returns (uint256) { 167 return roleList.length; 168 } 169 170 /** @notice checks if the role exists for the given org or master org 171 * @param _roleId - unique identifier for the role being added 172 * @param _orgId - org id to which the role belongs 173 * @param _ultParent - master org id 174 * @return true or false 175 */ 176 function roleExists(string memory _roleId, string memory _orgId, 177 string memory _ultParent) public view returns (bool) { 178 uint256 id; 179 if (roleIndex[keccak256(abi.encode(_roleId, _orgId))] != 0) { 180 id = _getRoleIndex(_roleId, _orgId); 181 return roleList[id].active; 182 } 183 else if (roleIndex[keccak256(abi.encode(_roleId, _ultParent))] != 0) { 184 id = _getRoleIndex(_roleId, _ultParent); 185 return roleList[id].active; 186 } 187 return false; 188 } 189 190 /** @notice returns the role index based on role id and org id 191 * @param _roleId - role id 192 * @param _orgId - org id 193 * @return role index 194 */ 195 function _getRoleIndex(string memory _roleId, string memory _orgId) 196 internal view returns (uint256) { 197 return roleIndex[keccak256(abi.encode(_roleId, _orgId))] - 1; 198 } 199 }