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  }