Don't even render components if the user doesn't have permission

This commit is contained in:
Dane Everitt 2020-08-22 19:01:29 -07:00
parent 54f9c5f187
commit 9ae3c17913
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
4 changed files with 43 additions and 14 deletions

View file

@ -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>

View file

@ -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/>
: :

View 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;

View file

@ -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>