RBAC.sol 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. pragma solidity ^0.4.18;
  2. import './Roles.sol';
  3. /**
  4. * @title RBAC (Role-Based Access Control)
  5. * @author Matt Condon (@Shrugs)
  6. * @dev Stores and provides setters and getters for roles and addresses.
  7. * Supports unlimited numbers of roles and addresses.
  8. * See //contracts/examples/RBACExample.sol for an example of usage.
  9. * This RBAC method uses strings to key roles. It may be beneficial
  10. * for you to write your own implementation of this interface using Enums or similar.
  11. */
  12. contract RBAC {
  13. using Roles for Roles.Role;
  14. mapping (string => Roles.Role) private roles;
  15. event LogRoleAdded(address addr, string roleName);
  16. event LogRoleRemoved(address addr, string roleName);
  17. /**
  18. * A constant role name for indicating admins.
  19. */
  20. string public constant ROLE_ADMIN = "admin";
  21. /**
  22. * @dev constructor. Sets msg.sender as admin by default
  23. */
  24. function RBAC()
  25. public
  26. {
  27. addRole(msg.sender, ROLE_ADMIN);
  28. }
  29. /**
  30. * @dev add a role to an address
  31. * @param addr address
  32. * @param roleName the name of the role
  33. */
  34. function addRole(address addr, string roleName)
  35. internal
  36. {
  37. roles[roleName].add(addr);
  38. LogRoleAdded(addr, roleName);
  39. }
  40. /**
  41. * @dev remove a role from an address
  42. * @param addr address
  43. * @param roleName the name of the role
  44. */
  45. function removeRole(address addr, string roleName)
  46. internal
  47. {
  48. roles[roleName].remove(addr);
  49. LogRoleRemoved(addr, roleName);
  50. }
  51. /**
  52. * @dev reverts if addr does not have role
  53. * @param addr address
  54. * @param roleName the name of the role
  55. * // reverts
  56. */
  57. function checkRole(address addr, string roleName)
  58. view
  59. public
  60. {
  61. roles[roleName].check(addr);
  62. }
  63. /**
  64. * @dev determine if addr has role
  65. * @param addr address
  66. * @param roleName the name of the role
  67. * @return bool
  68. */
  69. function hasRole(address addr, string roleName)
  70. view
  71. public
  72. returns (bool)
  73. {
  74. return roles[roleName].has(addr);
  75. }
  76. /**
  77. * @dev add a role to an address
  78. * @param addr address
  79. * @param roleName the name of the role
  80. */
  81. function adminAddRole(address addr, string roleName)
  82. onlyAdmin
  83. public
  84. {
  85. addRole(addr, roleName);
  86. }
  87. /**
  88. * @dev remove a role from an address
  89. * @param addr address
  90. * @param roleName the name of the role
  91. */
  92. function adminRemoveRole(address addr, string roleName)
  93. onlyAdmin
  94. public
  95. {
  96. removeRole(addr, roleName);
  97. }
  98. /**
  99. * @dev modifier to scope access to a single role (uses msg.sender as addr)
  100. * @param roleName the name of the role
  101. * // reverts
  102. */
  103. modifier onlyRole(string roleName)
  104. {
  105. checkRole(msg.sender, roleName);
  106. _;
  107. }
  108. /**
  109. * @dev modifier to scope access to admins
  110. * // reverts
  111. */
  112. modifier onlyAdmin()
  113. {
  114. checkRole(msg.sender, ROLE_ADMIN);
  115. _;
  116. }
  117. /**
  118. * @dev modifier to scope access to a set of roles (uses msg.sender as addr)
  119. * @param roleNames the names of the roles to scope access to
  120. * // reverts
  121. *
  122. * @TODO - when solidity supports dynamic arrays as arguments to modifiers, provide this
  123. * see: https://github.com/ethereum/solidity/issues/2467
  124. */
  125. // modifier onlyRoles(string[] roleNames) {
  126. // bool hasAnyRole = false;
  127. // for (uint8 i = 0; i < roleNames.length; i++) {
  128. // if (hasRole(msg.sender, roleNames[i])) {
  129. // hasAnyRole = true;
  130. // break;
  131. // }
  132. // }
  133. // require(hasAnyRole);
  134. // _;
  135. // }
  136. }