Skip to content

Instantly share code, notes, and snippets.

@DavidWells
Last active October 4, 2020 11:44
Show Gist options
  • Save DavidWells/8567870fc9d1045940bc81340feb83aa to your computer and use it in GitHub Desktop.
Save DavidWells/8567870fc9d1045940bc81340feb83aa to your computer and use it in GitHub Desktop.
import rules from "../rbac-rules";
const check = (rules, role, action, data) => {
const permissions = rules[role];
if (!permissions) {
// role is not present in the rules
return false;
}
const staticPermissions = permissions.static;
if (staticPermissions && staticPermissions.includes(action)) {
// static rule not provided for action
return true;
}
const dynamicPermissions = permissions.dynamic;
if (dynamicPermissions) {
const permissionCondition = dynamicPermissions[action];
if (!permissionCondition) {
// dynamic rule not provided for action
return false;
}
return permissionCondition(data);
}
return false;
};
// React Component
const Can = props => {
return check(rules, props.role, props.perform, props.data)
? props.yes()
: props.no();
}
Can.defaultProps = {
yes: () => null,
no: () => null
};
export default Can;
const rules = {
visitor: {
static: ["posts:list", "home-page:visit"]
},
writer: {
static: [
"posts:list",
"posts:create",
"users:getSelf",
"home-page:visit",
"dashboard-page:visit"
],
dynamic: {
"posts:edit": ({userId, postOwnerId}) => {
if (!userId || !postOwnerId) return false;
return userId === postOwnerId;
}
}
},
admin: {
static: [
"posts:list",
"posts:create",
"posts:edit",
"posts:delete",
"users:get",
"users:getSelf",
"home-page:visit",
"dashboard-page:visit"
]
}
};
export default rules;
import React from "react";
import { Redirect } from "react-router-dom";
import { AuthConsumer } from "../authContext";
import Can from "../components/Can";
import Logout from "../components/Logout";
import Profile from "../components/Profile";
import PostsList from "../components/PostsList";
const DashboardPage = () => (
<AuthConsumer>
{({ user }) => (
<Can
role={user.role}
perform="dashboard-page:visit"
yes={() => (
<div>
<h1>Dashboard</h1>
<Logout />
<Profile />
<PostsList />
</div>
)}
no={() => <Redirect to="/" />}
/>
)}
</AuthConsumer>
);
export default DashboardPage;
<Can
role={user.role}
perform="dashboard-page:visit"
yes={() => (
<h2>User can do it</h2>
)}
no={() => <h2>User can't do it</h2>}
/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment