forked from p15670423/monkey
All labels now show status
This commit is contained in:
parent
3d96f71988
commit
7006a2332f
|
@ -28,7 +28,8 @@ class Report(flask_restful.Resource):
|
||||||
elif report_type == ZERO_TRUST_REPORT_TYPE:
|
elif report_type == ZERO_TRUST_REPORT_TYPE:
|
||||||
if report_data == REPORT_DATA_PILLARS:
|
if report_data == REPORT_DATA_PILLARS:
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"summary": ZeroTrustService.get_pillars_summary(),
|
"statusesToPillars": ZeroTrustService.get_statuses_to_pillars(),
|
||||||
|
"pillarsToStatuses": ZeroTrustService.get_pillars_to_statuses(),
|
||||||
"grades": ZeroTrustService.get_pillars_grades()
|
"grades": ZeroTrustService.get_pillars_grades()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
from monkey_island.cc.services.reporting.zero_trust_service import ZeroTrustService
|
from monkey_island.cc.services.reporting.zero_trust_service import ZeroTrustService
|
||||||
|
|
||||||
from common.data.zero_trust_consts import *
|
from common.data.zero_trust_consts import *
|
||||||
|
@ -198,3 +200,35 @@ class TestZeroTrustService(IslandTestCase):
|
||||||
}
|
}
|
||||||
|
|
||||||
self.assertEquals(ZeroTrustService.get_directives_status(), expected)
|
self.assertEquals(ZeroTrustService.get_directives_status(), expected)
|
||||||
|
|
||||||
|
def test_get_pillars_to_statuses(self):
|
||||||
|
self.fail_if_not_testing_env()
|
||||||
|
self.clean_finding_db()
|
||||||
|
|
||||||
|
self.maxDiff = None
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
AUTOMATION_ORCHESTRATION: STATUS_UNEXECUTED,
|
||||||
|
DEVICES: STATUS_UNEXECUTED,
|
||||||
|
NETWORKS: STATUS_UNEXECUTED,
|
||||||
|
PEOPLE: STATUS_UNEXECUTED,
|
||||||
|
VISIBILITY_ANALYTICS: STATUS_UNEXECUTED,
|
||||||
|
WORKLOADS: STATUS_UNEXECUTED,
|
||||||
|
DATA: STATUS_UNEXECUTED
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertEquals(ZeroTrustService.get_pillars_to_statuses(), expected)
|
||||||
|
|
||||||
|
save_example_findings()
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
AUTOMATION_ORCHESTRATION: STATUS_UNEXECUTED,
|
||||||
|
DEVICES: STATUS_CONCLUSIVE,
|
||||||
|
NETWORKS: STATUS_INCONCLUSIVE,
|
||||||
|
PEOPLE: STATUS_INCONCLUSIVE,
|
||||||
|
VISIBILITY_ANALYTICS: STATUS_UNEXECUTED,
|
||||||
|
WORKLOADS: STATUS_UNEXECUTED,
|
||||||
|
DATA: STATUS_CONCLUSIVE
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertEquals(ZeroTrustService.get_pillars_to_statuses(), expected)
|
||||||
|
|
|
@ -116,7 +116,7 @@ class ZeroTrustService(object):
|
||||||
return [json.loads(event.to_json()) for event in events]
|
return [json.loads(event.to_json()) for event in events]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_pillars_summary():
|
def get_statuses_to_pillars():
|
||||||
results = {
|
results = {
|
||||||
STATUS_CONCLUSIVE: [],
|
STATUS_CONCLUSIVE: [],
|
||||||
STATUS_INCONCLUSIVE: [],
|
STATUS_INCONCLUSIVE: [],
|
||||||
|
@ -128,6 +128,14 @@ class ZeroTrustService(object):
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_pillars_to_statuses():
|
||||||
|
results = {}
|
||||||
|
for pillar in PILLARS:
|
||||||
|
results[pillar] = ZeroTrustService.__get_status_for_pillar(pillar)
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __get_status_for_pillar(pillar):
|
def __get_status_for_pillar(pillar):
|
||||||
grade = ZeroTrustService.__get_pillar_grade(pillar)
|
grade = ZeroTrustService.__get_pillar_grade(pillar)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {MonkeysStillAliveWarning} from "../report-components/common/MonkeysStill
|
||||||
import ReportLoader from "../report-components/common/ReportLoader";
|
import ReportLoader from "../report-components/common/ReportLoader";
|
||||||
import MustRunMonkeyWarning from "../report-components/common/MustRunMonkeyWarning";
|
import MustRunMonkeyWarning from "../report-components/common/MustRunMonkeyWarning";
|
||||||
import {SecurityIssuesGlance} from "../report-components/common/SecurityIssuesGlance";
|
import {SecurityIssuesGlance} from "../report-components/common/SecurityIssuesGlance";
|
||||||
import {PillarsSummary} from "../report-components/zerotrust/PillarsSummary";
|
import {StatusesToPillarsSummary} from "../report-components/zerotrust/StatusesToPillarsSummary";
|
||||||
|
|
||||||
class ZeroTrustReportPageComponent extends AuthComponent {
|
class ZeroTrustReportPageComponent extends AuthComponent {
|
||||||
|
|
||||||
|
@ -67,12 +67,12 @@ class ZeroTrustReportPageComponent extends AuthComponent {
|
||||||
<Grid fluid={true}>
|
<Grid fluid={true}>
|
||||||
<Row className="show-grid">
|
<Row className="show-grid">
|
||||||
<Col xs={8} sm={8} md={8} lg={8}>
|
<Col xs={8} sm={8} md={8} lg={8}>
|
||||||
<PillarsOverview pillars={this.state.pillars}/>
|
<PillarsOverview pillarsToStatuses={this.state.pillars.pillarsToStatuses} grades={this.state.pillars.grades}/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={4} sm={4} md={4} lg={4}>
|
<Col xs={4} sm={4} md={4} lg={4}>
|
||||||
<MonkeysStillAliveWarning allMonkeysAreDead={this.state.allMonkeysAreDead}/>
|
<MonkeysStillAliveWarning allMonkeysAreDead={this.state.allMonkeysAreDead}/>
|
||||||
<SecurityIssuesGlance issuesFound={this.anyIssuesFound()}/>
|
<SecurityIssuesGlance issuesFound={this.anyIssuesFound()}/>
|
||||||
<PillarsSummary pillars={this.state.pillars.summary}/>
|
<StatusesToPillarsSummary statusesToPillars={this.state.pillars.statusesToPillars} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -92,7 +92,7 @@ class ZeroTrustReportPageComponent extends AuthComponent {
|
||||||
|
|
||||||
const findingSection = <div id="findings-overview">
|
const findingSection = <div id="findings-overview">
|
||||||
<h2>Findings</h2>
|
<h2>Findings</h2>
|
||||||
<FindingsTable findings={this.state.findings}/>
|
<FindingsTable pillarsToStatuses={this.state.pillars.pillarsToStatuses} findings={this.state.findings}/>
|
||||||
</div>;
|
</div>;
|
||||||
|
|
||||||
content = <div id="MainContentSection">
|
content = <div id="MainContentSection">
|
||||||
|
|
|
@ -58,7 +58,7 @@ const columns = [
|
||||||
accessor: x => {
|
accessor: x => {
|
||||||
const pillars = x.pillars;
|
const pillars = x.pillars;
|
||||||
const listItems = pillars.map((pillar) =>
|
const listItems = pillars.map((pillar) =>
|
||||||
<li key={pillar}><PillarLabel pillar={pillar}/></li>
|
<li key={pillar.name}><PillarLabel pillar={pillar.name} status={pillar.status}/></li>
|
||||||
);
|
);
|
||||||
return <ul>{listItems}</ul>;
|
return <ul>{listItems}</ul>;
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,13 @@ const columns = [
|
||||||
|
|
||||||
class FindingsTable extends Component {
|
class FindingsTable extends Component {
|
||||||
render() {
|
render() {
|
||||||
|
const data = this.props.findings.map((finding) => {
|
||||||
|
const newFinding = finding;
|
||||||
|
newFinding.pillars = finding.pillars.map((pillar) => {
|
||||||
|
return {name: pillar, status: this.props.pillarsToStatuses[pillar]}
|
||||||
|
});
|
||||||
|
return newFinding;
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<PaginatedTable data={this.props.findings} pageSize={10} columns={columns}/>
|
<PaginatedTable data={this.props.findings} pageSize={10} columns={columns}/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,20 +1,12 @@
|
||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import 'styles/ZeroTrustPillars.css'
|
import 'styles/ZeroTrustPillars.css'
|
||||||
|
import {statusToLabelType} from "./StatusLabel";
|
||||||
|
|
||||||
export class PillarLabel extends Component {
|
export class PillarLabel extends Component {
|
||||||
pillar;
|
pillar;
|
||||||
|
status;
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const pillarToColor = {
|
|
||||||
"Data": "label-zt-data",
|
|
||||||
"People": "label-zt-people",
|
|
||||||
"Networks": "label-zt-networks",
|
|
||||||
"Workloads": "label-zt-workloads",
|
|
||||||
"Devices": "label-zt-devices",
|
|
||||||
"Visibility & Analytics": "label-zt-analytics",
|
|
||||||
"Automation & Orchestration": "label-zt-automation",
|
|
||||||
};
|
|
||||||
|
|
||||||
const pillarToIcon = {
|
const pillarToIcon = {
|
||||||
"Data": "fa fa-database",
|
"Data": "fa fa-database",
|
||||||
"People": "fa fa-user",
|
"People": "fa fa-user",
|
||||||
|
@ -25,7 +17,7 @@ export class PillarLabel extends Component {
|
||||||
"Automation & Orchestration": "fa fa-cogs",
|
"Automation & Orchestration": "fa fa-cogs",
|
||||||
};
|
};
|
||||||
|
|
||||||
const className = "label " + pillarToColor[this.props.pillar];
|
const className = "label " + statusToLabelType[this.props.status];
|
||||||
return <div className={className} style={{margin: '2px', display: 'inline-block'}}><i className={pillarToIcon[this.props.pillar]}/> {this.props.pillar}</div>
|
return <div className={className} style={{margin: '2px', display: 'inline-block'}}><i className={pillarToIcon[this.props.pillar]}/> {this.props.pillar}</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import {PillarLabel} from "./PillarLabel";
|
import {PillarLabel} from "./PillarLabel";
|
||||||
import PaginatedTable from "../common/PaginatedTable";
|
import PaginatedTable from "../common/PaginatedTable";
|
||||||
import {PillarsSummary} from "./PillarsSummary";
|
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
Header: 'Pillar Grading',
|
Header: 'Pillar Grading',
|
||||||
columns: [
|
columns: [
|
||||||
{ Header: 'Pillar', id: 'Pillar', accessor: x => {
|
{ Header: 'Pillar', id: 'Pillar', accessor: x => {
|
||||||
return (<PillarLabel pillar={x.pillar} />);
|
return (<PillarLabel pillar={x.pillar.name} status={x.pillar.status} />);
|
||||||
}},
|
}},
|
||||||
{ Header: 'Conclusive', accessor: 'Conclusive'},
|
{ Header: 'Conclusive', accessor: 'Conclusive'},
|
||||||
{ Header: 'Inconclusive', accessor: 'Inconclusive'},
|
{ Header: 'Inconclusive', accessor: 'Inconclusive'},
|
||||||
|
@ -19,9 +18,15 @@ const columns = [
|
||||||
];
|
];
|
||||||
|
|
||||||
class PillarOverview extends Component {
|
class PillarOverview extends Component {
|
||||||
|
pillarsToStatuses;
|
||||||
render() {
|
render() {
|
||||||
|
const data = this.props.grades.map((grade) => {
|
||||||
|
const newGrade = grade;
|
||||||
|
newGrade.pillar = {name: grade.pillar, status: this.props.pillarsToStatuses[grade.pillar]};
|
||||||
|
return newGrade;
|
||||||
|
});
|
||||||
return (<div id={this.constructor.name}>
|
return (<div id={this.constructor.name}>
|
||||||
<PaginatedTable data={this.props.pillars.grades} columns={columns} pageSize={10}/>
|
<PaginatedTable data={data} columns={columns} pageSize={10}/>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ const statusToIcon = {
|
||||||
"Unexecuted": "fa-question",
|
"Unexecuted": "fa-question",
|
||||||
};
|
};
|
||||||
|
|
||||||
const statusToLabelType = {
|
export const statusToLabelType = {
|
||||||
"Positive": "label-success",
|
"Positive": "label-success",
|
||||||
"Inconclusive": "label-warning",
|
"Inconclusive": "label-warning",
|
||||||
"Conclusive": "label-danger",
|
"Conclusive": "label-danger",
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React, {Component, Fragment} from "react";
|
||||||
import {PillarLabel} from "./PillarLabel";
|
import {PillarLabel} from "./PillarLabel";
|
||||||
import {StatusLabel} from "./StatusLabel";
|
import {StatusLabel} from "./StatusLabel";
|
||||||
|
|
||||||
export class PillarsSummary extends Component {
|
export class StatusesToPillarsSummary extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (<div id="piilar-summary">
|
return (<div id="piilar-summary">
|
||||||
{this.getStatusSummary("Conclusive")}
|
{this.getStatusSummary("Conclusive")}
|
||||||
|
@ -13,16 +13,15 @@ export class PillarsSummary extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
getStatusSummary(status) {
|
getStatusSummary(status) {
|
||||||
console.log(this.props.pillars);
|
if (this.props.statusesToPillars[status].length > 0) {
|
||||||
if (this.props.pillars[status].length > 0) {
|
|
||||||
return <Fragment>
|
return <Fragment>
|
||||||
<h3>
|
<h3>
|
||||||
<StatusLabel showText={true} status={status}/>
|
<StatusLabel showText={true} status={status}/>
|
||||||
</h3>
|
</h3>
|
||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
this.props.pillars[status].map((pillar) => {
|
this.props.statusesToPillars[status].map((pillar) => {
|
||||||
return <PillarLabel key={pillar} pillar={pillar}/>
|
return <PillarLabel key={pillar} pillar={pillar} status={status} />
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
Loading…
Reference in New Issue