diff --git a/monkey/monkey_island/cc/resources/reporting/report.py b/monkey/monkey_island/cc/resources/reporting/report.py index fba129e65..aa13468a3 100644 --- a/monkey/monkey_island/cc/resources/reporting/report.py +++ b/monkey/monkey_island/cc/resources/reporting/report.py @@ -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() } ) diff --git a/monkey/monkey_island/cc/services/reporting/test_zeroTrustService.py b/monkey/monkey_island/cc/services/reporting/test_zeroTrustService.py index ff6e88982..7e7df7ad0 100644 --- a/monkey/monkey_island/cc/services/reporting/test_zeroTrustService.py +++ b/monkey/monkey_island/cc/services/reporting/test_zeroTrustService.py @@ -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) diff --git a/monkey/monkey_island/cc/services/reporting/zero_trust_service.py b/monkey/monkey_island/cc/services/reporting/zero_trust_service.py index 835f869ea..bf2b9d6e8 100644 --- a/monkey/monkey_island/cc/services/reporting/zero_trust_service.py +++ b/monkey/monkey_island/cc/services/reporting/zero_trust_service.py @@ -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) diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ZeroTrustReportPage.js b/monkey/monkey_island/cc/ui/src/components/pages/ZeroTrustReportPage.js index 5795c275f..0f0326f14 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ZeroTrustReportPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ZeroTrustReportPage.js @@ -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 { - + - + @@ -92,7 +92,7 @@ class ZeroTrustReportPageComponent extends AuthComponent { const findingSection =

Findings

- +
; content =
diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsTable.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsTable.js index ae1c41d49..b50a0e436 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsTable.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsTable.js @@ -58,7 +58,7 @@ const columns = [ accessor: x => { const pillars = x.pillars; const listItems = pillars.map((pillar) => -
  • +
  • ); return ; } @@ -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 ( ); diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PillarLabel.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PillarLabel.js index b6b588876..4559e5cd9 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PillarLabel.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PillarLabel.js @@ -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
    {this.props.pillar}
    } } diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PillarOverview.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PillarOverview.js index a6c6f848f..558da5456 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PillarOverview.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PillarOverview.js @@ -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 (); + return (); }}, { 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 (
    - +
    ); } } diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/StatusLabel.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/StatusLabel.js index 68ce5111e..a53e4c919 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/StatusLabel.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/StatusLabel.js @@ -8,7 +8,7 @@ const statusToIcon = { "Unexecuted": "fa-question", }; -const statusToLabelType = { +export const statusToLabelType = { "Positive": "label-success", "Inconclusive": "label-warning", "Conclusive": "label-danger", diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PillarsSummary.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/StatusesToPillarsSummary.js similarity index 76% rename from monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PillarsSummary.js rename to monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/StatusesToPillarsSummary.js index 962afdd3c..bfcaceed9 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PillarsSummary.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/StatusesToPillarsSummary.js @@ -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 (
    {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

    { - this.props.pillars[status].map((pillar) => { - return + this.props.statusesToPillars[status].map((pillar) => { + return }) }