mirror of
https://github.com/strapi/strapi.git
synced 2025-12-04 19:13:20 +00:00
Add permissions to ctb main compo
Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
parent
e73101b664
commit
7d9041ecc3
@ -331,6 +331,11 @@ const data = {
|
||||
subject: 'application::address.address',
|
||||
conditions: [],
|
||||
},
|
||||
{
|
||||
action: 'plugins::content-manager.explorer.create',
|
||||
subject: 'application::restaurant.restaurant',
|
||||
conditions: [],
|
||||
},
|
||||
{
|
||||
action: 'plugins::content-manager.explorer.create',
|
||||
subject: 'application::homepage.homepage',
|
||||
@ -338,12 +343,12 @@ const data = {
|
||||
},
|
||||
|
||||
// Content type builder
|
||||
{
|
||||
action: 'plugins::content-type-builder.read',
|
||||
subject: null,
|
||||
fields: null,
|
||||
conditions: [],
|
||||
},
|
||||
// {
|
||||
// action: 'plugins::content-type-builder.read',
|
||||
// subject: null,
|
||||
// fields: null,
|
||||
// conditions: [],
|
||||
// },
|
||||
|
||||
// Documentation plugin
|
||||
// {
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import useUser from '../../hooks/useUser';
|
||||
import hasPermissions from '../../utils/hasPermissions';
|
||||
import LoadingIndicatorPage from '../LoadingIndicatorPage';
|
||||
|
||||
const WithPagePermissions = ({ permissions, children }) => {
|
||||
const userPermissions = useUser();
|
||||
const [state, setState] = useState({ isLoading: true, canAccess: false });
|
||||
|
||||
useEffect(() => {
|
||||
const checkPermission = async () => {
|
||||
try {
|
||||
const canAccess = await hasPermissions(userPermissions, permissions);
|
||||
|
||||
setState({ isLoading: false, canAccess });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
strapi.notification.error('notification.error');
|
||||
|
||||
setState({ isLoading: false });
|
||||
}
|
||||
};
|
||||
|
||||
checkPermission();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
if (state.isLoading) {
|
||||
return <LoadingIndicatorPage />;
|
||||
}
|
||||
|
||||
if (!state.canAccess) {
|
||||
return <Redirect to="/" />;
|
||||
}
|
||||
|
||||
return children;
|
||||
};
|
||||
|
||||
WithPagePermissions.defaultProps = {
|
||||
permissions: [],
|
||||
};
|
||||
|
||||
WithPagePermissions.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
permissions: PropTypes.array,
|
||||
};
|
||||
|
||||
export default WithPagePermissions;
|
||||
@ -0,0 +1,52 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import useUser from '../../hooks/useUser';
|
||||
import hasPermissions from '../../utils/hasPermissions';
|
||||
|
||||
// NOTE: this component is very similar to the WithPagePermissions
|
||||
// except that it does not handle redirections nor loading state
|
||||
|
||||
const WithPermissions = ({ permissions, children }) => {
|
||||
const userPermissions = useUser();
|
||||
const [state, setState] = useState({ isLoading: true, canAccess: false });
|
||||
|
||||
useEffect(() => {
|
||||
const checkPermission = async () => {
|
||||
try {
|
||||
const canAccess = await hasPermissions(userPermissions, permissions);
|
||||
|
||||
setState({ isLoading: false, canAccess });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
strapi.notification.error('notification.error');
|
||||
|
||||
setState({ isLoading: false });
|
||||
}
|
||||
};
|
||||
|
||||
checkPermission();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
if (state.isLoading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!state.canAccess) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return children;
|
||||
};
|
||||
|
||||
WithPermissions.defaultProps = {
|
||||
permissions: [],
|
||||
};
|
||||
|
||||
WithPermissions.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
permissions: PropTypes.array,
|
||||
};
|
||||
|
||||
export default WithPermissions;
|
||||
12
packages/strapi-helper-plugin/lib/src/hooks/useUser.js
Normal file
12
packages/strapi-helper-plugin/lib/src/hooks/useUser.js
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
*
|
||||
* useUser
|
||||
*
|
||||
*/
|
||||
|
||||
import { useContext } from 'react';
|
||||
import UserContext from '../contexts/UserContext';
|
||||
|
||||
const useUser = () => useContext(UserContext);
|
||||
|
||||
export default useUser;
|
||||
@ -79,6 +79,8 @@ export { default as SelectNav } from './components/SelectNav';
|
||||
export { default as SelectWrapper } from './components/SelectWrapper';
|
||||
export { default as UserProvider } from './components/UserProvider';
|
||||
export { default as ViewContainer } from './components/ViewContainer';
|
||||
export { default as WithPagePermissions } from './components/WithPagePermissions';
|
||||
export { default as WithPermissions } from './components/WithPermissions';
|
||||
|
||||
// Contexts
|
||||
export { GlobalContext, GlobalContextProvider, useGlobalContext } from './contexts/GlobalContext';
|
||||
@ -87,6 +89,7 @@ export { default as UserContext } from './contexts/UserContext';
|
||||
// Hooks
|
||||
export { default as useQuery } from './hooks/useQuery';
|
||||
export { default as useStrapi } from './hooks/useStrapi';
|
||||
export { default as useUser } from './hooks/useUser';
|
||||
|
||||
// Providers
|
||||
export { default as StrapiProvider } from './providers/StrapiProvider';
|
||||
|
||||
@ -6,11 +6,12 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useGlobalContext } from 'strapi-helper-plugin';
|
||||
import { useGlobalContext, WithPermissions } from 'strapi-helper-plugin';
|
||||
import { get } from 'lodash';
|
||||
import { Button } from '@buffetjs/core';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import getTrad from '../../utils/getTrad';
|
||||
import pluginPermissions from '../../utils/permissions';
|
||||
|
||||
// Create link from content-type-builder to content-manager
|
||||
function EditViewButton(props) {
|
||||
@ -31,9 +32,7 @@ function EditViewButton(props) {
|
||||
const category = get(modifiedData, 'category', '');
|
||||
|
||||
const suffixUrl =
|
||||
type === 'content-types'
|
||||
? props.getModelName()
|
||||
: `${category}/${componentSlug}`;
|
||||
type === 'content-types' ? props.getModelName() : `${category}/${componentSlug}`;
|
||||
|
||||
const handleClick = () => {
|
||||
emitEvent('willEditEditLayout');
|
||||
@ -49,22 +48,22 @@ function EditViewButton(props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
{...props}
|
||||
onClick={handleClick}
|
||||
icon={<FontAwesomeIcon icon="cog" style={{ fontSize: 13 }} />}
|
||||
label={formatMessage({
|
||||
id: getTrad(
|
||||
`injected-components.content-manager.edit-settings-view.link.${type}`
|
||||
),
|
||||
})}
|
||||
style={{
|
||||
paddingLeft: 15,
|
||||
paddingRight: 15,
|
||||
outline: 0,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
/>
|
||||
<WithPermissions permissions={pluginPermissions.main}>
|
||||
<Button
|
||||
{...props}
|
||||
onClick={handleClick}
|
||||
icon={<FontAwesomeIcon icon="cog" style={{ fontSize: 13 }} />}
|
||||
label={formatMessage({
|
||||
id: getTrad(`injected-components.content-manager.edit-settings-view.link.${type}`),
|
||||
})}
|
||||
style={{
|
||||
paddingLeft: 15,
|
||||
paddingRight: 15,
|
||||
outline: 0,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
/>
|
||||
</WithPermissions>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,8 @@
|
||||
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { LiLink, useGlobalContext } from 'strapi-helper-plugin';
|
||||
import { LiLink, useGlobalContext, WithPermissions } from 'strapi-helper-plugin';
|
||||
import pluginPermissions from '../../utils/permissions';
|
||||
|
||||
// Create link from content-type-builder to content-manager
|
||||
function EditViewLink(props) {
|
||||
@ -23,13 +24,15 @@ function EditViewLink(props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<LiLink
|
||||
{...props}
|
||||
url={url}
|
||||
onClick={() => {
|
||||
emitEvent('willEditEditLayout');
|
||||
}}
|
||||
/>
|
||||
<WithPermissions permissions={pluginPermissions.main}>
|
||||
<LiLink
|
||||
{...props}
|
||||
url={url}
|
||||
onClick={() => {
|
||||
emitEvent('willEditEditLayout');
|
||||
}}
|
||||
/>
|
||||
</WithPermissions>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -6,8 +6,9 @@
|
||||
|
||||
import React, { Suspense, lazy } from 'react';
|
||||
import { Switch, Route } from 'react-router-dom';
|
||||
import { LoadingIndicatorPage } from 'strapi-helper-plugin';
|
||||
import { LoadingIndicatorPage, WithPagePermissions } from 'strapi-helper-plugin';
|
||||
import pluginId from '../../pluginId';
|
||||
import pluginPermissions from '../../utils/permissions';
|
||||
import DataManagerProvider from '../DataManagerProvider';
|
||||
import RecursivePath from '../RecursivePath';
|
||||
import icons from './utils/icons.json';
|
||||
@ -17,22 +18,21 @@ const ListView = lazy(() => import('../ListView'));
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<Wrapper>
|
||||
<DataManagerProvider allIcons={icons}>
|
||||
<Suspense fallback={<LoadingIndicatorPage />}>
|
||||
<Switch>
|
||||
<Route
|
||||
path={`/plugins/${pluginId}/content-types/:uid`}
|
||||
component={ListView}
|
||||
/>
|
||||
<Route
|
||||
path={`/plugins/${pluginId}/component-categories/:categoryUid`}
|
||||
component={RecursivePath}
|
||||
/>
|
||||
</Switch>
|
||||
</Suspense>
|
||||
</DataManagerProvider>
|
||||
</Wrapper>
|
||||
<WithPagePermissions permissions={pluginPermissions.main}>
|
||||
<Wrapper>
|
||||
<DataManagerProvider allIcons={icons}>
|
||||
<Suspense fallback={<LoadingIndicatorPage />}>
|
||||
<Switch>
|
||||
<Route path={`/plugins/${pluginId}/content-types/:uid`} component={ListView} />
|
||||
<Route
|
||||
path={`/plugins/${pluginId}/component-categories/:categoryUid`}
|
||||
component={RecursivePath}
|
||||
/>
|
||||
</Switch>
|
||||
</Suspense>
|
||||
</DataManagerProvider>
|
||||
</Wrapper>
|
||||
</WithPagePermissions>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ import App from './containers/App';
|
||||
import Initializer from './containers/Initializer';
|
||||
import Link from './InjectedComponents/ContentManager/EditViewLink';
|
||||
import Button from './InjectedComponents/ContentManager/EditSettingViewButton';
|
||||
import pluginPermissions from './utils/permissions';
|
||||
import lifecycles from './lifecycles';
|
||||
import trads from './translations';
|
||||
import pluginId from './pluginId';
|
||||
@ -64,7 +65,7 @@ export default strapi => {
|
||||
defaultMessage: 'Content-Types Builder',
|
||||
},
|
||||
name,
|
||||
permissions: [{ action: 'plugins::content-type-builder.read', subject: null }],
|
||||
permissions: pluginPermissions.main,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
const pluginPermissions = {
|
||||
// This permission regards the main component (App) and is used to tell
|
||||
// If the plugin link should be displayed in the menu
|
||||
// And also if the plugin is accessible. This use case is found when a user types the url of the
|
||||
// plugin directly in the browser
|
||||
main: [{ action: 'plugins::content-type-builder.read', subject: null }],
|
||||
};
|
||||
|
||||
export default pluginPermissions;
|
||||
Loading…
x
Reference in New Issue
Block a user