Skip to content

Commit acf283c

Browse files
committed
fix: cleanup rbac permission usage
1 parent 6787412 commit acf283c

File tree

8 files changed

+324
-281
lines changed

8 files changed

+324
-281
lines changed

.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

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

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

1823
import pluginPermissions from '../../permissions';
1924
import pluginId from '../../helpers/pluginId';
@@ -27,6 +32,9 @@ import { InjectedRoute } from '../../types/injection-zones';
2732

2833
const App = () => {
2934
const getPlugin = useStrapiApp('MyComponent', (state) => state.getPlugin);
35+
const {
36+
allowedActions: { canList, canPatterns, canOverview },
37+
} = useRBAC(pluginPermissions);
3038

3139
const plugin = getPlugin(pluginId);
3240

@@ -36,48 +44,54 @@ const App = () => {
3644
const currentPath = location.pathname;
3745

3846
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">
47+
<Layouts.Root
48+
sideNav={(
49+
<SubNav>
50+
<SubNavHeader value="" label="Webtools" />
51+
<SubNavSections>
52+
<SubNavSection label="Core">
53+
{canOverview && (
4654
<SubNavLink tag={Link} to="/plugins/webtools" key="test" className={currentPath === '/plugins/webtools' ? 'active' : ''}>
4755
Overview
4856
</SubNavLink>
57+
)}
58+
{canList && (
4959
<SubNavLink tag={Link} to="/plugins/webtools/urls" key="test" className={currentPath.startsWith('/plugins/webtools/urls') ? 'active' : ''}>
5060
All URLs
5161
</SubNavLink>
62+
)}
63+
{canPatterns && (
5264
<SubNavLink tag={Link} to="/plugins/webtools/patterns" key="test" className={currentPath.startsWith('/plugins/webtools/patterns') ? 'active' : ''}>
5365
Url Patterns
5466
</SubNavLink>
55-
</SubNavSection>
67+
)}
68+
</SubNavSection>
69+
{routerComponents.length > 0 && (
5670
<SubNavSection label="Addons">
5771
{routerComponents.map(({ path, label }) => (
5872
<SubNavLink tag={Link} to={`/plugins/webtools${path}`} key={path} className={currentPath.startsWith(`/plugins/webtools${path}`) ? 'active' : ''}>
5973
{label}
6074
</SubNavLink>
6175
))}
6276
</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-
))}
77+
)}
78+
</SubNavSections>
79+
</SubNav>
80+
)}
81+
>
82+
<Routes>
83+
<Route path="/" element={<Overview />} />
84+
<Route path="/urls" element={<List />} />
85+
<Route path="/patterns" element={<PatternsListPage />} />
86+
<Route path="/patterns/new" element={<PatternsCreatePage />} />
87+
<Route path="/patterns/:id" element={<PatternsEditPage />} />
88+
{routerComponents.map(({ path, Component }) => (
89+
<Route path={path} element={<Component />} />
90+
))}
7691

77-
<Route path="*" element={<PageNotFound />} />
78-
</Routes>
79-
</Layouts.Root>
80-
</Page.Protect>
92+
<Route path="*" element={<PageNotFound />} />
93+
</Routes>
94+
</Layouts.Root>
8195
);
8296
};
8397

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/screens/List/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ const List = () => {
7373
}
7474

