Added pillar summary as per Barak's idea
This commit is contained in:
parent
0325521936
commit
cd7cc4011d
|
@ -12,7 +12,7 @@ STATUS_POSITIVE = u"Positive"
|
||||||
STATUS_INCONCLUSIVE = u"Inconclusive"
|
STATUS_INCONCLUSIVE = u"Inconclusive"
|
||||||
STATUS_CONCLUSIVE = u"Conclusive"
|
STATUS_CONCLUSIVE = u"Conclusive"
|
||||||
# Don't change order!
|
# Don't change order!
|
||||||
TEST_STATUSES = [STATUS_CONCLUSIVE, STATUS_INCONCLUSIVE, STATUS_POSITIVE, STATUS_UNEXECUTED]
|
ORDERED_TEST_STATUSES = [STATUS_CONCLUSIVE, STATUS_INCONCLUSIVE, STATUS_POSITIVE, STATUS_UNEXECUTED]
|
||||||
|
|
||||||
TEST_DATA_ENDPOINT_ELASTIC = u"unencrypted_data_endpoint_elastic"
|
TEST_DATA_ENDPOINT_ELASTIC = u"unencrypted_data_endpoint_elastic"
|
||||||
TEST_DATA_ENDPOINT_HTTP = u"unencrypted_data_endpoint_http"
|
TEST_DATA_ENDPOINT_HTTP = u"unencrypted_data_endpoint_http"
|
||||||
|
|
|
@ -4,7 +4,7 @@ Define a Document Schema for Zero Trust findings.
|
||||||
|
|
||||||
from mongoengine import Document, StringField, EmbeddedDocumentListField
|
from mongoengine import Document, StringField, EmbeddedDocumentListField
|
||||||
|
|
||||||
from common.data.zero_trust_consts import TEST_STATUSES, TESTS, TESTS_MAP, EXPLANATION_KEY, PILLARS_KEY
|
from common.data.zero_trust_consts import ORDERED_TEST_STATUSES, TESTS, TESTS_MAP, EXPLANATION_KEY, PILLARS_KEY
|
||||||
# Dummy import for mongoengine.
|
# Dummy import for mongoengine.
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
from event import Event
|
from event import Event
|
||||||
|
@ -19,7 +19,7 @@ class Finding(Document):
|
||||||
"""
|
"""
|
||||||
# SCHEMA
|
# SCHEMA
|
||||||
test = StringField(required=True, choices=TESTS)
|
test = StringField(required=True, choices=TESTS)
|
||||||
status = StringField(required=True, choices=TEST_STATUSES)
|
status = StringField(required=True, choices=ORDERED_TEST_STATUSES)
|
||||||
events = EmbeddedDocumentListField(document_type=Event)
|
events = EmbeddedDocumentListField(document_type=Event)
|
||||||
|
|
||||||
# LOGIC
|
# LOGIC
|
||||||
|
|
|
@ -27,7 +27,11 @@ class Report(flask_restful.Resource):
|
||||||
return ReportService.get_report()
|
return ReportService.get_report()
|
||||||
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(ZeroTrustService.get_pillars_grades())
|
return jsonify({
|
||||||
|
"summary": ZeroTrustService.get_pillars_summary(),
|
||||||
|
"grades": ZeroTrustService.get_pillars_grades()
|
||||||
|
}
|
||||||
|
)
|
||||||
elif report_data == REPORT_DATA_DIRECTIVES_STATUS:
|
elif report_data == REPORT_DATA_DIRECTIVES_STATUS:
|
||||||
return jsonify(ZeroTrustService.get_directives_status())
|
return jsonify(ZeroTrustService.get_directives_status())
|
||||||
elif report_data == REPORT_DATA_FINDINGS:
|
elif report_data == REPORT_DATA_FINDINGS:
|
||||||
|
|
|
@ -7,13 +7,13 @@ class ZeroTrustService(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_pillars_grades():
|
def get_pillars_grades():
|
||||||
pillars_grades = []
|
pillars_grades = []
|
||||||
all_findings = Finding.objects()
|
|
||||||
for pillar in PILLARS:
|
for pillar in PILLARS:
|
||||||
pillars_grades.append(ZeroTrustService.__get_pillar_grade(pillar, all_findings))
|
pillars_grades.append(ZeroTrustService.__get_pillar_grade(pillar))
|
||||||
return pillars_grades
|
return pillars_grades
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __get_pillar_grade(pillar, all_findings):
|
def __get_pillar_grade(pillar):
|
||||||
|
all_findings = Finding.objects()
|
||||||
pillar_grade = {
|
pillar_grade = {
|
||||||
"pillar": pillar,
|
"pillar": pillar,
|
||||||
STATUS_CONCLUSIVE: 0,
|
STATUS_CONCLUSIVE: 0,
|
||||||
|
@ -66,7 +66,7 @@ class ZeroTrustService(object):
|
||||||
all_statuses |= set(Finding.objects(test=test).distinct("status"))
|
all_statuses |= set(Finding.objects(test=test).distinct("status"))
|
||||||
|
|
||||||
for status in all_statuses:
|
for status in all_statuses:
|
||||||
if TEST_STATUSES.index(status) < TEST_STATUSES.index(worst_status):
|
if ORDERED_TEST_STATUSES.index(status) < ORDERED_TEST_STATUSES.index(worst_status):
|
||||||
worst_status = status
|
worst_status = status
|
||||||
|
|
||||||
return worst_status
|
return worst_status
|
||||||
|
@ -88,7 +88,7 @@ class ZeroTrustService(object):
|
||||||
def __get_lcd_worst_status_for_test(all_findings_for_test):
|
def __get_lcd_worst_status_for_test(all_findings_for_test):
|
||||||
current_status = STATUS_UNEXECUTED
|
current_status = STATUS_UNEXECUTED
|
||||||
for finding in all_findings_for_test:
|
for finding in all_findings_for_test:
|
||||||
if TEST_STATUSES.index(finding.status) < TEST_STATUSES.index(current_status):
|
if ORDERED_TEST_STATUSES.index(finding.status) < ORDERED_TEST_STATUSES.index(current_status):
|
||||||
current_status = finding.status
|
current_status = finding.status
|
||||||
|
|
||||||
return current_status
|
return current_status
|
||||||
|
@ -115,3 +115,23 @@ class ZeroTrustService(object):
|
||||||
def __get_events_as_dict(events):
|
def __get_events_as_dict(events):
|
||||||
return [json.loads(event.to_json()) for event in events]
|
return [json.loads(event.to_json()) for event in events]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_pillars_summary():
|
||||||
|
results = {
|
||||||
|
STATUS_CONCLUSIVE: [],
|
||||||
|
STATUS_INCONCLUSIVE: [],
|
||||||
|
STATUS_POSITIVE: [],
|
||||||
|
STATUS_UNEXECUTED: []
|
||||||
|
}
|
||||||
|
for pillar in PILLARS:
|
||||||
|
results[ZeroTrustService.__get_status_for_pillar(pillar)].append(pillar)
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __get_status_for_pillar(pillar):
|
||||||
|
grade = ZeroTrustService.__get_pillar_grade(pillar)
|
||||||
|
for status in ORDERED_TEST_STATUSES:
|
||||||
|
if grade[status] > 0:
|
||||||
|
return status
|
||||||
|
return STATUS_UNEXECUTED
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
import {Button, Col} from 'react-bootstrap';
|
import {Button, Col} 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 PillarGrades from "../report-components/zerotrust/PillarGrades";
|
import PillarsOverview from "../report-components/zerotrust/PillarOverview";
|
||||||
import FindingsTable from "../report-components/zerotrust/FindingsTable";
|
import FindingsTable from "../report-components/zerotrust/FindingsTable";
|
||||||
import {SinglePillarDirectivesStatus} from "../report-components/zerotrust/SinglePillarDirectivesStatus";
|
import {SinglePillarDirectivesStatus} from "../report-components/zerotrust/SinglePillarDirectivesStatus";
|
||||||
import {MonkeysStillAliveWarning} from "../report-components/common/MonkeysStillAliveWarning";
|
import {MonkeysStillAliveWarning} from "../report-components/common/MonkeysStillAliveWarning";
|
||||||
|
@ -60,9 +60,10 @@ class ZeroTrustReportPageComponent extends AuthComponent {
|
||||||
if (this.stillLoadingDataFromServer()) {
|
if (this.stillLoadingDataFromServer()) {
|
||||||
content = <ReportLoader loading={true}/>;
|
content = <ReportLoader loading={true}/>;
|
||||||
} else {
|
} else {
|
||||||
|
console.log(this.state.pillars);
|
||||||
const pillarsSection = <div id="pillars-overview">
|
const pillarsSection = <div id="pillars-overview">
|
||||||
<h2>Pillars Overview</h2>
|
<h2>Pillars Overview</h2>
|
||||||
<PillarGrades pillars={this.state.pillars}/>
|
<PillarsOverview pillars={this.state.pillars}/>
|
||||||
</div>;
|
</div>;
|
||||||
|
|
||||||
const directivesSection = <div id="directives-overview">
|
const directivesSection = <div id="directives-overview">
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
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 = [
|
||||||
{
|
{
|
||||||
|
@ -17,10 +18,14 @@ const columns = [
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
class PillarGrades extends Component {
|
class PillarOverview extends Component {
|
||||||
render() {
|
render() {
|
||||||
return <PaginatedTable data={this.props.pillars} columns={columns} pageSize={10}/>;
|
return (<div id={this.constructor.name}>
|
||||||
|
<PillarsSummary pillars={this.props.pillars.summary}/>
|
||||||
|
<br/>
|
||||||
|
<PaginatedTable data={this.props.pillars.grades} columns={columns} pageSize={10}/>
|
||||||
|
</div>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PillarGrades;
|
export default PillarOverview;
|
|
@ -0,0 +1,29 @@
|
||||||
|
import React, {Component, Fragment} from "react";
|
||||||
|
import {PillarLabel} from "./PillarLabel";
|
||||||
|
|
||||||
|
export class PillarsSummary extends Component {
|
||||||
|
render() {
|
||||||
|
return (<div id="piilar-summary">
|
||||||
|
{this.getStatusSummary("Conclusive")}
|
||||||
|
{this.getStatusSummary("Inconclusive")}
|
||||||
|
{this.getStatusSummary("Positive")}
|
||||||
|
{this.getStatusSummary("Unexecuted")}
|
||||||
|
</div>);
|
||||||
|
}
|
||||||
|
|
||||||
|
getStatusSummary(status) {
|
||||||
|
console.log(this.props.pillars);
|
||||||
|
if (this.props.pillars[status].length > 0) {
|
||||||
|
return <Fragment>
|
||||||
|
<h3>{status}</h3>
|
||||||
|
<p>
|
||||||
|
{
|
||||||
|
this.props.pillars[status].map((pillar) => {
|
||||||
|
return <PillarLabel key={pillar} pillar={pillar}/>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
</Fragment>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue