Skip to content

Commit 95208ca

Browse files
authored
Merge pull request #243 from pluginpal/feature/rbac
Feature/rbac
2 parents 0a40d46 + 315bced commit 95208ca

File tree

16 files changed

+367
-298
lines changed

16 files changed

+367
-298
lines changed

.changeset/chatty-planets-stay.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"strapi-plugin-webtools": patch
3+
---
4+
5+
fix: use RBAC hook instead of <Page.Protect> for the permission check of the sidebar view

.changeset/ready-lands-taste.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"strapi-plugin-webtools": minor
3+
---
4+
5+
feat: introduce a new rbac permission 'overview'

.changeset/social-goats-juggle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"strapi-plugin-webtools": patch
3+
---
4+
5+
fix: cleanup rbac permission usage

.changeset/tall-mangos-hide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"strapi-plugin-webtools": patch
3+
---
4+
5+
fix: prevent the whole form from being removed when a user doesn't have url_alias permissions

packages/addons/sitemap/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"watch": "../../../node_modules/.bin/pack-up watch",
4141
"watch:link": "../../../node_modules/.bin/strapi-plugin watch:link",
4242
"develop:copy-files": "copyfiles -u 1 xsl/**/* ../../../playground/src/plugins/webtools-addon-sitemap/xsl/",
43-
"eslint": "../../../node_modules/.bin/eslint './**/*.{js,jsx,ts,tsx}'",
43+
"eslint": "../../../node_modules/.bin/eslint --max-warnings=0 './**/*.{js,jsx,ts,tsx}'",
4444
"eslint:fix": "../../../node_modules/.bin/eslint --fix './**/*.{js,jsx,ts,tsx}'"
4545
},
4646
"peerDependencies": {

packages/addons/sitemap/server/bootstrap.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { logMessage } from './utils';
22
import { getPluginService } from './utils/getPluginService';
33

44
export default async () => {
5-
const sitemap = strapi.plugin('webtools-addon-sitemap');
65
const cron = strapi.config.get('plugin::webtools-addon-sitemap.cron');
76

87
try {

packages/core/admin/components/EditView/index.tsx

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import React, { useEffect } from 'react';
22
import { useQuery } from 'react-query';
3-
import { unstable_useContentManagerContext, Page, useFetchClient } from '@strapi/strapi/admin';
3+
import {
4+
unstable_useContentManagerContext,
5+
useFetchClient,
6+
useRBAC,
7+
} from '@strapi/strapi/admin';
48
import EditForm from '../EditForm';
59
import Permalink from './Permalink';
610
import { isContentTypeEnabled } from '../../../server/util/enabledContentTypes';
@@ -9,6 +13,9 @@ import pluginPermissions from '../../permissions';
913

1014
const EditView = () => {
1115
const { get } = useFetchClient();
16+
const {
17+
allowedActions: { canSidebar },
18+
} = useRBAC(pluginPermissions);
1219
const context = unstable_useContentManagerContext();
1320
const {
1421
contentType,
@@ -31,19 +38,13 @@ const EditView = () => {
3138
useEffect(() => {
3239
const label = Array.from(document.querySelectorAll('label')).find((l) => l.textContent.startsWith('url_alias'));
3340
if (label) {
34-
let parentDiv = label.closest('div');
35-
for (let i = 0; i < 3; i++) {
36-
if (parentDiv) {
37-
// @ts-expect-error
38-
parentDiv = parentDiv.parentElement;
39-
}
40-
}
41-
if (parentDiv) {
42-
parentDiv.remove();
43-
}
41+
label.closest('div').remove();
4442
}
4543
}, []);
4644

45+
// Early return if the user has no permissions to view the sidebar.
46+
if (!canSidebar) return null;
47+
4748
// @ts-expect-error
4849
// Early return if the content type is not enabled.
4950
if (!isContentTypeEnabled(contentType)) return null;
@@ -54,12 +55,13 @@ const EditView = () => {
5455
aliases.refetch();
5556
}
5657

57-
// Early return for loading and error states.
58+
// Early return for loading, error and empty states.
5859
if (aliases.isLoading) return null;
5960
if (aliases.error) return null;
61+
if (!aliases.data) return null;
6062

6163
return (
62-
<Page.Protect permissions={pluginPermissions['edit-view.sidebar']}>
64+
<>
6365
<EditForm />
6466
{aliases.data.data.length === 0 && (
6567
<div>Save the form to generate the URL alias</div>
@@ -69,7 +71,7 @@ const EditView = () => {
6971
path={aliases.data.data[0].url_path}
7072
/>
7173
)}
72-
</Page.Protect>
74+
</>
7375
);
7476
};
7577

packages/core/admin/containers/App/index.tsx

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ import {
1313
SubNavSection,
1414
SubNavLink,
1515
} from '@strapi/design-system';
16-
import { Page, useStrapiApp, Layouts } from '@strapi/strapi/admin';
16+
import {
17+
useStrapiApp,
18+
Layouts,
19+
useRBAC,
20+
} from '@strapi/strapi/admin';
1721

1822
import pluginPermissions from '../../permissions';
1923
import pluginId from '../../helpers/pluginId';
@@ -27,6 +31,9 @@ import { InjectedRoute } from '../../types/injection-zones';
2731

2832
const App = () => {
2933
const getPlugin = useStrapiApp('MyComponent', (state) => state.getPlugin);
34+
const {
35+
allowedActions: { canList, canPatterns, canOverview },
36+
} = useRBAC(pluginPermissions);
3037

3138
const plugin = getPlugin(pluginId);
3239

@@ -36,48 +43,54 @@ const App = () => {
3643
const currentPath = location.pathname;
3744

3845
return (
39-
<Page.Protect permissions={pluginPermissions['settings.patterns']}>
40-
<Layouts.Root
41-
sideNav={(
42-
<SubNav>
43-
<SubNavHeader value="" label="Webtools" />
44-
<SubNavSections>
45-
<SubNavSection label="Core">
46+
<Layouts.Root
47+
sideNav={(
48+
<SubNav>
49+
<SubNavHeader value="" label="Webtools" />
50+
<SubNavSections>
51+
<SubNavSection label="Core">
52+
{canOverview && (
4653
<SubNavLink tag={Link} to="/plugins/webtools" key="test" className={currentPath === '/plugins/webtools' ? 'active' : ''}>
4754
Overview
4855
</SubNavLink>
56+
)}
57+
{canList && (
4958
<SubNavLink tag={Link} to="/plugins/webtools/urls" key="test" className={currentPath.startsWith('/plugins/webtools/urls') ? 'active' : ''}>
5059
All URLs
5160
</SubNavLink>
61+
)}
62+
{canPatterns && (
5263
<SubNavLink tag={Link} to="/plugins/webtools/patterns" key="test" className={currentPath.startsWith('/plugins/webtools/patterns') ? 'active' : ''}>
5364
Url Patterns
5465
</SubNavLink>
55-
</SubNavSection>
66+
)}
67+
</SubNavSection>
68+
{routerComponents.length > 0 && (
5669
<SubNavSection label="Addons">
5770
{routerComponents.map(({ path, label }) => (
5871
<SubNavLink tag={Link} to={`/plugins/webtools${path}`} key={path} className={currentPath.startsWith(`/plugins/webtools${path}`) ? 'active' : ''}>
5972
{label}
6073
</SubNavLink>
6174
))}
6275
</SubNavSection>
63-
</SubNavSections>
64-
</SubNav>
65-
)}
66-
>
67-
<Routes>
68-
<Route path="/" element={<Overview />} />
69-
<Route path="/urls" element={<List />} />
70-
<Route path="/patterns" element={<PatternsListPage />} />
71-
<Route path="/patterns/new" element={<PatternsCreatePage />} />
72-
<Route path="/patterns/:id" element={<PatternsEditPage />} />
73-
{routerComponents.map(({ path, Component }) => (
74-
<Route path={path} element={<Component />} />
75-
))}
76+
)}
77+
</SubNavSections>
78+
</SubNav>
79+
)}
80+
>
81+
<Routes>
82+
<Route path="/" element={<Overview />} />
83+
<Route path="/urls" element={<List />} />
84+
<Route path="/patterns" element={<PatternsListPage />} />
85+
<Route path="/patterns/new" element={<PatternsCreatePage />} />
86+
<Route path="/patterns/:id" element={<PatternsEditPage />} />
87+
{routerComponents.map(({ path, Component }) => (
88+
<Route path={path} element={<Component />} />
89+
))}
7690

77-
<Route path="*" element={<PageNotFound />} />
78-
</Routes>
79-
</Layouts.Root>
80-
</Page.Protect>
91+
<Route path="*" element={<PageNotFound />} />
92+
</Routes>
93+
</Layouts.Root>
8194
);
8295
};
8396

packages/core/admin/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { prefixPluginTranslations } from './helpers/prefixPluginTranslations';
1010
import CheckboxConfirmation from './components/ContentManagerHooks/ConfirmationCheckbox';
1111

1212
import { PluginIcon } from './components/PluginIcon';
13+
import pluginPermissions from './permissions';
1314

1415
const { name } = pluginPkg.strapi;
1516

@@ -41,7 +42,11 @@ export default {
4142

4243
return component;
4344
},
44-
permissions: [], // permissions to apply to the link
45+
permissions: [
46+
pluginPermissions['settings.overview'][0],
47+
pluginPermissions['settings.list'][0],
48+
pluginPermissions['settings.patterns'][0],
49+
],
4550
});
4651
},
4752
bootstrap(app: StrapiApp) {

packages/core/admin/permissions.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1+
/**
2+
* @todo
3+
* Change the permission keys to be single words.
4+
* That way the permissions work better wit the useRBAC hook.
5+
*/
16
const pluginPermissions = {
27
// This permission regards the main component (App) and is used to tell
38
// If the plugin link should be displayed in the menu
49
// And also if the plugin is accessible. This use case is found when a user types the url of the
510
// plugin directly in the browser
611
'settings.list': [{ action: 'plugin::webtools.settings.list', subject: null }],
7-
// 'settings.overview': [{ action: 'plugin::webtools.settings.overview', subject: null }],
12+
'settings.overview': [{ action: 'plugin::webtools.settings.overview', subject: null }],
813
'settings.patterns': [{ action: 'plugin::webtools.settings.patterns', subject: null }],
914
'edit-view.sidebar': [{ action: 'plugin::webtools.edit-view.sidebar', subject: null }],
1015
};

0 commit comments

Comments
 (0)