Provide a small ACL framework for react-admin to manage resources views access based on pre-defined roles.
Tip: For a more complete solution for complex roles and permissions, check out ra-rbac.
npm install --save-dev ra-auth-acl
# or
yarn add ra-auth-acl
This library relies on the existing React Admin permission management, which allows to get permissions from an authenticated user.
- Use
<ResourceWithPermissions>
instead of the react-admin<Resource>
component.
import React from 'react';
import { Admin } from 'react-admin';
import { ResourceWithPermissions } from 'ra-auth-acl';
import authProvider from './authProvider';
import posts from './posts';
import comments from './comments';
render(
<Admin authProvider={authProvider}>
{permissions => [
<ResourceWithPermissions name="posts" permissions={permissions} {...posts} />,
<ResourceWithPermissions name="comments" permissions={permissions} {...comments} />,
]}
</Admin>
);
- On your custom authentication provider, return an access control list when the framework asks for it using the
AUTH_GET_PERMISSIONS
verb:
// authProvider.js
import { AUTH_GET_PERMISSIONS } from 'react-admin';
export default (type, params) => {
// ...
if (type === AUTH_GET_PERMISSIONS) {
return Promise.resolve({
posts: {
// Use the resource `name` prop as identifier
enabled: true,
list: true,
create: false,
edit: false,
show: true,
},
comments: {
enabled: false, // This won't show the resource at all
custom: true, // You can pass your own custom keys if needed
},
});
}
};
The ACL works with five default permissions, all false
by default:
- enabled: Display the resource or not.
- list: Display the list view of the resource
- create: Display the create view of the resource
- edit: Display the edit view of the resource
- show: Display the show view of the resource
- You can go with your custom permissions and use the
hasAccess
helper to customize your resources:
import { hasAccess } from 'ra-auth-acl';
export const UserList = ({ permissions, ...props }) => (
<List {...props}>
<Datagrid rowClick={hasAccess(permissions, 'users.edit') ? 'edit' : 'show'} expand={<UserEditEmbedded />}>
<TextField source="id" />
<TextField source="name" />
{hasAccess(permissions, 'users.custom') && <TextField source="role" />}
</Datagrid>
</List>
);
You can chain all the permissions you need in the hasAccess
helper. All of them should be true
to unlock the access.
hasAccess(permissions, 'user.edit', 'user.custom');
Instead of building the permissions list each time, you can store the role in the local storage or in a JSON Web Token, and request the permissions list at runtime:
// authProvider.js
import { AUTH_GET_PERMISSIONS } from 'react-admin';
import { buildFullAccessFor } from 'ra-auth-acl';
const permissions = {
admin: {
...buildFullAccessFor(['posts', 'comments', 'users', 'tags']),
},
user: {
...buildFullAccessFor(['posts', 'comments', 'tags']),
},
};
export default (type, params) => {
if (type === AUTH_GET_PERMISSIONS) {
const role = localStorage.getItem('role'); // Might be async request!
return Promise.resolve(permissions[role]);
}
};
This library is licensed under the MIT License, sponsored and supported by marmelab.