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