From de835a4fd3a05021a48aac3a15c557e5680347b9 Mon Sep 17 00:00:00 2001 From: Imre Toth <imre.toth@ess.eu> Date: Tue, 22 Feb 2022 11:52:45 +0000 Subject: [PATCH] Icshwi 8500 access level refinement --- .../deployments/browse-deployments.feature | 4 +- src/App.js | 4 +- src/__tests__/browse-deployments-test.js | 10 +-- src/components/IOC/IOCDetails.js | 7 +- src/components/IOC/IOCLiveStatus.js | 27 ++++--- src/components/IOC/IOCManage.js | 28 ++++--- src/components/IOC/IOCService.js | 80 ++++++++++--------- .../deployments/DeploymentDetails.js | 26 +++--- .../navigation/GlobalAppBar/GlobalAppBar.js | 1 + src/views/IOC/IOCDetailsAccessControl.js | 2 +- .../DeploymentDetailsAccessControl.js | 2 +- .../deployments/DeploymentsAccessControl.js | 2 +- src/views/deployments/DeploymentsView.js | 13 ++- src/views/host/HostDetailsAccessControl.js | 2 +- src/views/host/HostDetailsView.js | 25 +++--- 15 files changed, 134 insertions(+), 99 deletions(-) diff --git a/features/deployments/browse-deployments.feature b/features/deployments/browse-deployments.feature index fe8a46aa..a8ef8ba3 100644 --- a/features/deployments/browse-deployments.feature +++ b/features/deployments/browse-deployments.feature @@ -2,7 +2,7 @@ Feature: Browse IOC Deployments Scenario: User wants to browse IOC deployments Given the user is not logged in and navigates to the deployments page - Then they should get Access deniend + Then they should not get Access deniend # Scenario: Logged in user wants to browse IOC deployments # Given the user is logged in @@ -22,7 +22,7 @@ Feature: Browse IOC Deployments Scenario: User wants to navigate to a specific IOC deployment Given the user is not logged in and tries to navigate any deployment details page - Then they should get Access deniend + Then they should not get Access deniend # Scenario: Logged in user wants to navigate to a specific IOC deployment # Given the user is on the deployments page diff --git a/src/App.js b/src/App.js index 3dc71300..3178b9b9 100644 --- a/src/App.js +++ b/src/App.js @@ -13,8 +13,8 @@ import { IOCListView } from './views/IOC/IOCListView'; import { HomeAccessControl } from './views/home/HomeAccessControl'; import { GlobalAppBar } from './components/navigation/GlobalAppBar/GlobalAppBar'; import { IOCDetailsAccessControl } from './views/IOC/IOCDetailsAccessControl'; -import { DeploymentsAccessControl } from './views/deployments/DeploymentsAccessControl' -import { DeploymentDetailsAccessControl } from './views/deployments/DeploymentDetailsAccessControl' +import { DeploymentsAccessControl } from './views/deployments/DeploymentsAccessControl'; +import { DeploymentDetailsAccessControl } from './views/deployments/DeploymentDetailsAccessControl'; import { APIProvider, UserProvider } from './api/SwaggerApi'; import { HostListView } from "./views/host/HostListView"; import { HostDetailsAccessControl } from "./views/host/HostDetailsAccessControl"; diff --git a/src/__tests__/browse-deployments-test.js b/src/__tests__/browse-deployments-test.js index 3aef6a61..e319273d 100644 --- a/src/__tests__/browse-deployments-test.js +++ b/src/__tests__/browse-deployments-test.js @@ -21,11 +21,11 @@ defineFeature(feature, (test) => { <App /> </Router> ) - await screen.findByText(/deployment log/i); + await screen.findByText(/Running/i); }); - then('they should get Access deniend', async () => { - expect(await screen.findByText(/access denied/i)).toBeInTheDocument(); + then('they should not get Access deniend', async () => { + expect(await screen.findByText(/IOC Name/i)).toBeInTheDocument(); }); }); @@ -59,8 +59,8 @@ defineFeature(feature, (test) => { await screen.findByText(/deployment details/i); }); - then('they should get Access deniend', async () => { - expect(await screen.findByText(/access denied/i)).toBeInTheDocument() + then('they should not get Access deniend', async () => { + expect(await screen.findByText(/Running Undeployment/i)).toBeInTheDocument() }); }); diff --git a/src/components/IOC/IOCDetails.js b/src/components/IOC/IOCDetails.js index 40ebccce..1a536d3c 100644 --- a/src/components/IOC/IOCDetails.js +++ b/src/components/IOC/IOCDetails.js @@ -3,6 +3,7 @@ import React from "react"; import { SimpleAccordion } from "../common/Accordion/SimpleAccordion"; import { KeyValueTable } from "../common/KeyValueTable/KeyValueTable"; import { IOCBadge } from "./IOCBadge"; +import AccessControl from "../auth/AccessControl"; export function diff(o1, o2) { let diff = Object.keys(o2).reduce((diff, key) => { @@ -29,7 +30,11 @@ export function IOCDetails({ ioc, getSubset=defaultSubset, alert, buttons }) { </Grid>} <Grid item xs={12}> <Box display="flex" flexDirection="row-reverse" p={2} m={1}> - {buttons} + <AccessControl + allowedRoles={["DeploymentToolAdmin, DeploymentToolIntegrator"]} + renderNoAccess={() =><></>}> + {buttons} + </AccessControl> </Box> </Grid> <Grid item xs={12}> diff --git a/src/components/IOC/IOCLiveStatus.js b/src/components/IOC/IOCLiveStatus.js index 7af6472f..d775b35e 100644 --- a/src/components/IOC/IOCLiveStatus.js +++ b/src/components/IOC/IOCLiveStatus.js @@ -9,7 +9,7 @@ import GitRefLink from "./GitRefLink"; import IOCAlerts from "./IOCAlerts"; import { IOCService } from "./IOCService"; import { IOCCommandTable } from "./IOCCommandTable"; - +import AccessControl from '../../components/auth/AccessControl'; export function IOCLiveStatus({ ioc, currentCommand, commands, getCommands, buttonDisabled, setButtonDisabled, setOperationQueued, commandLazyParams, setCommandLazyParams, commandColumnSort, setCommandColumnSort, rowsPerPage}) { @@ -47,19 +47,22 @@ export function IOCLiveStatus({ ioc, currentCommand, commands, getCommands, butt return ( <> - <IOCDetails ioc={liveIOC} getSubset={getSubset} alert={<IOCAlerts ioc={liveIOC}/>}/> + <IOCDetails ioc={liveIOC} getSubset={getSubset} alert={<IOCAlerts ioc={liveIOC} />} /> <SimpleAccordion summary="IOC Service Control log"> - <IOCCommandTable commands={commands} - commandLazyParams={commandLazyParams} setCommandLazyParams={setCommandLazyParams} commandColumnSort={commandColumnSort} setCommandColumnSort={setCommandColumnSort} - rowsPerPage={rowsPerPage} /> - </SimpleAccordion> - <SimpleAccordion summary="ProcServLog info" defaultExpanded> - {liveIOC.activeDeployment?.host.csEntryId ? - <LokiContainer csEntryId={liveIOC.activeDeployment?.host.csEntryId} iocName={ioc.namingName} isDeployed={isIocDeployed(ioc)} /> - : - <Alert severity="error" variant="standard">Invalid CSentry ID for target host</Alert> - } + <IOCCommandTable commands={commands} + commandLazyParams={commandLazyParams} setCommandLazyParams={setCommandLazyParams} commandColumnSort={commandColumnSort} setCommandColumnSort={setCommandColumnSort} + rowsPerPage={rowsPerPage} /> </SimpleAccordion> + <AccessControl allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]} + renderNoAccess={() => <></>}> + <SimpleAccordion summary="ProcServLog info" defaultExpanded> + {liveIOC.activeDeployment?.host.csEntryId ? + <LokiContainer csEntryId={liveIOC.activeDeployment?.host.csEntryId} iocName={ioc.namingName} isDeployed={isIocDeployed(ioc)} /> + : + <Alert severity="error" variant="standard">Invalid CSentry ID for target host</Alert> + } + </SimpleAccordion> + </AccessControl> </> ); } diff --git a/src/components/IOC/IOCManage.js b/src/components/IOC/IOCManage.js index c564615c..2e931a46 100644 --- a/src/components/IOC/IOCManage.js +++ b/src/components/IOC/IOCManage.js @@ -11,6 +11,7 @@ import { Link } from 'react-router-dom'; import { DeploymentsTable } from "../../components/deployments/DeploymentsTable"; import { SimpleAccordion } from "../common/Accordion/SimpleAccordion"; import { initRequestParams } from "../common/Helper"; +import AccessControl from "../auth/AccessControl"; export function IOCManage({ ioc, getIOC, buttonDisabled }) { const [deployDialogOpen, setDeployDialogOpen] = useState(false); @@ -155,18 +156,21 @@ export function IOCManage({ ioc, getIOC, buttonDisabled }) { </> } /> - <SimpleAccordion summary="Deployment log"> - <DeploymentsTable deployments={deployments.deploymentList} totalCount={deployments.totalCount} - lazyParams={lazyParams} setLazyParams={setLazyParams} columnSort={columnSort} setColumnSort={setColumnSort} - rowsPerPage={rowsPerPage} /> - </SimpleAccordion> - <SimpleModal open={deployDialogOpen} setOpen={setDeployDialogOpen}> - <DeployIOC open={deployDialogOpen} setOpen={setDeployDialogOpen} submitCallback={closeDeployModal} init={formInit} hook={useUpdateAndDeployIoc.bind(null, ioc.id)} - hasActiveDeployment={ioc.activeDeployment} /> - </SimpleModal> - <SimpleModal open={undeployDialogOpen} setOpen={setUndeployDialogOpen}> - <UndeployIOC open={undeployDialogOpen} setOpen={setUndeployDialogOpen} submitCallback={closeUndeployModal} ioc={ioc} hook={useCreateUndeployment.bind(null, ioc.id)} /> - </SimpleModal> + <AccessControl allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]} + renderNoAccess={() => <></>}> + <SimpleAccordion summary="Deployment log"> + <DeploymentsTable deployments={deployments.deploymentList} totalCount={deployments.totalCount} + lazyParams={lazyParams} setLazyParams={setLazyParams} columnSort={columnSort} setColumnSort={setColumnSort} + rowsPerPage={rowsPerPage} /> + </SimpleAccordion> + <SimpleModal open={deployDialogOpen} setOpen={setDeployDialogOpen}> + <DeployIOC open={deployDialogOpen} setOpen={setDeployDialogOpen} submitCallback={closeDeployModal} init={formInit} hook={useUpdateAndDeployIoc.bind(null, ioc.id)} + hasActiveDeployment={ioc.activeDeployment} /> + </SimpleModal> + <SimpleModal open={undeployDialogOpen} setOpen={setUndeployDialogOpen}> + <UndeployIOC open={undeployDialogOpen} setOpen={setUndeployDialogOpen} submitCallback={closeUndeployModal} ioc={ioc} hook={useCreateUndeployment.bind(null, ioc.id)} /> + </SimpleModal> + </AccessControl> </> ); } diff --git a/src/components/IOC/IOCService.js b/src/components/IOC/IOCService.js index de5aec56..734acaf4 100644 --- a/src/components/IOC/IOCService.js +++ b/src/components/IOC/IOCService.js @@ -9,6 +9,7 @@ import { notificationContext } from "../../components/common/notification/Notifi import { Alert } from "@material-ui/lab"; import { theme } from "../../style/Theme"; import { initRequestParams } from "../common/Helper"; +import AccessControl from "../auth/AccessControl"; const useStyles = makeStyles({ startButton: { @@ -152,45 +153,50 @@ export function IOCService({ ioc, currentCommand, getCommands, buttonDisabled, s return ( <> - <SimpleModal open={adHocDialogOpen} setOpen={setAdHocDialogOpen}> - <ConfirmationDialog open={adHocDialogOpen} setOpen={setAdHocDialogOpen} title={adHocDialogTitle} description={adHocDialogDescription} callback={callbackRef.current} /> - </SimpleModal> - - <Grid container spacing={1}> - {ioc.active === true ? - <Grid item xs={1} md={1}> - <Tooltip title={disabledStopButtonTitle}> - <span> - <Button className={classes.stopButton} onClick={openStopModal} disabled={buttonDisabled || ioc.operationInProgress}>Stop</Button> - </span> - </Tooltip> - </Grid> - : - <></> - } - {ioc.active === false ? - <Grid item xs={1} md={1}> - <Tooltip title={disabledStartButtonTitle}> - <span> - <Button className={classes.startButton} onClick={openStartModal} disabled={buttonDisabled || ioc.operationInProgress}>Start</Button> - </span> - </Tooltip> - </Grid> - : - <></> - } - <Grid item xs={12} md={12}> - {error ? - <Alert severity="error">{error}</Alert> - : - <> - {command ? - <CommandJobStatus awxCommandId={command.awxCommandId} actionType={action} /> : inProgress ? <LinearProgress color="primary" /> : <></> + <AccessControl + allowedRoles={["DeploymentToolAdmin"]} + allowedUsersWithRoles={[{ user: ioc.owner, role: "DeploymentToolIntegrator" }]} + renderNoAccess={() => <></>}> + <SimpleModal open={adHocDialogOpen} setOpen={setAdHocDialogOpen}> + <ConfirmationDialog open={adHocDialogOpen} setOpen={setAdHocDialogOpen} title={adHocDialogTitle} description={adHocDialogDescription} callback={callbackRef.current} /> + </SimpleModal> + + <Grid container spacing={1}> + {ioc.active === true ? + <Grid item xs={1} md={1}> + <Tooltip title={disabledStopButtonTitle}> + <span> + <Button className={classes.stopButton} onClick={openStopModal} disabled={buttonDisabled || ioc.operationInProgress}>Stop</Button> + </span> + </Tooltip> + </Grid> + : + <></> + } + {ioc.active === false ? + <Grid item xs={1} md={1}> + <Tooltip title={disabledStartButtonTitle}> + <span> + <Button className={classes.startButton} onClick={openStartModal} disabled={buttonDisabled || ioc.operationInProgress}>Start</Button> + </span> + </Tooltip> + </Grid> + : + <></> + } + <Grid item xs={12} md={12}> + {error ? + <Alert severity="error">{error}</Alert> + : + <> + {command ? + <CommandJobStatus awxCommandId={command.awxCommandId} actionType={action} /> : inProgress ? <LinearProgress color="primary" /> : <></> + } + </> } - </> - } + </Grid> </Grid> - </Grid> + </AccessControl> </> ) } diff --git a/src/components/deployments/DeploymentDetails.js b/src/components/deployments/DeploymentDetails.js index 577cc86b..09dde3e1 100644 --- a/src/components/deployments/DeploymentDetails.js +++ b/src/components/deployments/DeploymentDetails.js @@ -10,6 +10,7 @@ import { Alert } from '@material-ui/lab'; import { Link } from 'react-router-dom'; import { formatDate } from '../common/Helper'; import GitRefLink from '../IOC/GitRefLink'; +import AccessControl from '../auth/AccessControl'; const useStyles = makeStyles({ root: { @@ -85,17 +86,20 @@ export function DeploymentDetails({ deployment, getDeployment }) { {alert && <Grid item xs={12}> {alert} </Grid>} - <Grid item xs={12} md={12} style={{paddingBottom: 0}}> - { deployment.awxJobId ? - <SimpleAccordion summary="Ansible Job Output" defaultExpanded> - <Container> - <DeploymentJobOutput awxJobId={deployment.awxJobId} update={updateOutput} /> - </Container> - </SimpleAccordion> - : - <></> - } - </Grid> + <AccessControl allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]} + renderNoAccess={() => <></>}> + <Grid item xs={12} md={12} style={{ paddingBottom: 0 }}> + {deployment.awxJobId ? + <SimpleAccordion summary="Ansible Job Output" defaultExpanded> + <Container> + <DeploymentJobOutput awxJobId={deployment.awxJobId} update={updateOutput} /> + </Container> + </SimpleAccordion> + : + <></> + } + </Grid> + </AccessControl> </Grid> ); } diff --git a/src/components/navigation/GlobalAppBar/GlobalAppBar.js b/src/components/navigation/GlobalAppBar/GlobalAppBar.js index 78cc0d9b..f72f0fd3 100644 --- a/src/components/navigation/GlobalAppBar/GlobalAppBar.js +++ b/src/components/navigation/GlobalAppBar/GlobalAppBar.js @@ -397,6 +397,7 @@ export function GlobalAppBar({ children }) { const menuItemsVisitor = [ makeLink("Explore IOCs", "/iocs", <CCCEControlSymbol />), makeLink("Explore IOC hosts", "/hosts", <Storage />), + makeLink("Deployment log", "/deployments", <Assignment />), makeLink("Statistics", "/statistics", <TrendingUp />), makeLink("About", "/about", <InfoIcon />) ] diff --git a/src/views/IOC/IOCDetailsAccessControl.js b/src/views/IOC/IOCDetailsAccessControl.js index 2c035c46..29d80d6c 100644 --- a/src/views/IOC/IOCDetailsAccessControl.js +++ b/src/views/IOC/IOCDetailsAccessControl.js @@ -12,7 +12,7 @@ export function IOCDetailsAccessControl({ match }) { return ( <RootContainer> - <AccessControl allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]}> + <AccessControl allowedRoles={[]}> <IOCDetailsContainer id={id} /> </AccessControl> </RootContainer> diff --git a/src/views/deployments/DeploymentDetailsAccessControl.js b/src/views/deployments/DeploymentDetailsAccessControl.js index 604ced75..062f1e45 100644 --- a/src/views/deployments/DeploymentDetailsAccessControl.js +++ b/src/views/deployments/DeploymentDetailsAccessControl.js @@ -10,7 +10,7 @@ export function DeploymentDetailsAccessControl({ match }) { return ( <RootContainer> - <AccessControl allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]}> + <AccessControl allowedRoles={[]}> <DeploymentDetailsView id={id}/> </AccessControl> </RootContainer> diff --git a/src/views/deployments/DeploymentsAccessControl.js b/src/views/deployments/DeploymentsAccessControl.js index 17d3a9a7..dd1e9bb6 100644 --- a/src/views/deployments/DeploymentsAccessControl.js +++ b/src/views/deployments/DeploymentsAccessControl.js @@ -9,7 +9,7 @@ export function DeploymentsAccessControl() { return ( <RootContainer> - <AccessControl allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]}> + <AccessControl allowedRoles={[]}> <DeploymentsView/> </AccessControl> </RootContainer> diff --git a/src/views/deployments/DeploymentsView.js b/src/views/deployments/DeploymentsView.js index 91ebaa7b..25b33cd0 100644 --- a/src/views/deployments/DeploymentsView.js +++ b/src/views/deployments/DeploymentsView.js @@ -9,6 +9,7 @@ import { useDeploymentSearch, userContext } from '../../api/SwaggerApi'; import { initRequestParams } from '../../components/common/Helper'; import { useEffect } from 'react'; import { SearchBar } from '../../components/common/SearchBar/SearchBar'; +import AccessControl from '../../components/auth/AccessControl'; const useStyles = makeStyles((theme) => ({ root: { @@ -130,10 +131,14 @@ export function DeploymentsView() { </Tabs> </Grid> <Grid item xs={8} md={2}> - <FormControlLabel className={classes.formControl} - control={<Switch checked={ownOnly} onChange={handleChangeOwn} />} - label={<Typography variant="h5">My deployments</Typography>} - /> + <AccessControl allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]} + renderNoAccess={() => <></>} > + + <FormControlLabel className={classes.formControl} + control={<Switch checked={ownOnly} onChange={handleChangeOwn} />} + label={<Typography variant="h5">My deployments</Typography>} + /> + </AccessControl> </Grid> <Grid item xs={12} md={12}> {content} diff --git a/src/views/host/HostDetailsAccessControl.js b/src/views/host/HostDetailsAccessControl.js index d25c1500..ae00c37f 100644 --- a/src/views/host/HostDetailsAccessControl.js +++ b/src/views/host/HostDetailsAccessControl.js @@ -10,7 +10,7 @@ export function HostDetailsAccessControl({ match }) { return ( <RootContainer data-testid="host-details-container"> - <AccessControl allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]}> + <AccessControl allowedRoles={[]}> <HostDetailsView id={id}/> </AccessControl> </RootContainer> diff --git a/src/views/host/HostDetailsView.js b/src/views/host/HostDetailsView.js index 3ab8f4ba..8715f97e 100644 --- a/src/views/host/HostDetailsView.js +++ b/src/views/host/HostDetailsView.js @@ -20,6 +20,7 @@ import { KeyValueTable } from '../../components/common/KeyValueTable/KeyValueTab import { LokiPanel } from '../../components/common/Loki/LokiPanel'; import { useHistory } from "react-router-dom"; import { formatDate, initRequestParams } from '../../components/common/Helper'; +import AccessControl from '../../components/auth/AccessControl'; const useStyles = makeStyles((theme) => ({ secondItem: { @@ -86,12 +87,15 @@ export function HostDetailsView({ id }) { rowsPerPage={rowsPerPage}/> </Hidden> </SimpleAccordion> - <SimpleAccordion summary="Syslog info" defaultExpanded> - {host && - <Container> - <LokiPanel host={host} isSyslog={true} isDeployed={true} /> - </Container>} - </SimpleAccordion> + <AccessControl allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]} + renderNoAccess={() => <></>}> + <SimpleAccordion summary="Syslog info" defaultExpanded> + {host && + <Container> + <LokiPanel host={host} isSyslog={true} isDeployed={true} /> + </Container>} + </SimpleAccordion> + </AccessControl> <Card variant="outlined"> <CardContent> <Container> @@ -107,10 +111,13 @@ export function HostDetailsView({ id }) { </Container> </CardContent> </Card> - <SimpleAccordion summary="CSEntry Configuration"> + <AccessControl allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]} + renderNoAccess={() => <></>} > + <SimpleAccordion summary="CSEntry Configuration"> - {host && <KeyValueTable obj={renderHost} variant="table" />} - </SimpleAccordion> + {host && <KeyValueTable obj={renderHost} variant="table" />} + </SimpleAccordion> + </AccessControl> </Paper> ); } \ No newline at end of file -- GitLab