RBAC Permissions for custom plugins — Strapi 4
It’s no big secret really, the Strapi documentation is flawed. Most of the work is done by guessing, console.logging and piecing together scattered pieces of information found in ancient forum posts on the official forum or random sites where someone in desperate need screams into the void. If you happen to find a piece of documentation on your topic, you will find that it covers about 60% (give or take) of what you're trying to achieve. But we are not here to complain, let’s get down to brass tacks. The following post will be a cleaned-up summary of information I found on the topic on the Strapi forum and links will be referenced at the end.
The problem I was trying to solve was to set up RBAC (Role Based Access Control) for a custom plugin, added to the left-hand menu. Essentially, this allows you to control who can use your plugin based on the role of the user.
This blog post assumes that you have already started to develop your custom plugin and will not cover that part.
The project structure looks something as follows. It is not complete but shows the relevant files. Subsequently, all path references will assume the plugin root as the topmost level.
.
├── LICENSE
├── README.md
├── admin
│ └── src
│ ├── pages
│ │ ├── HomePage
│ │ └── app
│ ├── permissions.js
│ └── index.js
├── server
│ ├── bootstrap.js
│ └── index.js
├── strapi-admin.js
└── strapi-server.jsFirst off, we start by creating /admin/src/permissions.js
const pluginPermissions = {
main: [{ action: 'plugin::site-publisher.read', subject: null }],
};
export default pluginPermissions;Action: This is the operation you want to be able to set permissions on, in my case it was Read operations on the plugin. Other operations available adhere to CRUD.
Next up, we will create a wrapper that uses check permissions before letting the user into the actual homepage of the plugin.
Create /admin/src/pages/app/index.js
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import { NotFound, CheckPagePermissions } from '@strapi/helper-plugin';
import pluginId from '../../pluginId';
import pluginPermissions from '../../permissions';
import HomePage from '../HomePage';
const App = () => {
return (
<CheckPagePermissions permissions={pluginPermissions.main}>
<Switch>
<Route path={`/plugins/${pluginId}`} component={HomePage} exact />
<Route component={NotFound} />
</Switch>
</CheckPagePermissions>
);
};
export default App;Reference /admin/src/permissions.js and ./pages/app in /admin/src/index.js
import pluginPkg from '../../package.json';
import pluginId from './pluginId';
import Initializer from './components/Initializer';
import PluginIcon from './components/PluginIcon';
+ import pluginPermissions from './permissions';
const { name, displayName } = pluginPkg.strapi;
export default {
register(app) {
app.addMenuLink({
to: `/plugins/${pluginId}`,
icon: PluginIcon,
intlLabel: {
id: `${pluginId}.plugin.name`,
defaultMessage: displayName,
},
Component: async () => {
+ const component = await import('./pages/app');
return component;
},
+ permissions: pluginPermissions.main,
});
app.registerPlugin({
id: pluginId,
name,
initializer: Initializer,
isReady: false,
});
},
};Edit /server/bootstrap.js
"use strict";
module.exports = ({ strapi }) => {
const actions = [
{
section: 'plugins',
displayName: 'Read',
uid: 'read',
pluginName: 'site-publisher',
},
];
strapi.admin.services.permission.actionProvider.registerMany(actions);
}section: Which part of the permissions page this should fall under.
pluginName: The name of the plugin
displayName: Name of the setting
uid: Unique identifier of this action
More information about actions and registering them can be found here.
Finally, in /server/index.js add a reference to the bootstrap file.
const routes = require('./routes');
const controllers = require('./controllers');
const config = require('./config');
+ const bootstrap = require('./bootstrap')
module.exports = {
+ bootstrap,
routes,
controllers,
config,That should be it! Rebuild and start your Strapi server and head on over to the permissions page to see if it is present.
References:
— https://contributor.strapi.io/docs/core/admin/permissions/how-they-work
— https://forum.strapi.io/t/limiting-access-of-a-custom-plugin-to-admin-users-only/27546
