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:
|
||||
if report_data == REPORT_DATA_PILLARS:
|
||||
return jsonify({
|
||||
"summary": ZeroTrustService.get_pillars_summary(),
|
||||
"statusesToPillars": ZeroTrustService.get_statuses_to_pillars(),
|
||||
"pillarsToStatuses": ZeroTrustService.get_pillars_to_statuses(),
|
||||
"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 common.data.zero_trust_consts import *
|
||||
|
@ -198,3 +200,35 @@ class TestZeroTrustService(IslandTestCase):
|
|||
}
|
||||
|
||||
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]
|
||||
|
||||
@staticmethod
|
||||
def get_pillars_summary():
|
||||
def get_statuses_to_pillars():
|
||||
results = {
|
||||
STATUS_CONCLUSIVE: [],
|
||||
STATUS_INCONCLUSIVE: [],
|
||||
|
@ -128,6 +128,14 @@ class ZeroTrustService(object):
|
|||
|
||||
return results
|
||||
|
||||
@staticmethod
|
||||
def get_pillars_to_statuses():
|
||||
results = {}
|
||||
for pillar in PILLARS:
|
||||
results[pillar] = ZeroTrustService.__get_status_for_pillar(pillar)
|
||||
|
||||
return results
|
||||
|
||||
@staticmethod
|
||||
def __get_status_for_pillar(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 MustRunMonkeyWarning from "../report-components/common/MustRunMonkeyWarning";
|
||||
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 {
|
||||
|
||||
|
@ -67,12 +67,12 @@ class ZeroTrustReportPageComponent extends AuthComponent {
|
|||
<Grid fluid={true}>
|
||||
<Row className="show-grid">
|
||||
<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 xs={4} sm={4} md={4} lg={4}>
|
||||
<MonkeysStillAliveWarning allMonkeysAreDead={this.state.allMonkeysAreDead}/>
|
||||
<SecurityIssuesGlance issuesFound={this.anyIssuesFound()}/>
|
||||
<PillarsSummary pillars={this.state.pillars.summary}/>
|
||||
<StatusesToPillarsSummary statusesToPillars={this.state.pillars.statusesToPillars} />
|
||||
</Col>
|
||||
</Row>
|
||||
</Grid>
|
||||
|
@ -92,7 +92,7 @@ class ZeroTrustReportPageComponent extends AuthComponent {
|
|||
|
||||
const findingSection = <div id="findings-overview">
|
||||
<h2>Findings</h2>
|
||||
<FindingsTable findings={this.state.findings}/>
|
||||
<FindingsTable pillarsToStatuses={this.state.pillars.pillarsToStatuses} findings={this.state.findings}/>
|
||||
</div>;
|
||||
|
||||
content = <div id="MainContentSection">
|
||||
|
|
|
@ -58,7 +58,7 @@ const columns = [
|
|||
accessor: x => {
|
||||
const pillars = x.pillars;
|
||||
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>;
|
||||
}
|
||||
|
@ -74,6 +74,13 @@ const columns = [
|
|||
|
||||
class FindingsTable extends Component {
|
||||
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 (
|
||||
<PaginatedTable data={this.props.findings} pageSize={10} columns={columns}/>
|
||||
);
|
||||
|
|
|
@ -1,20 +1,12 @@
|
|||
import React, {Component} from "react";
|
||||
import 'styles/ZeroTrustPillars.css'
|
||||
import {statusToLabelType} from "./StatusLabel";
|
||||
|
||||
export class PillarLabel extends Component {
|
||||
pillar;
|
||||
status;
|
||||
|
||||
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 = {
|
||||
"Data": "fa fa-database",
|
||||
"People": "fa fa-user",
|
||||
|
@ -25,7 +17,7 @@ export class PillarLabel extends Component {
|
|||
"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>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import React, {Component} from "react";
|
||||
import {PillarLabel} from "./PillarLabel";
|
||||
import PaginatedTable from "../common/PaginatedTable";
|
||||
import {PillarsSummary} from "./PillarsSummary";
|
||||
|
||||
const columns = [
|
||||
{
|
||||
Header: 'Pillar Grading',
|
||||
columns: [
|
||||
{ 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: 'Inconclusive', accessor: 'Inconclusive'},
|
||||
|
@ -19,9 +18,15 @@ const columns = [
|
|||
];
|
||||
|
||||
class PillarOverview extends Component {
|
||||
pillarsToStatuses;
|
||||
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}>
|
||||
<PaginatedTable data={this.props.pillars.grades} columns={columns} pageSize={10}/>
|
||||
<PaginatedTable data={data} columns={columns} pageSize={10}/>
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ const statusToIcon = {
|
|||
"Unexecuted": "fa-question",
|
||||
};
|
||||
|
||||
const statusToLabelType = {
|
||||
export const statusToLabelType = {
|
||||
"Positive": "label-success",
|
||||
"Inconclusive": "label-warning",
|
||||
"Conclusive": "label-danger",
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, {Component, Fragment} from "react";
|
|||
import {PillarLabel} from "./PillarLabel";
|
||||
import {StatusLabel} from "./StatusLabel";
|
||||
|
||||
export class PillarsSummary extends Component {
|
||||
export class StatusesToPillarsSummary extends Component {
|
||||
render() {
|
||||
return (<div id="piilar-summary">
|
||||
{this.getStatusSummary("Conclusive")}
|
||||
|
@ -13,16 +13,15 @@ export class PillarsSummary extends Component {
|
|||
}
|
||||
|
||||
getStatusSummary(status) {
|
||||
console.log(this.props.pillars);
|
||||
if (this.props.pillars[status].length > 0) {
|
||||
if (this.props.statusesToPillars[status].length > 0) {
|
||||
return <Fragment>
|
||||
<h3>
|
||||
<StatusLabel showText={true} status={status}/>
|
||||
</h3>
|
||||
<div>
|
||||
{
|
||||
this.props.pillars[status].map((pillar) => {
|
||||
return <PillarLabel key={pillar} pillar={pillar}/>
|
||||
this.props.statusesToPillars[status].map((pillar) => {
|
||||
return <PillarLabel key={pillar} pillar={pillar} status={status} />
|
||||
})
|
||||
}
|
||||
</div>
|
Loading…
Reference in New Issue