Separated findings per status

This commit is contained in:
Shay Nehmad 2019-08-28 14:10:30 +03:00
parent dfebf5e841
commit a4a9f0c491
6 changed files with 70 additions and 32 deletions

View File

@ -3,7 +3,7 @@ import {Col, Grid, Row} from 'react-bootstrap';
import AuthComponent from '../AuthComponent'; import AuthComponent from '../AuthComponent';
import ReportHeader, {ReportTypes} from "../report-components/common/ReportHeader"; import ReportHeader, {ReportTypes} from "../report-components/common/ReportHeader";
import PillarsOverview from "../report-components/zerotrust/PillarOverview"; import PillarsOverview from "../report-components/zerotrust/PillarOverview";
import FindingsTable from "../report-components/zerotrust/FindingsTable"; import FindingsSection from "../report-components/zerotrust/FindingsSection";
import SinglePillarRecommendationsStatus from "../report-components/zerotrust/SinglePillarRecommendationsStatus"; import SinglePillarRecommendationsStatus from "../report-components/zerotrust/SinglePillarRecommendationsStatus";
import MonkeysStillAliveWarning from "../report-components/common/MonkeysStillAliveWarning"; import MonkeysStillAliveWarning from "../report-components/common/MonkeysStillAliveWarning";
import ReportLoader from "../report-components/common/ReportLoader"; import ReportLoader from "../report-components/common/ReportLoader";
@ -99,7 +99,7 @@ class ZeroTrustReportPageComponent extends AuthComponent {
happened in your network. This will enable you to match up with your SOC logs and alerts and to gain deeper happened in your network. This will enable you to match up with your SOC logs and alerts and to gain deeper
insight as to what exactly happened during this test. insight as to what exactly happened during this test.
</p> </p>
<FindingsTable pillarsToStatuses={this.state.pillars.pillarsToStatuses} findings={this.state.findings}/> <FindingsSection pillarsToStatuses={this.state.pillars.pillarsToStatuses} findings={this.state.findings}/>
</div>); </div>);
} }

View File