7575
return (
76-
<Page.Protect permissions={pluginPermissions['settings.patterns']}>
76+
<Page.Protect permissions={pluginPermissions['settings.list']}>
7777
<Layouts.Header
7878
title={formatMessage({ id: 'webtools.settings.page.list.title', defaultMessage: 'URLs' })}
7979
subtitle={formatMessage({ id: 'webtools.settings.page.list.description', defaultMessage: 'A list of all the known URL aliases.' })}

packages/core/admin/screens/Overview/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const List = () => {
3131
);
3232
}
3333
return (
34-
<Page.Protect permissions={pluginPermissions['settings.patterns']}>
34+
<Page.Protect permissions={pluginPermissions['settings.overview']}>
3535
<Layouts.Header
3636
title={formatMessage({ id: 'webtools.settings.page.overview.title', defaultMessage: 'Overview' })}
3737
subtitle={formatMessage({ id: 'webtools.settings.page.overview.description', defaultMessage: 'Webtools global information' })}

packages/core/admin/screens/Patterns/CreatePage/index.tsx

Lines changed: 115 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ import {
1616
Grid,
1717
Loader,
1818
} from '@strapi/design-system';
19-
import { useNotification, getFetchClient, Layouts } from '@strapi/strapi/admin';
19+
import {
20+
useNotification,
21+
getFetchClient,
22+
Layouts,
23+
Page,
24+
} from '@strapi/strapi/admin';
2025
import { ArrowLeft, Check } from '@strapi/icons';
2126
import schema from './utils/schema';
2227
import { ErrorResponse } from '../../../types/error-response';
@@ -28,6 +33,7 @@ import { PatternFormValues, ValidatePatternResponse } from '../../../types/url-p
2833
import { EnabledContentTypes } from '../../../types/enabled-contenttypes';
2934
import LanguageCheckboxes from '../../../components/LanguageCheckboxes';
3035
import HiddenLocalizedField from '../../../components/HiddenLocalizedField';
36+
import pluginPermissions from '../../../permissions';
3137

3238
const CreatePatternPage = () => {
3339
const navigate = useNavigate();
@@ -100,118 +106,120 @@ const CreatePatternPage = () => {
100106
};
101107

102108
return (
103-
<Formik<PatternFormValues>
104-
enableReinitialize
105-
initialValues={{
106-
pattern: '', contenttype: '', languages: [], localized: false,
107-
}}
108-
onSubmit={handleCreateSubmit}
109-
validationSchema={schema}
110-
validate={validatePattern}
111-
validateOnChange={false}
112-
>
113-
{({
114-
handleSubmit,
115-
values,
116-
errors,
117-
touched,
118-
isSubmitting,
119-
setFieldValue,
120-
}) => (
121-
<Form noValidate onSubmit={handleSubmit}>
122-
<Layouts.Header
123-
title={formatMessage({
124-
id: 'webtools.settings.page.patterns.create.title',
125-
defaultMessage: 'Add new pattern',
126-
})}
127-
subtitle={formatMessage({
128-
id: 'webtools.settings.page.patterns.create.description',
129-
defaultMessage: 'Add a pattern for automatic URL alias generation.',
130-
})}
131-
navigationAction={(
132-
<DsLink startIcon={<ArrowLeft />} tag={Link} to={`/plugins/${pluginId}/patterns`}>
133-
{formatMessage({
134-
id: 'global.back',
135-
defaultMessage: 'Back',
136-
})}
137-
</DsLink>
138-
)}
139-
primaryAction={(
140-
<Button type="submit" loading={isSubmitting} startIcon={<Check />}>
141-
{formatMessage({
142-
id: 'global.save',
143-
defaultMessage: 'Save',
144-
})}
145-
</Button>
146-
)}
147-
/>
148-
<Layouts.Content>
149-
<Box
150-
background="neutral0"
151-
hasRadius
152-
shadow="filterShadow"
153-
paddingTop={6}
154-
paddingBottom={6}
155-
paddingLeft={7}
156-
paddingRight={7}
157-
>
158-
<Typography variant="delta">
159-
{formatMessage({
160-
id: 'webtools.settings.page.patterns.create.subtitle',
161-
defaultMessage: 'Pattern details',
162-
})}
163-
</Typography>
164-
<Grid.Root gap={4} marginTop={4}>
165-
<Grid.Item col={6} direction="column" alignItems="flex-start" gap="4">
166-
<Select
167-
name="contenttype"
168-
list={contentTypes.data.data}
169-
value={values.contenttype || ''}
170-
setFieldValue={setFieldValue}
171-
label={formatMessage({
172-
id: 'webtools.settings.form.contenttype.label',
173-
defaultMessage: 'Content type',
174-
})}
175-
error={
176-
errors.contenttype && touched.contenttype
177-
? formatMessage({ id: String(errors.contenttype), defaultMessage: 'Invalid value' })
178-
: null
179-
}
180-
/>
181-
{(values.contenttype !== '') && (
182-
<PatternField
183-
values={values}
184-
uid={values.contenttype}
109+
<Page.Protect permissions={pluginPermissions['settings.patterns']}>
110+
<Formik<PatternFormValues>
111+
enableReinitialize
112+
initialValues={{
113+
pattern: '', contenttype: '', languages: [], localized: false,
114+
}}
115+
onSubmit={handleCreateSubmit}
116+
validationSchema={schema}
117+
validate={validatePattern}
118+
validateOnChange={false}
119+
>
120+
{({
121+
handleSubmit,
122+
values,
123+
errors,
124+
touched,
125+
isSubmitting,
126+
setFieldValue,
127+
}) => (
128+
<Form noValidate onSubmit={handleSubmit}>
129+
<Layouts.Header
130+
title={formatMessage({
131+
id: 'webtools.settings.page.patterns.create.title',
132+
defaultMessage: 'Add new pattern',
133+
})}
134+
subtitle={formatMessage({
135+
id: 'webtools.settings.page.patterns.create.description',
136+
defaultMessage: 'Add a pattern for automatic URL alias generation.',
137+
})}
138+
navigationAction={(
139+
<DsLink startIcon={<ArrowLeft />} tag={Link} to={`/plugins/${pluginId}/patterns`}>
140+
{formatMessage({
141+
id: 'global.back',
142+
defaultMessage: 'Back',
143+
})}
144+
</DsLink>
145+
)}
146+
primaryAction={(
147+
<Button type="submit" loading={isSubmitting} startIcon={<Check />}>
148+
{formatMessage({
149+
id: 'global.save',
150+
defaultMessage: 'Save',
151+
})}
152+
</Button>
153+
)}
154+
/>
155+
<Layouts.Content>
156+
<Box
157+
background="neutral0"
158+
hasRadius
159+
shadow="filterShadow"
160+
paddingTop={6}
161+
paddingBottom={6}
162+
paddingLeft={7}
163+
paddingRight={7}
164+
>
165+
<Typography variant="delta">
166+
{formatMessage({
167+
id: 'webtools.settings.page.patterns.create.subtitle',
168+
defaultMessage: 'Pattern details',
169+
})}
170+
</Typography>
171+
<Grid.Root gap={4} marginTop={4}>
172+
<Grid.Item col={6} direction="column" alignItems="flex-start" gap="4">
173+
<Select
174+
name="contenttype"
175+
list={contentTypes.data.data}
176+
value={values.contenttype || ''}
185177
setFieldValue={setFieldValue}
178+
label={formatMessage({
179+
id: 'webtools.settings.form.contenttype.label',
180+
defaultMessage: 'Content type',
181+
})}
186182
error={
187-
errors.pattern && touched.pattern
188-
? errors.pattern
183+
errors.contenttype && touched.contenttype
184+
? formatMessage({ id: String(errors.contenttype), defaultMessage: 'Invalid value' })
189185
: null
190186
}
191187
/>
192-
)}
193-
<HiddenLocalizedField
194-
localized={getSelectedContentType(values.contenttype)?.localized}
195-
setFieldValue={setFieldValue}
196-
/>
197-
{values.localized && (
198-
<LanguageCheckboxes
199-
onChange={(newLanguages) => setFieldValue('languages', newLanguages)}
200-
selectedLanguages={values.languages}
201-
error={
202-
errors.languages && touched.languages
203-
? errors.languages
204-
: null
205-
}
188+
{(values.contenttype !== '') && (
189+
<PatternField
190+
values={values}
191+
uid={values.contenttype}
192+
setFieldValue={setFieldValue}
193+
error={
194+
errors.pattern && touched.pattern
195+
? errors.pattern
196+
: null
197+
}
198+
/>
199+
)}
200+
<HiddenLocalizedField
201+
localized={getSelectedContentType(values.contenttype)?.localized}
202+
setFieldValue={setFieldValue}
206203
/>
207-
)}
208-
</Grid.Item>
209-
</Grid.Root>
210-
</Box>
211-
</Layouts.Content>
212-
</Form>
213-
)}
214-
</Formik>
204+
{values.localized && (
205+
<LanguageCheckboxes
206+
onChange={(newLanguages) => setFieldValue('languages', newLanguages)}
207+
selectedLanguages={values.languages}
208+
error={
209+
errors.languages && touched.languages
210+
? errors.languages
211+
: null
212+
}
213+
/>
214+
)}
215+
</Grid.Item>
216+
</Grid.Root>
217+
</Box>
218+
</Layouts.Content>
219+
</Form>
220+
)}
221+
</Formik>
222+
</Page.Protect>
215223
);
216224
};
217225

0 commit comments

Comments
 (0)