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  }