React RBAC Guard #
react-rbac-guard
is a module allowing to manage visibility of particular components depending on user credentials (or current permissions set). Module uses approach that was inspired by "react-redux-connect" module.The package currently in the early development stage.
Dependensies ##
React RBAC requires either React new context API or React legacy context API support. Module tries to use new context API (React version >= 16.3) if available. Otherwise fallbacks to legacy context API. Legacy context API has problem with returningfalse
from shouldComponentUpdate
in intermediate components (see docs).Installation ##
$> npm install react-rbac-guard
Integration in 5 easy steps ##
- Define your own class derived from
Requirement
class. It must implementisSatisfied
method that takes credentials as parameter. The method must returntrue
if requirement is satisfied by credentials andfalse
otherwise
import { Requirement } from "react-rbac-guard";
class Need extends Requirement {
constructor(permission) {
super();
this.permission = permission;
}
isSatisfied(credentials) {
// assume credentilas is an object
return credentials[this.permission] ? true : false;
}
}
- Create requirements
const NeedManagePost = new Need("CanManagePost");
const NeedManageComment = new Need("CanManageComment");
const NeedManageUser = new Need("CanManageUser");
- Create guards
import { guardFactory } from "react-rbac-guard";
const PostManager = guardFactory(NeedManagePost);
const CommentManager = guardFactory(NeedManageComment);
const UserManager = guardFactory(NeedManageUser);
- Provide credentials via
CredentialProvider
and use guards as components
import { CredentialProvider } from "react-rbac-guard";
class App extends Component {
render() {
const credentials = {}; // you have to provide it
return (
<CredentialProvider value={credentials}>
<PostManager>
<button>Edit Post</button>
<button>Delete Post</button>
</PostManager>
<CommentManager>
<button>Edit Comment</button>
<button>Delete Comment</button>
</CommentManager>
<UserManager>
<button>Block User</button>
</UserManager>
</CredentialProvider>
);
}
}
- Enjoy!
Capabilities ##
- You can use
all
,any
,not
functions to combine requirements.
// Let's assume we have NeedAdmin, NeedManager, NeedUser, NeedGuest requirements.
// You can produce new ones by combining them.
import { any, not } from "react-rbac-gurad";
const NeedAuthorized = not(NeedGuest);
const NeedExtendedRights = any(NeedAdmin, NeedManager);
In other words, you can define arbitrary predicate (in terms of mathematical logic) based on your requirements.- You can use Guard component directly (without guardFactory).
<Guard requirement={NeedAdmin}>
<button>Restart Server</button>
</Guard>
- You can use
protect
to protect your components (it behaves likeconnect
fromreact-redux-connect
).
import { protect } from "react-rbac-guard";
class CustomersList extends Component {
...
}
// exports decorated component (like connect in "react-redux-connect")
export default protect(NeedExtendedRights)(CustomersList);
or to protect external components
import { Button } from "react-bootstrap";
import { protect } from "react-rbac-guard";
const SignUpButton = protect(NeedGuest)(Button);
const SignOutButton = protect(NeedAuthrized)(Button);
- It's also possible to make a decision inside credentials object
class Credentials {
satisfies(requirement) {
return ...// return boolean depending on requirement
}
}
class MyRequirement extends Requirement {
...
isSatisfied(credentials) {
return credentilas.satisfies(this);
}
}
const credentials = new Credentials(...);
<CredentialProvider value={credentials}>
...
</CredentialProvider>