Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
O
openzeppelin-contracts-upgradeable
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
俞永鹏
openzeppelin-contracts-upgradeable
Commits
9bb2c958
Commit
9bb2c958
authored
Dec 01, 2017
by
Matt Condon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add adminAddRole, adminRemoveRole, and make hasRole/checkRole public
parent
e931c1cb
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
84 additions
and
87 deletions
+84
-87
RBACExample.sol
contracts/examples/RBACExample.sol
+0
-61
RBAC.sol
contracts/ownership/rbac/RBAC.sol
+57
-3
RBAC.js
test/RBAC.js
+18
-14
RBACMock.sol
test/helpers/RBACMock.sol
+9
-9
No files found.
contracts/examples/RBACExample.sol
deleted
100644 → 0
View file @
e931c1cb
pragma solidity ^0.4.8;
import '../ownership/rbac/RBAC.sol';
contract RBACExample is RBAC {
modifier onlyOwnerOrAdvisor()
{
require(
hasRole(msg.sender, "owner") ||
hasRole(msg.sender, "advisor")
);
_;
}
function RBACExample(address[] _advisors)
public
{
addRole(msg.sender, "owner");
addRole(msg.sender, "advisor");
for (uint256 i = 0; i < _advisors.length; i++) {
addRole(_advisors[i], "advisor");
}
}
function onlyOwnersCanDoThis()
onlyRole("owner")
view
external
{
}
function onlyAdvisorsCanDoThis()
onlyRole("advisor")
view
external
{
}
function eitherOwnerOrAdvisorCanDoThis()
onlyOwnerOrAdvisor
view
external
{
}
// owners can remove advisor's role
function removeAdvisor(address _addr)
onlyRole("owner")
public
{
// revert if the user isn't an advisor
// (perhaps you want to soft-fail here instead?)
checkRole(_addr, "advisor");
// remove the advisor's role
removeRole(_addr, "advisor");
}
}
contracts/ownership/rbac/RBAC.sol
View file @
9bb2c958
...
...
@@ -17,6 +17,23 @@ contract RBAC {
mapping (string => Roles.Role) internal roles;
event LogRoleAdded(address addr, string roleName);
event LogRoleRemoved(address addr, string roleName);
/**
* A constant role name for indicating admins.
*/
string public constant ROLE_ADMIN = "admin";
/**
* @dev constructor. Sets msg.sender as admin by default
*/
function RBAC()
public
{
addRole(msg.sender, ROLE_ADMIN);
}
/**
* @dev add a role to an address
* @param addr address
...
...
@@ -26,6 +43,7 @@ contract RBAC {
internal
{
roles[roleName].add(addr);
LogRoleAdded(addr, roleName);
}
/**
...
...
@@ -37,6 +55,7 @@ contract RBAC {
internal
{
roles[roleName].remove(addr);
LogRoleRemoved(addr, roleName);
}
/**
...
...
@@ -47,7 +66,7 @@ contract RBAC {
*/
function checkRole(address addr, string roleName)
view
internal
public
{
roles[roleName].check(addr);
}
...
...
@@ -60,13 +79,38 @@ contract RBAC {
*/
function hasRole(address addr, string roleName)
view
internal
public
returns (bool)
{
return roles[roleName].has(addr);
}
/**
* @dev add a role to an address
* @param addr address
* @param roleName the name of the role
*/
function adminAddRole(address addr, string roleName)
onlyAdmin
public
{
addRole(addr, roleName);
}
/**
* @dev remove a role from an address
* @param addr address
* @param roleName the name of the role
*/
function adminRemoveRole(address addr, string roleName)
onlyAdmin
public
{
removeRole(addr, roleName);
}
/**
* @dev modifier to scope access to a single role (uses msg.sender as addr)
* @param roleName the name of the role
* // reverts
...
...
@@ -78,11 +122,21 @@ contract RBAC {
}
/**
* @dev modifier to scope access to admins
* // reverts
*/
modifier onlyAdmin()
{
checkRole(msg.sender, ROLE_ADMIN);
_;
}
/**
* @dev modifier to scope access to a set of roles (uses msg.sender as addr)
* @param roleNames the names of the roles to scope access to
* // reverts
*
* @TODO - when solidity supports dynamic arrays as arguments, provide this
* @TODO - when solidity supports dynamic arrays as arguments
to modifiers
, provide this
* see: https://github.com/ethereum/solidity/issues/2467
*/
// modifier onlyRoles(string[] roleNames) {
...
...
test/RBAC.js
View file @
9bb2c958
...
...
@@ -10,39 +10,39 @@ contract('RBAC', function(accounts) {
let
mock
const
[
owner
,
admin
,
anyone
,
...
advisors
]
=
accounts
before
(
async
()
=>
{
mock
=
await
RBACMock
.
new
(
advisors
,
{
from
:
owner
})
mock
=
await
RBACMock
.
new
(
advisors
,
{
from
:
admin
})
})
context
(
'in normal conditions'
,
()
=>
{
it
(
'allows
owner to call #onlyOwner
sCanDoThis'
,
async
()
=>
{
await
mock
.
only
OwnersCanDoThis
({
from
:
owner
})
it
(
'allows
admin to call #onlyAdmin
sCanDoThis'
,
async
()
=>
{
await
mock
.
only
AdminsCanDoThis
({
from
:
admin
})
.
should
.
be
.
fulfilled
})
it
(
'allows
owner
to call #onlyAdvisorsCanDoThis'
,
async
()
=>
{
await
mock
.
onlyAdvisorsCanDoThis
({
from
:
owner
})
it
(
'allows
admin
to call #onlyAdvisorsCanDoThis'
,
async
()
=>
{
await
mock
.
onlyAdvisorsCanDoThis
({
from
:
admin
})
.
should
.
be
.
fulfilled
})
it
(
'allows advisors to call #onlyAdvisorsCanDoThis'
,
async
()
=>
{
await
mock
.
onlyAdvisorsCanDoThis
({
from
:
advisors
[
0
]
})
.
should
.
be
.
fulfilled
})
it
(
'allows
owner to call #eitherOwner
OrAdvisorCanDoThis'
,
async
()
=>
{
await
mock
.
either
OwnerOrAdvisorCanDoThis
({
from
:
owner
})
it
(
'allows
admin to call #eitherAdmin
OrAdvisorCanDoThis'
,
async
()
=>
{
await
mock
.
either
AdminOrAdvisorCanDoThis
({
from
:
admin
})
.
should
.
be
.
fulfilled
})
it
(
'allows advisors to call #either
Owner
OrAdvisorCanDoThis'
,
async
()
=>
{
await
mock
.
either
Owner
OrAdvisorCanDoThis
({
from
:
advisors
[
0
]
})
it
(
'allows advisors to call #either
Admin
OrAdvisorCanDoThis'
,
async
()
=>
{
await
mock
.
either
Admin
OrAdvisorCanDoThis
({
from
:
advisors
[
0
]
})
.
should
.
be
.
fulfilled
})
it
(
'does not allow
owner
s to call #nobodyCanDoThis'
,
async
()
=>
{
it
(
'does not allow
admin
s to call #nobodyCanDoThis'
,
async
()
=>
{
expectThrow
(
mock
.
nobodyCanDoThis
({
from
:
owner
})
mock
.
nobodyCanDoThis
({
from
:
admin
})
)
})
it
(
'does not allow advisors to call #nobodyCanDoThis'
,
async
()
=>
{
...
...
@@ -55,8 +55,12 @@ contract('RBAC', function(accounts) {
mock
.
nobodyCanDoThis
({
from
:
anyone
})
)
})
it
(
'allows an owner to remove an advisor
\'
s role'
,
async
()
=>
{
await
mock
.
removeAdvisor
(
advisors
[
0
],
{
from
:
owner
})
it
(
'allows an admin to remove an advisor
\'
s role'
,
async
()
=>
{
await
mock
.
removeAdvisor
(
advisors
[
0
],
{
from
:
admin
})
.
should
.
be
.
fulfilled
})
it
(
'allows admins to #adminRemoveRole'
,
async
()
=>
{
await
mock
.
adminRemoveRole
(
advisors
[
3
],
'advisor'
,
{
from
:
admin
})
.
should
.
be
.
fulfilled
})
})
...
...
test/helpers/RBACMock.sol
View file @
9bb2c958
...
...
@@ -5,10 +5,10 @@ import '../../contracts/ownership/rbac/RBAC.sol';
contract RBACMock is RBAC {
modifier only
Owner
OrAdvisor()
modifier only
Admin
OrAdvisor()
{
require(
hasRole(msg.sender, "
owner
") ||
hasRole(msg.sender, "
admin
") ||
hasRole(msg.sender, "advisor")
);
_;
...
...
@@ -17,7 +17,7 @@ contract RBACMock is RBAC {
function RBACMock(address[] _advisors)
public
{
addRole(msg.sender, "
owner
");
addRole(msg.sender, "
admin
");
addRole(msg.sender, "advisor");
for (uint256 i = 0; i < _advisors.length; i++) {
...
...
@@ -25,8 +25,8 @@ contract RBACMock is RBAC {
}
}
function only
Owner
sCanDoThis()
onlyRole("
owner
")
function only
Admin
sCanDoThis()
onlyRole("
admin
")
view
external
{
...
...
@@ -39,8 +39,8 @@ contract RBACMock is RBAC {
{
}
function either
Owner
OrAdvisorCanDoThis()
only
Owner
OrAdvisor
function either
Admin
OrAdvisorCanDoThis()
only
Admin
OrAdvisor
view
external
{
...
...
@@ -53,9 +53,9 @@ contract RBACMock is RBAC {
{
}
//
owner
s can remove advisor's role
//
admin
s can remove advisor's role
function removeAdvisor(address _addr)
only
Role("owner")
only
Admin
public
{
// revert if the user isn't an advisor
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment