Merge pull request #1332 from guardicore/ransomware_tab_by_default

Sort report tabs according to scenario
This commit is contained in:
VakarisZ 2021-07-16 15:47:59 +03:00 committed by GitHub
commit c760e06f03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 80 additions and 69 deletions

View File

@ -33,7 +33,7 @@ import _ from "lodash";
let notificationIcon = require('../images/notification-logo-512x512.png'); let notificationIcon = require('../images/notification-logo-512x512.png');
const Routes = { export const Routes = {
LandingPage: '/landing-page', LandingPage: '/landing-page',
GettingStartedPage: '/', GettingStartedPage: '/',
Report: '/report', Report: '/report',
@ -178,7 +178,21 @@ class AppComponent extends AuthComponent {
clearInterval(this.interval); clearInterval(this.interval);
} }
getDefaultReport() {
if(this.state.islandMode === 'ransomware'){
return Routes.RansomwareReport
} else {
return Routes.SecurityReport
}
}
render() { render() {
let defaultSideNavProps = {completedSteps: this.state.completedSteps,
onStatusChange: this.updateStatus,
islandMode: this.state.islandMode,
defaultReport: this.getDefaultReport()}
return ( return (
<Router> <Router>
<Container fluid> <Container fluid>
@ -191,50 +205,39 @@ class AppComponent extends AuthComponent {
completedSteps={new CompletedSteps()} completedSteps={new CompletedSteps()}
onStatusChange={this.updateStatus}/>)} onStatusChange={this.updateStatus}/>)}
{this.renderRoute(Routes.GettingStartedPage, {this.renderRoute(Routes.GettingStartedPage,
<SidebarLayoutComponent component={GettingStartedPage} <SidebarLayoutComponent component={GettingStartedPage} {...defaultSideNavProps}/>,
completedSteps={this.state.completedSteps}
onStatusChange={this.updateStatus}
/>,
true)} true)}
{this.renderRoute(Routes.ConfigurePage, {this.renderRoute(Routes.ConfigurePage,
<SidebarLayoutComponent component={ConfigurePage} <SidebarLayoutComponent component={ConfigurePage} {...defaultSideNavProps}/>)}
islandMode={this.state.islandMode}
onStatusChange={this.updateStatus}
completedSteps={this.state.completedSteps}/>)}
{this.renderRoute(Routes.RunMonkeyPage, {this.renderRoute(Routes.RunMonkeyPage,
<SidebarLayoutComponent component={RunMonkeyPage} <SidebarLayoutComponent component={RunMonkeyPage} {...defaultSideNavProps}/>)}
islandMode={this.state.islandMode}
onStatusChange={this.updateStatus}
completedSteps={this.state.completedSteps}/>)}
{this.renderRoute(Routes.MapPage, {this.renderRoute(Routes.MapPage,
<SidebarLayoutComponent component={MapPage} <SidebarLayoutComponent component={MapPage} {...defaultSideNavProps}/>)}
onStatusChange={this.updateStatus}
completedSteps={this.state.completedSteps}/>)}
{this.renderRoute(Routes.TelemetryPage, {this.renderRoute(Routes.TelemetryPage,
<SidebarLayoutComponent component={TelemetryPage} <SidebarLayoutComponent component={TelemetryPage} {...defaultSideNavProps}/>)}
onStatusChange={this.updateStatus}
completedSteps={this.state.completedSteps}/>)}
{this.renderRoute(Routes.StartOverPage, {this.renderRoute(Routes.StartOverPage,
<SidebarLayoutComponent component={StartOverPage} <SidebarLayoutComponent component={StartOverPage} {...defaultSideNavProps}/>)}
onStatusChange={this.updateStatus} {this.redirectToReport()}
completedSteps={this.state.completedSteps}/>)}
{this.redirectTo(Routes.Report, Routes.SecurityReport)}
{this.renderRoute(Routes.SecurityReport, {this.renderRoute(Routes.SecurityReport,
<SidebarLayoutComponent component={ReportPage} <SidebarLayoutComponent component={ReportPage}
completedSteps={this.state.completedSteps}/>)} islandMode={this.state.islandMode}
{...defaultSideNavProps}/>)}
{this.renderRoute(Routes.AttackReport, {this.renderRoute(Routes.AttackReport,
<SidebarLayoutComponent component={ReportPage} <SidebarLayoutComponent component={ReportPage}
completedSteps={this.state.completedSteps}/>)} islandMode={this.state.islandMode}
{...defaultSideNavProps}/>)}
{this.renderRoute(Routes.ZeroTrustReport, {this.renderRoute(Routes.ZeroTrustReport,
<SidebarLayoutComponent component={ReportPage} <SidebarLayoutComponent component={ReportPage}
completedSteps={this.state.completedSteps}/>)} islandMode={this.state.islandMode}
{...defaultSideNavProps}/>)}
{this.renderRoute(Routes.RansomwareReport, {this.renderRoute(Routes.RansomwareReport,
<SidebarLayoutComponent component={ReportPage} <SidebarLayoutComponent component={ReportPage}
completedSteps={this.state.completedSteps}/>)} islandMode={this.state.islandMode}
{...defaultSideNavProps}/>)}
{this.renderRoute(Routes.LicensePage, {this.renderRoute(Routes.LicensePage,
<SidebarLayoutComponent component={LicensePage} <SidebarLayoutComponent component={LicensePage}
onStatusChange={this.updateStatus} islandMode={this.state.islandMode}
completedSteps={this.state.completedSteps}/>)} {...defaultSideNavProps}/>)}
<Route component={NotFoundPage}/> <Route component={NotFoundPage}/>
</Switch> </Switch>
</Container> </Container>
@ -242,6 +245,14 @@ class AppComponent extends AuthComponent {
); );
} }
redirectToReport() {
if (this.state.islandMode === 'ransomware') {
return this.redirectTo(Routes.Report, Routes.RansomwareReport)
} else {
return this.redirectTo(Routes.Report, Routes.SecurityReport)
}
}
showInfectionDoneNotification() { showInfectionDoneNotification() {
if (this.shouldShowNotification()) { if (this.shouldShowNotification()) {
const hostname = window.location.hostname; const hostname = window.location.hostname;

View File

@ -7,7 +7,7 @@ import {faExternalLinkAlt} from '@fortawesome/free-solid-svg-icons';
import VersionComponent from './side-menu/VersionComponent'; import VersionComponent from './side-menu/VersionComponent';
import '../styles/components/SideNav.scss'; import '../styles/components/SideNav.scss';
import {CompletedSteps} from "./side-menu/CompletedSteps"; import {CompletedSteps} from "./side-menu/CompletedSteps";
import {isReportRoute} from "./Main"; import {isReportRoute, Routes} from "./Main";
const guardicoreLogoImage = require('../images/guardicore-logo.png'); const guardicoreLogoImage = require('../images/guardicore-logo.png');
@ -17,15 +17,16 @@ const infectionMonkeyImage = require('../images/infection-monkey.svg');
type Props = { type Props = {
disabled?: boolean, disabled?: boolean,
completedSteps: CompletedSteps completedSteps: CompletedSteps,
defaultReport: string
} }
const SideNavComponent = ({disabled=false, completedSteps}: Props) => { const SideNavComponent = ({disabled, completedSteps, defaultReport}: Props) => {
return ( return (
<> <>
<NavLink to={'/'} exact={true}> <NavLink to={Routes.GettingStartedPage} exact={true}>
<div className='header'> <div className='header'>
<img alt='logo' src={logoImage} style={{width: '5vw', margin: '15px'}}/> <img alt='logo' src={logoImage} style={{width: '5vw', margin: '15px'}}/>
<img src={infectionMonkeyImage} style={{width: '15vw'}} alt='Infection Monkey'/> <img src={infectionMonkeyImage} style={{width: '15vw'}} alt='Infection Monkey'/>
@ -34,7 +35,7 @@ const SideNavComponent = ({disabled=false, completedSteps}: Props) => {
<ul className='navigation'> <ul className='navigation'>
<li> <li>
<NavLink to='/run-monkey' className={getNavLinkClass()}> <NavLink to={Routes.RunMonkeyPage} className={getNavLinkClass()}>
<span className='number'>1.</span> <span className='number'>1.</span>
Run Monkey Run Monkey
{completedSteps.runMonkey ? {completedSteps.runMonkey ?
@ -43,7 +44,7 @@ const SideNavComponent = ({disabled=false, completedSteps}: Props) => {
</NavLink> </NavLink>
</li> </li>
<li> <li>
<NavLink to='/infection/map' className={getNavLinkClass()}> <NavLink to={Routes.MapPage} className={getNavLinkClass()}>
<span className='number'>2.</span> <span className='number'>2.</span>
Infection Map Infection Map
{completedSteps.infectionDone ? {completedSteps.infectionDone ?
@ -52,7 +53,7 @@ const SideNavComponent = ({disabled=false, completedSteps}: Props) => {
</NavLink> </NavLink>
</li> </li>
<li> <li>
<NavLink to='/report/security' <NavLink to={defaultReport}
className={getNavLinkClass()} className={getNavLinkClass()}
isActive={(_match, location) => { isActive={(_match, location) => {
return (isReportRoute(location.pathname)) return (isReportRoute(location.pathname))
@ -65,7 +66,7 @@ const SideNavComponent = ({disabled=false, completedSteps}: Props) => {
</NavLink> </NavLink>
</li> </li>
<li> <li>
<NavLink to='/start-over' className={getNavLinkClass()}> <NavLink to={Routes.StartOverPage} className={getNavLinkClass()}>
<span className='number'><FontAwesomeIcon icon={faUndo} style={{'marginLeft': '-1px'}}/></span> <span className='number'><FontAwesomeIcon icon={faUndo} style={{'marginLeft': '-1px'}}/></span>
Start Over Start Over
</NavLink> </NavLink>
@ -74,7 +75,7 @@ const SideNavComponent = ({disabled=false, completedSteps}: Props) => {
<hr/> <hr/>
<ul> <ul>
<li><NavLink to='/configure' <li><NavLink to={Routes.ConfigurePage}
className={getNavLinkClass()}> className={getNavLinkClass()}>
Configuration Configuration
</NavLink></li> </NavLink></li>
@ -96,7 +97,7 @@ const SideNavComponent = ({disabled=false, completedSteps}: Props) => {
<FontAwesomeIcon icon={faExternalLinkAlt} /> Documentation <FontAwesomeIcon icon={faExternalLinkAlt} /> Documentation
</a> </a>
<br/> <br/>
<NavLink to='/license'>License</NavLink> <NavLink to={Routes.LicensePage}>License</NavLink>
</div> </div>
<VersionComponent/> <VersionComponent/>
</>); </>);

View File

@ -6,13 +6,16 @@ import {Col, Row} from 'react-bootstrap';
const SidebarLayoutComponent = ({component: Component, const SidebarLayoutComponent = ({component: Component,
sideNavDisabled = false, sideNavDisabled = false,
completedSteps = null, completedSteps = null,
defaultReport = '',
...other ...other
}) => ( }) => (
<Route {...other} render={() => { <Route {...other} render={() => {
return ( return (
<Row> <Row>
<Col sm={3} md={3} lg={3} xl={2} className='sidebar'> <Col sm={3} md={3} lg={3} xl={2} className='sidebar'>
<SideNavComponent disabled={sideNavDisabled} completedSteps={completedSteps}/> <SideNavComponent disabled={sideNavDisabled}
completedSteps={completedSteps}
defaultReport={defaultReport}/>
</Col> </Col>
<Component {...other} /> <Component {...other} />
</Row>) </Row>)

View File

@ -16,6 +16,7 @@ class ReportPageComponent extends AuthComponent {
constructor(props) { constructor(props) {
super(props); super(props);
this.sections = ['security', 'zeroTrust', 'attack', 'ransomware']; this.sections = ['security', 'zeroTrust', 'attack', 'ransomware'];
this.state = { this.state = {
securityReport: {}, securityReport: {},
attackReport: {}, attackReport: {},
@ -28,6 +29,7 @@ class ReportPageComponent extends AuthComponent {
{key: 'zeroTrust', title: 'Zero trust report'}, {key: 'zeroTrust', title: 'Zero trust report'},
{key: 'attack', title: 'ATT&CK report'}] {key: 'attack', title: 'ATT&CK report'}]
}; };
} }
static selectReport(reports) { static selectReport(reports) {
@ -65,9 +67,6 @@ class ReportPageComponent extends AuthComponent {
ransomwareReport: res ransomwareReport: res
}); });
}); });
if (this.shouldShowRansomwareReport(this.state.ransomwareReport)) {
this.addRansomwareReportTab();
}
} }
} }
@ -96,32 +95,6 @@ class ReportPageComponent extends AuthComponent {
return ztReport return ztReport
}; };
shouldShowRansomwareReport(report) { // TODO: Add proper check
if (report) {
return true;
}
}
addRansomwareReportTab() { // TODO: Fetch mode from API endpoint
let ransomwareTab = {key: 'ransomware', title: 'Ransomware report'};
// let mode = "";
// this.authFetch('/api/mode')
// .then(res => res.json())
// .then(res => {
// mode = res.mode
// }
// );
let mode = 'ransomware';
if (mode === 'ransomware') {
this.state.orderedSections.splice(0, 0, ransomwareTab);
}
else {
this.state.orderedSections.push(ransomwareTab);
}
}
componentWillUnmount() { componentWillUnmount() {
clearInterval(this.state.ztReportRefreshInterval); clearInterval(this.state.ztReportRefreshInterval);
} }
@ -187,9 +160,32 @@ class ReportPageComponent extends AuthComponent {
} }
} }
addRansomwareTab() {
let ransomwareTab = {key: 'ransomware', title: 'Ransomware report'};
if(this.isRansomwareTabMissing(ransomwareTab)){
if (this.props.islandMode === 'ransomware') {
this.state.orderedSections.splice(0, 0, ransomwareTab);
}
else {
this.state.orderedSections.push(ransomwareTab);
}
}
}
isRansomwareTabMissing(ransomwareTab) {
return (
this.props.islandMode !== undefined &&
!this.state.orderedSections.some(tab =>
(tab.key === ransomwareTab.key
&& tab.title === ransomwareTab.title)
));
}
render() { render() {
let content; let content;
this.addRansomwareTab();
if (this.state.runStarted) { if (this.state.runStarted) {
content = this.getReportContent(); content = this.getReportContent();
} else { } else {