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 f1a4de673..7b1369dbc 100755 --- a/monkey/monkey_island/cc/ui/src/components/pages/ZeroTrustReportPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ZeroTrustReportPage.js @@ -8,7 +8,6 @@ import SinglePillarDirectivesStatus from "../report-components/zerotrust/SingleP import MonkeysStillAliveWarning from "../report-components/common/MonkeysStillAliveWarning"; import ReportLoader from "../report-components/common/ReportLoader"; import MustRunMonkeyWarning from "../report-components/common/MustRunMonkeyWarning"; -import SecurityIssuesGlance from "../report-components/common/SecurityIssuesGlance"; import StatusesToPillarsSummary from "../report-components/zerotrust/StatusesToPillarsSummary"; import PrintReportButton from "../report-components/common/PrintReportButton"; import {extractExecutionStatusFromServerResponse} from "../report-components/common/ExecutionStatus"; @@ -94,6 +93,11 @@ class ZeroTrustReportPageComponent extends AuthComponent { generateFindingsSection() { return (

Findings

+

+ Deep-dive into the details of each test, and see the explicit events and exact timestamps in which things + 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. +

); } @@ -101,6 +105,10 @@ class ZeroTrustReportPageComponent extends AuthComponent { generateDirectivesSection() { return (

Directives

+

+ Analyze each zero trust recommendation by pillar, and see if you've followed through with it. See test results + to understand how the monkey tested your adherence to that recommendation. +

{ Object.keys(this.state.directives).map((pillar) => { return ; - } + }, + maxWidth: 80 + }, + { Header: 'Directive', accessor: 'directive', + style: {'whiteSpace': 'unset'} // This enables word wrap }, { Header: 'Tests', id: 'tests', style: {'whiteSpace': 'unset'}, // This enables word wrap @@ -56,7 +56,7 @@ class TestsStatus extends AuthComponent { return (
  • {test.test}
  • ) }); return - +
      {listItems}
    ; } diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/EventsAndButtonComponent.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/EventsAndButtonComponent.js index 0222b375f..0b96f8fc2 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/EventsAndButtonComponent.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/EventsAndButtonComponent.js @@ -3,6 +3,7 @@ import EventsModal from "./EventsModal"; import {Button} from "react-bootstrap"; import FileSaver from "file-saver"; import * as PropTypes from "prop-types"; +import ExportEventsButton from "./ExportEventsButton"; export default class EventsAndButtonComponent extends Component { constructor(props) { @@ -23,22 +24,17 @@ export default class EventsAndButtonComponent extends Component { render() { return (
    - -

    - - -

    + { + const content = JSON.stringify(this.props.events, null, 2); + const blob = new Blob([content], {type: "text/plain;charset=utf-8"}); + FileSaver.saveAs(blob, this.props.exportFilename + ".json"); + }}/> +
    ); } diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/EventsModal.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/EventsModal.js index 9543603bd..5da053242 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/EventsModal.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/EventsModal.js @@ -2,6 +2,8 @@ import React, {Component} from "react"; import {Modal} from "react-bootstrap"; import EventsTimeline from "./EventsTimeline"; import * as PropTypes from "prop-types"; +import FileSaver from "file-saver"; +import ExportEventsButton from "./ExportEventsButton"; export default class EventsModal extends Component { constructor(props) { @@ -24,6 +26,11 @@ export default class EventsModal extends Component { onClick={() => this.props.hideCallback()}> Close + { + const content = JSON.stringify(this.props.events, null, 2); + const blob = new Blob([content], {type: "text/plain;charset=utf-8"}); + FileSaver.saveAs(blob, this.props.exportFilename + ".json"); + }}/> diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/ExportEventsButton.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/ExportEventsButton.js new file mode 100644 index 000000000..b75516e2c --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/ExportEventsButton.js @@ -0,0 +1,15 @@ +import React, {Component} from "react"; +import {Button} from "react-bootstrap"; +import * as PropTypes from "prop-types"; + +export default class ExportEventsButton extends Component { + render() { + return + } +} + +ExportEventsButton.propTypes = {onClick: PropTypes.func}; 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 9d706b3f2..658d6d039 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 @@ -1,4 +1,4 @@ -import React, {Component} from "react"; +import React, {Component, Fragment} from "react"; import PillarLabel from "./PillarLabel"; import PaginatedTable from "../common/PaginatedTable"; import EventsAndButtonComponent from "./EventsAndButtonComponent"; @@ -6,24 +6,27 @@ import EventsAndButtonComponent from "./EventsAndButtonComponent"; const columns = [ { - Header: 'Findings', columns: [ - { Header: 'Finding', accessor: 'test', - style: {'whiteSpace': 'unset'} // This enables word wrap - }, { Header: 'Pillars', id: "pillars", accessor: x => { const pillars = x.pillars; - const listItems = pillars.map((pillar) => -
  • + const pillarLabels = pillars.map((pillar) => + ); - return ; - } + return {pillarLabels}; + }, + maxWidth: 200, + style: {'whiteSpace': 'unset'} }, + { Header: 'Finding', accessor: 'test', + style: {'whiteSpace': 'unset'} // This enables word wrap + }, + { Header: 'Events', id:"events", accessor: x => { return ; - } + }, + maxWidth: 160, } ] } diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/SinglePillarDirectivesStatus.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/SinglePillarDirectivesStatus.js index 47f477dfd..9a5f9723d 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/SinglePillarDirectivesStatus.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/SinglePillarDirectivesStatus.js @@ -3,6 +3,7 @@ import PillarLabel from "./PillarLabel"; import DirectivesStatusTable from "./DirectivesStatusTable"; import React, {Fragment} from "react"; import * as PropTypes from "prop-types"; +import {Panel} from "react-bootstrap"; export default class SinglePillarDirectivesStatus extends AuthComponent { render() { @@ -11,10 +12,20 @@ export default class SinglePillarDirectivesStatus extends AuthComponent { } else { return ( - -

    - -
    + + + +

    + 🔽 +

    +
    +
    + + + + + +
    ); } }