Don't even render components if the user doesn't have permission
This commit is contained in:
parent
54f9c5f187
commit
9ae3c17913
4 changed files with 43 additions and 14 deletions
|
@ -52,8 +52,8 @@ export default ({ title, image, message, onBack, onRetry }: Props) => (
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<img src={image} css={tw`w-2/3 h-auto select-none`}/>
|
<img src={image} css={tw`w-2/3 h-auto select-none mx-auto`}/>
|
||||||
<h2 css={tw`mt-6 text-neutral-900 font-bold`}>{title}</h2>
|
<h2 css={tw`mt-10 text-neutral-900 font-bold text-4xl`}>{title}</h2>
|
||||||
<p css={tw`text-sm text-neutral-700 mt-2`}>
|
<p css={tw`text-sm text-neutral-700 mt-2`}>
|
||||||
{message}
|
{message}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -24,7 +24,7 @@ const Code = styled.code`${tw`font-mono py-1 px-2 bg-neutral-900 rounded text-sm
|
||||||
const Label = styled.label`${tw`uppercase text-xs mt-1 text-neutral-400 block px-1 select-none transition-colors duration-150`}`;
|
const Label = styled.label`${tw`uppercase text-xs mt-1 text-neutral-400 block px-1 select-none transition-colors duration-150`}`;
|
||||||
|
|
||||||
const NetworkContainer = () => {
|
const NetworkContainer = () => {
|
||||||
const { uuid, allocations, name: serverName } = useServer();
|
const { uuid, allocations } = useServer();
|
||||||
const { clearFlashes, clearAndAddHttpError } = useFlash();
|
const { clearFlashes, clearAndAddHttpError } = useFlash();
|
||||||
const [ loading, setLoading ] = useState<false | number>(false);
|
const [ loading, setLoading ] = useState<false | number>(false);
|
||||||
const { data, error, mutate } = useSWR<Allocation[]>(uuid, key => getServerAllocations(key), { initialData: allocations });
|
const { data, error, mutate } = useSWR<Allocation[]>(uuid, key => getServerAllocations(key), { initialData: allocations });
|
||||||
|
@ -61,10 +61,7 @@ const NetworkContainer = () => {
|
||||||
}, [ error ]);
|
}, [ error ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContentBlock showFlashKey={'server:network'}>
|
<PageContentBlock showFlashKey={'server:network'} title={'Network'}>
|
||||||
<Helmet>
|
|
||||||
<title> {serverName} | Network </title>
|
|
||||||
</Helmet>
|
|
||||||
{!data ?
|
{!data ?
|
||||||
<Spinner size={'large'} centered/>
|
<Spinner size={'large'} centered/>
|
||||||
:
|
:
|
||||||
|
|
27
resources/scripts/hoc/requireServerPermission.tsx
Normal file
27
resources/scripts/hoc/requireServerPermission.tsx
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import React from 'react';
|
||||||
|
import Can from '@/components/elements/Can';
|
||||||
|
import NotFound from '@/components/screens/NotFound';
|
||||||
|
import ScreenBlock from '@/components/screens/ScreenBlock';
|
||||||
|
|
||||||
|
const requireServerPermission = (Component: React.ComponentType<any>, permissions: string | string[]) => {
|
||||||
|
return class extends React.Component<any, any> {
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<Can
|
||||||
|
action={permissions}
|
||||||
|
renderOnError={
|
||||||
|
<ScreenBlock
|
||||||
|
image={'/assets/svgs/server_error.svg'}
|
||||||
|
title={'Access Denied'}
|
||||||
|
message={'You do not have permission to access this page.'}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Component/>
|
||||||
|
</Can>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default requireServerPermission;
|
|
@ -28,6 +28,7 @@ import SubNavigation from '@/components/elements/SubNavigation';
|
||||||
import NetworkContainer from '@/components/server/network/NetworkContainer';
|
import NetworkContainer from '@/components/server/network/NetworkContainer';
|
||||||
import InstallListener from '@/components/server/InstallListener';
|
import InstallListener from '@/components/server/InstallListener';
|
||||||
import StartupContainer from '@/components/server/startup/StartupContainer';
|
import StartupContainer from '@/components/server/startup/StartupContainer';
|
||||||
|
import requireServerPermission from '@/hoc/requireServerPermission';
|
||||||
|
|
||||||
const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>) => {
|
const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>) => {
|
||||||
const { rootAdmin } = useStoreState(state => state.user.data!);
|
const { rootAdmin } = useStoreState(state => state.user.data!);
|
||||||
|
@ -121,7 +122,11 @@ const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>)
|
||||||
<TransitionRouter>
|
<TransitionRouter>
|
||||||
<Switch location={location}>
|
<Switch location={location}>
|
||||||
<Route path={`${match.path}`} component={ServerConsole} exact/>
|
<Route path={`${match.path}`} component={ServerConsole} exact/>
|
||||||
<Route path={`${match.path}/files`} component={FileManagerContainer} exact/>
|
<Route
|
||||||
|
path={`${match.path}/files`}
|
||||||
|
component={requireServerPermission(FileManagerContainer, 'file.*')}
|
||||||
|
exact
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={`${match.path}/files/:action(edit|new)`}
|
path={`${match.path}/files/:action(edit|new)`}
|
||||||
render={props => (
|
render={props => (
|
||||||
|
@ -131,17 +136,17 @@ const ServerRouter = ({ match, location }: RouteComponentProps<{ id: string }>)
|
||||||
)}
|
)}
|
||||||
exact
|
exact
|
||||||
/>
|
/>
|
||||||
<Route path={`${match.path}/databases`} component={DatabasesContainer} exact/>
|
<Route path={`${match.path}/databases`} component={requireServerPermission(DatabasesContainer, 'database.*')} exact/>
|
||||||
<Route path={`${match.path}/schedules`} component={ScheduleContainer} exact/>
|
<Route path={`${match.path}/schedules`} component={requireServerPermission(ScheduleContainer, 'schedule.*')} exact/>
|
||||||
<Route
|
<Route
|
||||||
path={`${match.path}/schedules/:id`}
|
path={`${match.path}/schedules/:id`}
|
||||||
component={ScheduleEditContainer}
|
component={ScheduleEditContainer}
|
||||||
exact
|
exact
|
||||||
/>
|
/>
|
||||||
<Route path={`${match.path}/users`} component={UsersContainer} exact/>
|
<Route path={`${match.path}/users`} component={requireServerPermission(UsersContainer, 'user.*')} exact/>
|
||||||
<Route path={`${match.path}/backups`} component={BackupContainer} exact/>
|
<Route path={`${match.path}/backups`} component={requireServerPermission(BackupContainer, 'backup.*')} exact/>
|
||||||
<Route path={`${match.path}/network`} component={NetworkContainer} exact/>
|
<Route path={`${match.path}/network`} component={requireServerPermission(NetworkContainer, 'allocation.*')} exact/>
|
||||||
<Route path={`${match.path}/startup`} component={StartupContainer} exact/>
|
<Route path={`${match.path}/startup`} component={requireServerPermission(StartupContainer, 'startup.*')} exact/>
|
||||||
<Route path={`${match.path}/settings`} component={SettingsContainer} exact/>
|
<Route path={`${match.path}/settings`} component={SettingsContainer} exact/>
|
||||||
<Route path={'*'} component={NotFound}/>
|
<Route path={'*'} component={NotFound}/>
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
Loading…
Reference in a new issue