@ -26,7 +26,7 @@ export default class EventsAndButtonComponent extends Component {
<div> <div>
<EventsModal events={this.props.events} showEvents={this.state.isShow} hideCallback={this.hide} exportFilename={this.props.exportFilename} /> <EventsModal events={this.props.events} showEvents={this.state.isShow} hideCallback={this.hide} exportFilename={this.props.exportFilename} />
<div className="text-center" style={{"display": "grid"}}> <div className="text-center" style={{"display": "grid"}}>
<Button className="btn btn-info btn-lg" onClick={this.show}> <Button className="btn btn-info" onClick={this.show}>
Show Events Show Events
</Button> </Button>
<ExportEventsButton onClick={() => { <ExportEventsButton onClick={() => {

View File

@ -4,7 +4,7 @@ import * as PropTypes from "prop-types";
export default class ExportEventsButton extends Component { export default class ExportEventsButton extends Component {
render() { render() {
return <Button className="btn btn-primary btn-lg" return <Button className="btn btn-primary"
onClick={this.props.onClick} onClick={this.props.onClick}
> >
Export Events Export Events

View File

@ -0,0 +1,38 @@
import React, {Component, Fragment} from "react";
import PillarLabel from "./PillarLabel";
import EventsAndButtonComponent from "./EventsAndButtonComponent";
import {ZeroTrustStatuses} from "./ZeroTrustPillars";
import {FindingsTable} from "./FindingsTable";
class FindingsSection extends Component {
render() {
return (
<Fragment>
<FindingsTable data={this.getFilteredFindings(ZeroTrustStatuses.failed)} status={ZeroTrustStatuses.failed}/>
<FindingsTable data={this.getFilteredFindings(ZeroTrustStatuses.inconclusive)} status={ZeroTrustStatuses.inconclusive}/>
<FindingsTable data={this.getFilteredFindings(ZeroTrustStatuses.passed)} status={ZeroTrustStatuses.passed}/>
</Fragment>
);
}
getFilteredFindings(statusToFilter) {
const findings = this.props.findings.map((finding) => {
// Deep copy
const newFinding = JSON.parse(JSON.stringify(finding));
if (newFinding.status === statusToFilter) {
newFinding.pillars = newFinding.pillars.map((pillar) => {
return {name: pillar, status: this.props.pillarsToStatuses[pillar]}
});
return newFinding;
}
});
// Filter nulls out of the list
return findings.filter(function (el) {
return el != null;
});
}
}
export default FindingsSection;

View File

@ -1,13 +1,28 @@
import React, {Component, Fragment} from "react"; import React, {Component, Fragment} from "react";
import PillarLabel from "./PillarLabel"; import StatusLabel from "./StatusLabel";
import PaginatedTable from "../common/PaginatedTable"; import PaginatedTable from "../common/PaginatedTable";
import * as PropTypes from "prop-types";
import PillarLabel from "./PillarLabel";
import EventsAndButtonComponent from "./EventsAndButtonComponent"; import EventsAndButtonComponent from "./EventsAndButtonComponent";
const columns = [ const columns = [
{ {
columns: [ columns: [
{ Header: 'Pillars', id: "pillars", {
Header: 'Finding', accessor: 'test',
style: {'whiteSpace': 'unset'} // This enables word wrap
},
{
Header: 'Events', id: "events",
accessor: x => {
return <EventsAndButtonComponent events={x.events} exportFilename={"Events_" + x.test_key}/>;
},
maxWidth: 160,
},
{
Header: 'Pillars', id: "pillars",
accessor: x => { accessor: x => {
const pillars = x.pillars; const pillars = x.pillars;
const pillarLabels = pillars.map((pillar) => const pillarLabels = pillars.map((pillar) =>
@ -18,34 +33,19 @@ const columns = [
maxWidth: 200, maxWidth: 200,
style: {'whiteSpace': 'unset'} style: {'whiteSpace': 'unset'}
}, },
{ Header: 'Finding', accessor: 'test',
style: {'whiteSpace': 'unset'} // This enables word wrap
},
{ Header: 'Events', id:"events",
accessor: x => {
return <EventsAndButtonComponent events={x.events} exportFilename={"Events_" + x.test_key}/>;
},
maxWidth: 160,
}
] ]
} }
]; ];
class FindingsTable extends Component {
export class FindingsTable extends Component {
render() { render() {
const data = this.props.findings.map((finding) => { return <Fragment>
const newFinding = JSON.parse(JSON.stringify(finding)); <h3>{<div style={{display: "inline-block"}}><StatusLabel status={this.props.status} showText={true}/>
newFinding.pillars = newFinding.pillars.map((pillar) => { </div>} tests' findings</h3>
return {name: pillar, status: this.props.pillarsToStatuses[pillar]} <PaginatedTable data={this.props.data} pageSize={10} columns={columns}/>
}); </Fragment>
return newFinding;
});
return (
<PaginatedTable data={data} pageSize={10} columns={columns}/>
);
} }
} }
FindingsTable.propTypes = {data: PropTypes.array, status: PropTypes.string};
export default FindingsTable;

View File

@ -16,10 +16,10 @@ const columns = [
}, },
maxWidth: 80 maxWidth: 80
}, },
{ Header: 'Recommendation', accessor: 'recommendation', { Header: 'ZT Recommendation', accessor: 'recommendation',
style: {'whiteSpace': 'unset'} // This enables word wrap style: {'whiteSpace': 'unset'} // This enables word wrap
}, },
{ Header: 'Tests', id: 'tests', { Header: 'Monkey Tests', id: 'tests',
style: {'whiteSpace': 'unset'}, // This enables word wrap style: {'whiteSpace': 'unset'}, // This enables word wrap
accessor: x => { accessor: x => {
return <TestsStatus tests={x.tests} />; return <TestsStatus tests={x.tests} />;