Refactored Finding DTO into ScoutSuiteFinding and MonkeyFinding DTO which inherit from more abstract Finding.
This commit is contained in:
parent
9444067250
commit
80e7435572
|
@ -22,10 +22,6 @@ STATUS_FAILED = "Failed"
|
|||
# Don't change order! The statuses are ordered by importance/severity.
|
||||
ORDERED_TEST_STATUSES = [STATUS_FAILED, STATUS_VERIFY, STATUS_PASSED, STATUS_UNEXECUTED]
|
||||
|
||||
MONKEY_FINDING = "monkey_finding"
|
||||
SCOUTSUITE_FINDING = "scoutsuite_finding"
|
||||
FINDING_TYPES = [MONKEY_FINDING, SCOUTSUITE_FINDING]
|
||||
|
||||
TEST_DATA_ENDPOINT_ELASTIC = "unencrypted_data_endpoint_elastic"
|
||||
TEST_DATA_ENDPOINT_HTTP = "unencrypted_data_endpoint_http"
|
||||
TEST_MACHINE_EXPLOITED = "machine_exploited"
|
||||
|
|
|
@ -4,7 +4,8 @@ Define a Document Schema for Zero Trust findings.
|
|||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import Union
|
||||
|
||||
import abc
|
||||
|
||||
from mongoengine import Document, GenericLazyReferenceField, StringField
|
||||
|
||||
|
@ -12,7 +13,6 @@ import common.common_consts.zero_trust_consts as zero_trust_consts
|
|||
# Dummy import for mongoengine.
|
||||
# noinspection PyUnresolvedReferences
|
||||
from monkey_island.cc.models.zero_trust.monkey_finding_details import MonkeyFindingDetails
|
||||
from monkey_island.cc.models.zero_trust.scoutsuite_finding_details import ScoutSuiteFindingDetails
|
||||
|
||||
|
||||
class Finding(Document):
|
||||
|
@ -33,39 +33,21 @@ class Finding(Document):
|
|||
* The logic section defines complex questions we can ask about a single document which are asked multiple
|
||||
times, or complex action we will perform - somewhat like an API.
|
||||
"""
|
||||
# SCHEMA
|
||||
test = StringField(required=True, choices=zero_trust_consts.TESTS)
|
||||
status = StringField(required=True, choices=zero_trust_consts.ORDERED_TEST_STATUSES)
|
||||
finding_type = StringField(required=True, choices=zero_trust_consts.FINDING_TYPES)
|
||||
|
||||
# Details are in a separate document in order to discourage pulling them when not needed
|
||||
# due to performance.
|
||||
details = GenericLazyReferenceField(choices=[MonkeyFindingDetails, ScoutSuiteFindingDetails], required=True)
|
||||
# http://docs.mongoengine.org/guide/defining-documents.html#document-inheritance
|
||||
meta = {'allow_inheritance': True}
|
||||
|
||||
# LOGIC
|
||||
def get_test_explanation(self):
|
||||
return zero_trust_consts.TESTS_MAP[self.test][zero_trust_consts.TEST_EXPLANATION_KEY]
|
||||
# SCHEMA
|
||||
test = StringField(required=True, choices=zero_trust_consts.TESTS)
|
||||
status = StringField(required=True, choices=zero_trust_consts.ORDERED_TEST_STATUSES)
|
||||
|
||||
def get_pillars(self):
|
||||
return zero_trust_consts.TESTS_MAP[self.test][zero_trust_consts.PILLARS_KEY]
|
||||
# Details are in a separate document in order to discourage pulling them when not needed
|
||||
# due to performance.
|
||||
details = GenericLazyReferenceField(required=True)
|
||||
|
||||
# Creation methods
|
||||
@staticmethod
|
||||
@abc.abstractmethod
|
||||
def save_finding(test: str,
|
||||
status: str,
|
||||
detail_ref: Union[MonkeyFindingDetails, ScoutSuiteFindingDetails]) -> Finding:
|
||||
finding = Finding(test=test,
|
||||
status=status,
|
||||
details=detail_ref,
|
||||
finding_type=Finding._get_finding_type_by_details(detail_ref))
|
||||
finding.save()
|
||||
return finding
|
||||
|
||||
@staticmethod
|
||||
def _get_finding_type_by_details(details: Union[MonkeyFindingDetails, ScoutSuiteFindingDetails]) -> str:
|
||||
if type(details) == MonkeyFindingDetails:
|
||||
return zero_trust_consts.MONKEY_FINDING
|
||||
else:
|
||||
return zero_trust_consts.SCOUTSUITE_FINDING
|
||||
detail_ref) -> Finding:
|
||||
pass
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
from mongoengine import LazyReferenceField
|
||||
|
||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||
from monkey_island.cc.models.zero_trust.monkey_finding_details import MonkeyFindingDetails
|
||||
|
||||
|
||||
class MonkeyFinding(Finding):
|
||||
details = LazyReferenceField(MonkeyFindingDetails, required=True)
|
||||
|
||||
@staticmethod
|
||||
def save_finding(test: str,
|
||||
status: str,
|
||||
detail_ref: MonkeyFindingDetails) -> Finding:
|
||||
monkey_finding = MonkeyFinding(test=test,
|
||||
status=status,
|
||||
details=detail_ref)
|
||||
monkey_finding.save()
|
||||
return monkey_finding
|
|
@ -0,0 +1,18 @@
|
|||
from mongoengine import LazyReferenceField
|
||||
|
||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||
from monkey_island.cc.models.zero_trust.scoutsuite_finding_details import ScoutSuiteFindingDetails
|
||||
|
||||
|
||||
class ScoutSuiteFinding(Finding):
|
||||
details = LazyReferenceField(ScoutSuiteFindingDetails, required=True)
|
||||
|
||||
@staticmethod
|
||||
def save_finding(test: str,
|
||||
status: str,
|
||||
detail_ref: ScoutSuiteFindingDetails) -> Finding:
|
||||
scoutsuite_finding = ScoutSuiteFinding(test=test,
|
||||
status=status,
|
||||
details=detail_ref)
|
||||
scoutsuite_finding.save()
|
||||
return scoutsuite_finding
|
|
@ -4,29 +4,22 @@ from mongoengine import ValidationError
|
|||
import common.common_consts.zero_trust_consts as zero_trust_consts
|
||||
from monkey_island.cc.models.zero_trust.event import Event
|
||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||
from monkey_island.cc.models.zero_trust.monkey_finding import MonkeyFinding
|
||||
from monkey_island.cc.models.zero_trust.monkey_finding_details import MonkeyFindingDetails
|
||||
from monkey_island.cc.models.zero_trust.scoutsuite_finding_details import ScoutSuiteFindingDetails
|
||||
from monkey_island.cc.test_common.fixtures import FixtureEnum
|
||||
|
||||
MONKEY_FINDING_DETAIL_MOCK = MonkeyFindingDetails()
|
||||
MONKEY_FINDING_DETAIL_MOCK.events = ['mock1', 'mock2']
|
||||
SCOUTSUITE_FINDING_DETAIL_MOCK = ScoutSuiteFindingDetails()
|
||||
SCOUTSUITE_FINDING_DETAIL_MOCK.scoutsuite_rules = []
|
||||
|
||||
|
||||
class TestFinding:
|
||||
class TestMonkeyFinding:
|
||||
|
||||
@pytest.mark.usefixtures(FixtureEnum.USES_DATABASE)
|
||||
def test_save_finding_validation(self):
|
||||
with pytest.raises(ValidationError):
|
||||
_ = Finding.save_finding(test="bla bla",
|
||||
status=zero_trust_consts.STATUS_FAILED,
|
||||
detail_ref=MONKEY_FINDING_DETAIL_MOCK)
|
||||
|
||||
with pytest.raises(ValidationError):
|
||||
_ = Finding.save_finding(test=zero_trust_consts.TEST_SEGMENTATION,
|
||||
status="bla bla",
|
||||
detail_ref=SCOUTSUITE_FINDING_DETAIL_MOCK)
|
||||
_ = MonkeyFinding.save_finding(test="bla bla",
|
||||
status=zero_trust_consts.STATUS_FAILED,
|
||||
detail_ref=MONKEY_FINDING_DETAIL_MOCK)
|
||||
|
||||
@pytest.mark.usefixtures(FixtureEnum.USES_DATABASE)
|
||||
def test_save_finding_sanity(self):
|
||||
|
@ -37,8 +30,10 @@ class TestFinding:
|
|||
monkey_details_example = MonkeyFindingDetails()
|
||||
monkey_details_example.events.append(event_example)
|
||||
monkey_details_example.save()
|
||||
Finding.save_finding(test=zero_trust_consts.TEST_SEGMENTATION,
|
||||
status=zero_trust_consts.STATUS_FAILED, detail_ref=monkey_details_example)
|
||||
MonkeyFinding.save_finding(test=zero_trust_consts.TEST_SEGMENTATION,
|
||||
status=zero_trust_consts.STATUS_FAILED,
|
||||
detail_ref=monkey_details_example)
|
||||
|
||||
assert len(Finding.objects(test=zero_trust_consts.TEST_SEGMENTATION)) == 1
|
||||
assert len(MonkeyFinding.objects(test=zero_trust_consts.TEST_SEGMENTATION)) == 1
|
||||
assert len(MonkeyFinding.objects(status=zero_trust_consts.STATUS_FAILED)) == 1
|
||||
assert len(Finding.objects(status=zero_trust_consts.STATUS_FAILED)) == 1
|
|
@ -0,0 +1,41 @@
|
|||
import pytest
|
||||
from mongoengine import ValidationError
|
||||
|
||||
import common.common_consts.zero_trust_consts as zero_trust_consts
|
||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||
from monkey_island.cc.models.zero_trust.monkey_finding_details import MonkeyFindingDetails
|
||||
from monkey_island.cc.models.zero_trust.scoutsuite_finding import ScoutSuiteFinding
|
||||
from monkey_island.cc.models.zero_trust.scoutsuite_finding_details import ScoutSuiteFindingDetails
|
||||
from monkey_island.cc.services.zero_trust.test_common.scoutsuite_finding_data import RULES
|
||||
from monkey_island.cc.test_common.fixtures import FixtureEnum
|
||||
|
||||
MONKEY_FINDING_DETAIL_MOCK = MonkeyFindingDetails()
|
||||
MONKEY_FINDING_DETAIL_MOCK.events = ['mock1', 'mock2']
|
||||
SCOUTSUITE_FINDING_DETAIL_MOCK = ScoutSuiteFindingDetails()
|
||||
SCOUTSUITE_FINDING_DETAIL_MOCK.scoutsuite_rules = []
|
||||
|
||||
|
||||
class TestScoutSuiteFinding:
|
||||
|
||||
@pytest.mark.usefixtures(FixtureEnum.USES_DATABASE)
|
||||
def test_save_finding_validation(self):
|
||||
with pytest.raises(ValidationError):
|
||||
_ = ScoutSuiteFinding.save_finding(test=zero_trust_consts.TEST_SEGMENTATION,
|
||||
status="bla bla",
|
||||
detail_ref=SCOUTSUITE_FINDING_DETAIL_MOCK)
|
||||
|
||||
@pytest.mark.usefixtures(FixtureEnum.USES_DATABASE)
|
||||
def test_save_finding_sanity(self):
|
||||
assert len(Finding.objects(test=zero_trust_consts.TEST_SEGMENTATION)) == 0
|
||||
|
||||
rule_example = RULES[0]
|
||||
scoutsuite_details_example = ScoutSuiteFindingDetails()
|
||||
scoutsuite_details_example.scoutsuite_rules.append(rule_example)
|
||||
scoutsuite_details_example.save()
|
||||
ScoutSuiteFinding.save_finding(test=zero_trust_consts.TEST_SEGMENTATION,
|
||||
status=zero_trust_consts.STATUS_FAILED,
|
||||
detail_ref=scoutsuite_details_example)
|
||||
|
||||
assert len(ScoutSuiteFinding.objects(test=zero_trust_consts.TEST_SEGMENTATION)) == 1
|
||||
assert len(ScoutSuiteFinding.objects(status=zero_trust_consts.STATUS_FAILED)) == 1
|
||||
assert len(Finding.objects(status=zero_trust_consts.STATUS_FAILED)) == 1
|
|
@ -24,7 +24,7 @@ class ZeroTrustReport(flask_restful.Resource):
|
|||
elif report_data == REPORT_DATA_PRINCIPLES_STATUS:
|
||||
return jsonify(PrincipleService.get_principles_status())
|
||||
elif report_data == REPORT_DATA_FINDINGS:
|
||||
return jsonify(FindingService.get_all_findings())
|
||||
return jsonify(FindingService.get_all_findings_for_ui())
|
||||
elif report_data == REPORT_DATA_SCOUTSUITE:
|
||||
# Raw ScoutSuite data is already solved as json, no need to jsonify
|
||||
return Response(ScoutSuiteRawDataService.get_scoutsuite_data_json(),
|
||||
|
|
|
@ -4,14 +4,14 @@ from bson import ObjectId
|
|||
|
||||
from common.common_consts import zero_trust_consts
|
||||
from monkey_island.cc.models.zero_trust.event import Event
|
||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||
from monkey_island.cc.models.zero_trust.monkey_finding import MonkeyFinding
|
||||
from monkey_island.cc.models.zero_trust.monkey_finding_details import MonkeyFindingDetails
|
||||
|
||||
|
||||
class MonkeyZTFindingService:
|
||||
|
||||
@staticmethod
|
||||
def create_or_add_to_existing(test: str, status: str, events: str):
|
||||
def create_or_add_to_existing(test: str, status: str, events: List[Event]):
|
||||
"""
|
||||
Create a new finding or add the events to an existing one if it's the same (same meaning same status and same
|
||||
test).
|
||||
|
@ -19,7 +19,7 @@ class MonkeyZTFindingService:
|
|||
:raises: Assertion error if this is used when there's more then one finding which fits the query - this is not
|
||||
when this function should be used.
|
||||
"""
|
||||
existing_findings = Finding.objects(test=test, status=status)
|
||||
existing_findings = MonkeyFinding.objects(test=test, status=status)
|
||||
assert (len(existing_findings) < 2), "More than one finding exists for {}:{}".format(test, status)
|
||||
|
||||
if len(existing_findings) == 0:
|
||||
|
@ -33,15 +33,15 @@ class MonkeyZTFindingService:
|
|||
details = MonkeyFindingDetails()
|
||||
details.events = events
|
||||
details.save()
|
||||
Finding.save_finding(test, status, details)
|
||||
MonkeyFinding.save_finding(test, status, details)
|
||||
|
||||
@staticmethod
|
||||
def add_events(finding: Finding, events: List[Event]):
|
||||
def add_events(finding: MonkeyFinding, events: List[Event]):
|
||||
finding.details.fetch().add_events(events).save()
|
||||
|
||||
@staticmethod
|
||||
def get_events_by_finding(finding_id: str) -> List[object]:
|
||||
finding = Finding.objects.get(id=finding_id)
|
||||
finding = MonkeyFinding.objects.get(id=finding_id)
|
||||
pipeline = [{'$match': {'_id': ObjectId(finding.details.id)}},
|
||||
{'$unwind': '$events'},
|
||||
{'$project': {'events': '$events'}},
|
||||
|
|
|
@ -5,6 +5,7 @@ import pytest
|
|||
from common.common_consts import zero_trust_consts
|
||||
from monkey_island.cc.models.zero_trust.event import Event
|
||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||
from monkey_island.cc.models.zero_trust.monkey_finding import MonkeyFinding
|
||||
from monkey_island.cc.services.zero_trust.monkey_findings.monkey_zt_finding_service import MonkeyZTFindingService
|
||||
from monkey_island.cc.test_common.fixtures import FixtureEnum
|
||||
|
||||
|
@ -67,4 +68,4 @@ class TestMonkeyZTFindingService:
|
|||
# Create new finding
|
||||
MonkeyZTFindingService.create_or_add_to_existing(test=TESTS[1], status=STATUS[1], events=[EVENTS[1]])
|
||||
# Assert there was a new finding created, because test and status is different
|
||||
assert len(Finding.objects()) == 2
|
||||
assert len(MonkeyFinding.objects()) == 2
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
from typing import List
|
||||
|
||||
from common.common_consts import zero_trust_consts
|
||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||
from monkey_island.cc.models.zero_trust.scoutsuite_finding import ScoutSuiteFinding
|
||||
from monkey_island.cc.models.zero_trust.scoutsuite_finding_details import ScoutSuiteFindingDetails
|
||||
from monkey_island.cc.models.zero_trust.scoutsuite_rule import ScoutSuiteRule
|
||||
from monkey_island.cc.services.zero_trust.scoutsuite.consts.scoutsuite_findings import ScoutSuiteFinding
|
||||
from monkey_island.cc.services.zero_trust.scoutsuite.consts.scoutsuite_finding_maps import ScoutSuiteFindingMap
|
||||
from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_rule_service import ScoutSuiteRuleService
|
||||
|
||||
|
||||
class ScoutSuiteZTFindingService:
|
||||
|
||||
@staticmethod
|
||||
def process_rule(finding: ScoutSuiteFinding, rule: ScoutSuiteRule):
|
||||
existing_findings = Finding.objects(test=finding.test, finding_type=zero_trust_consts.SCOUTSUITE_FINDING)
|
||||
def process_rule(finding: ScoutSuiteFindingMap, rule: ScoutSuiteRule):
|
||||
existing_findings = ScoutSuiteFinding.objects(test=finding.test)
|
||||
assert (len(existing_findings) < 2), "More than one finding exists for {}".format(finding.test)
|
||||
|
||||
if len(existing_findings) == 0:
|
||||
|
@ -21,12 +21,12 @@ class ScoutSuiteZTFindingService:
|
|||
ScoutSuiteZTFindingService.add_rule(existing_findings[0], rule)
|
||||
|
||||
@staticmethod
|
||||
def _create_new_finding_from_rule(finding: ScoutSuiteFinding, rule: ScoutSuiteRule):
|
||||
def _create_new_finding_from_rule(finding: ScoutSuiteFindingMap, rule: ScoutSuiteRule):
|
||||
details = ScoutSuiteFindingDetails()
|
||||
details.scoutsuite_rules = [rule]
|
||||
details.save()
|
||||
status = ScoutSuiteZTFindingService.get_finding_status_from_rules(details.scoutsuite_rules)
|
||||
Finding.save_finding(finding.test, status, details)
|
||||
ScoutSuiteFinding.save_finding(finding.test, status, details)
|
||||
|
||||
@staticmethod
|
||||
def get_finding_status_from_rules(rules: List[ScoutSuiteRule]) -> str:
|
||||
|
@ -40,13 +40,13 @@ class ScoutSuiteZTFindingService:
|
|||
return zero_trust_consts.STATUS_PASSED
|
||||
|
||||
@staticmethod
|
||||
def add_rule(finding: Finding, rule: ScoutSuiteRule):
|
||||
def add_rule(finding: ScoutSuiteFinding, rule: ScoutSuiteRule):
|
||||
ScoutSuiteZTFindingService.change_finding_status_by_rule(finding, rule)
|
||||
finding.save()
|
||||
finding.details.fetch().add_rule(rule)
|
||||
|
||||
@staticmethod
|
||||
def change_finding_status_by_rule(finding: Finding, rule: ScoutSuiteRule):
|
||||
def change_finding_status_by_rule(finding: ScoutSuiteFinding, rule: ScoutSuiteRule):
|
||||
rule_status = ScoutSuiteZTFindingService.get_finding_status_from_rules([rule])
|
||||
finding_status = finding.status
|
||||
new_finding_status = ScoutSuiteZTFindingService.get_finding_status_from_rule_status(finding_status, rule_status)
|
||||
|
|
|
@ -2,6 +2,7 @@ import pytest
|
|||
|
||||
from common.common_consts import zero_trust_consts
|
||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||
from monkey_island.cc.models.zero_trust.scoutsuite_finding import ScoutSuiteFinding
|
||||
from monkey_island.cc.services.zero_trust.scoutsuite.scoutsuite_zt_finding_service import ScoutSuiteZTFindingService
|
||||
from monkey_island.cc.services.zero_trust.test_common.scoutsuite_finding_data import RULES, SCOUTSUITE_FINDINGS
|
||||
from monkey_island.cc.test_common.fixtures import FixtureEnum
|
||||
|
@ -15,7 +16,7 @@ class TestScoutSuiteZTFindingService:
|
|||
ScoutSuiteZTFindingService.process_rule(SCOUTSUITE_FINDINGS[0], RULES[0])
|
||||
findings = list(Finding.objects())
|
||||
assert len(findings) == 1
|
||||
assert findings[0].finding_type == zero_trust_consts.SCOUTSUITE_FINDING
|
||||
assert type(findings[0]) == ScoutSuiteFinding
|
||||
# Assert that details were created properly
|
||||
details = findings[0].details.fetch()
|
||||
assert len(details.scoutsuite_rules) == 1
|
||||
|
@ -23,9 +24,9 @@ class TestScoutSuiteZTFindingService:
|
|||
|
||||
# Rule processing should add rule to an already existing finding
|
||||
ScoutSuiteZTFindingService.process_rule(SCOUTSUITE_FINDINGS[0], RULES[1])
|
||||
findings = list(Finding.objects())
|
||||
findings = list(ScoutSuiteFinding.objects())
|
||||
assert len(findings) == 1
|
||||
assert findings[0].finding_type == zero_trust_consts.SCOUTSUITE_FINDING
|
||||
assert type(findings[0]) == ScoutSuiteFinding
|
||||
# Assert that details were created properly
|
||||
details = findings[0].details.fetch()
|
||||
assert len(details.scoutsuite_rules) == 2
|
||||
|
@ -35,7 +36,7 @@ class TestScoutSuiteZTFindingService:
|
|||
ScoutSuiteZTFindingService.process_rule(SCOUTSUITE_FINDINGS[1], RULES[1])
|
||||
findings = list(Finding.objects())
|
||||
assert len(findings) == 2
|
||||
assert findings[1].finding_type == zero_trust_consts.SCOUTSUITE_FINDING
|
||||
assert type(findings[0]) == ScoutSuiteFinding
|
||||
# Assert that details were created properly
|
||||
details = findings[1].details.fetch()
|
||||
assert len(details.scoutsuite_rules) == 1
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
from common.common_consts.zero_trust_consts import TEST_SCOUTSUITE_SERVICE_SECURITY, STATUS_FAILED, SCOUTSUITE_FINDING, \
|
||||
TEST_ENDPOINT_SECURITY_EXISTS, STATUS_PASSED, MONKEY_FINDING
|
||||
from common.common_consts.zero_trust_consts import TEST_SCOUTSUITE_SERVICE_SECURITY, STATUS_FAILED, \
|
||||
TEST_ENDPOINT_SECURITY_EXISTS, STATUS_PASSED
|
||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||
from monkey_island.cc.models.zero_trust.monkey_finding import MonkeyFinding
|
||||
from monkey_island.cc.models.zero_trust.scoutsuite_finding import ScoutSuiteFinding
|
||||
from monkey_island.cc.services.zero_trust.test_common.monkey_finding_data import get_monkey_details_dto
|
||||
from monkey_island.cc.services.zero_trust.test_common.scoutsuite_finding_data import get_scoutsuite_details_dto
|
||||
|
||||
|
@ -8,16 +10,14 @@ from monkey_island.cc.services.zero_trust.test_common.scoutsuite_finding_data im
|
|||
def get_scoutsuite_finding_dto() -> Finding:
|
||||
scoutsuite_details = get_scoutsuite_details_dto()
|
||||
scoutsuite_details.save()
|
||||
return Finding(test=TEST_SCOUTSUITE_SERVICE_SECURITY,
|
||||
status=STATUS_FAILED,
|
||||
finding_type=SCOUTSUITE_FINDING,
|
||||
details=scoutsuite_details)
|
||||
return ScoutSuiteFinding(test=TEST_SCOUTSUITE_SERVICE_SECURITY,
|
||||
status=STATUS_FAILED,
|
||||
details=scoutsuite_details)
|
||||
|
||||
|
||||
def get_monkey_finding_dto() -> Finding:
|
||||
monkey_details = get_monkey_details_dto()
|
||||
monkey_details.save()
|
||||
return Finding(test=TEST_ENDPOINT_SECURITY_EXISTS,
|
||||
status=STATUS_PASSED,
|
||||
finding_type=MONKEY_FINDING,
|
||||
details=monkey_details)
|
||||
return MonkeyFinding(test=TEST_ENDPOINT_SECURITY_EXISTS,
|
||||
status=STATUS_PASSED,
|
||||
details=monkey_details)
|
||||
|
|
|
@ -6,6 +6,8 @@ from bson import SON
|
|||
from common.common_consts import zero_trust_consts
|
||||
from common.utils.exceptions import UnknownFindingError
|
||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||
from monkey_island.cc.models.zero_trust.monkey_finding import MonkeyFinding
|
||||
from monkey_island.cc.models.zero_trust.scoutsuite_finding import ScoutSuiteFinding
|
||||
from monkey_island.cc.services.zero_trust.monkey_findings.monkey_zt_details_service import MonkeyZTDetailsService
|
||||
|
||||
|
||||
|
@ -16,15 +18,18 @@ class EnrichedFinding:
|
|||
test_key: str
|
||||
pillars: List[str]
|
||||
status: str
|
||||
finding_type: str
|
||||
details: Union[dict, None]
|
||||
|
||||
|
||||
class FindingService:
|
||||
|
||||
@staticmethod
|
||||
def get_all_findings() -> List[EnrichedFinding]:
|
||||
findings = list(Finding.objects)
|
||||
def get_all_findings_from_db() -> List[Finding]:
|
||||
return list(Finding.objects)
|
||||
|
||||
@staticmethod
|
||||
def get_all_findings_for_ui() -> List[EnrichedFinding]:
|
||||
findings = FindingService.get_all_findings_from_db()
|
||||
for i in range(len(findings)):
|
||||
details = FindingService._get_finding_details(findings[i])
|
||||
findings[i] = findings[i].to_mongo()
|
||||
|
@ -41,16 +46,15 @@ class FindingService:
|
|||
test_key=finding['test'],
|
||||
pillars=test_info[zero_trust_consts.PILLARS_KEY],
|
||||
status=finding['status'],
|
||||
finding_type=finding['finding_type'],
|
||||
details=None
|
||||
)
|
||||
return enriched_finding
|
||||
|
||||
@staticmethod
|
||||
def _get_finding_details(finding: Finding) -> Union[dict, SON]:
|
||||
if finding.finding_type == zero_trust_consts.MONKEY_FINDING:
|
||||
if type(finding) == MonkeyFinding:
|
||||
return MonkeyZTDetailsService.fetch_details_for_display(finding.details.id)
|
||||
elif finding.finding_type == zero_trust_consts.SCOUTSUITE_FINDING:
|
||||
elif type(finding) == ScoutSuiteFinding:
|
||||
return finding.details.fetch().to_mongo()
|
||||
else:
|
||||
raise UnknownFindingError(f"Unknown finding type {finding.finding_type}")
|
||||
raise UnknownFindingError(f"Unknown finding type {str(type(finding))}")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import common.common_consts.zero_trust_consts as zero_trust_consts
|
||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||
from monkey_island.cc.services.zero_trust.zero_trust_report.finding_service import FindingService
|
||||
|
||||
|
||||
class PillarService:
|
||||
|
@ -13,7 +13,7 @@ class PillarService:
|
|||
@staticmethod
|
||||
def _get_pillars_grades():
|
||||
pillars_grades = []
|
||||
all_findings = Finding.objects()
|
||||
all_findings = FindingService.get_all_findings_from_db()
|
||||
for pillar in zero_trust_consts.PILLARS:
|
||||
pillars_grades.append(PillarService.__get_pillar_grade(pillar, all_findings))
|
||||
return pillars_grades
|
||||
|
@ -67,7 +67,7 @@ class PillarService:
|
|||
|
||||
@staticmethod
|
||||
def __get_status_of_single_pillar(pillar):
|
||||
all_findings = Finding.objects()
|
||||
all_findings = FindingService.get_all_findings_from_db()
|
||||
grade = PillarService.__get_pillar_grade(pillar, all_findings)
|
||||
for status in zero_trust_consts.ORDERED_TEST_STATUSES:
|
||||
if grade[status] > 0:
|
||||
|
|
|
@ -3,9 +3,10 @@ from unittest.mock import MagicMock
|
|||
import pytest
|
||||
|
||||
from common.common_consts.zero_trust_consts import TESTS_MAP, TEST_SCOUTSUITE_SERVICE_SECURITY, STATUS_FAILED, \
|
||||
SCOUTSUITE_FINDING, DEVICES, NETWORKS, MONKEY_FINDING, STATUS_PASSED, TEST_ENDPOINT_SECURITY_EXISTS
|
||||
DEVICES, NETWORKS, STATUS_PASSED, TEST_ENDPOINT_SECURITY_EXISTS
|
||||
from monkey_island.cc.services.zero_trust.monkey_findings.monkey_zt_details_service import MonkeyZTDetailsService
|
||||
from monkey_island.cc.services.zero_trust.test_common.finding_data import get_scoutsuite_finding_dto, get_monkey_finding_dto
|
||||
from monkey_island.cc.services.zero_trust.test_common.finding_data import get_scoutsuite_finding_dto, \
|
||||
get_monkey_finding_dto
|
||||
from monkey_island.cc.services.zero_trust.zero_trust_report.finding_service import FindingService, EnrichedFinding
|
||||
from monkey_island.cc.test_common.fixtures.fixture_enum import FixtureEnum
|
||||
|
||||
|
@ -18,11 +19,10 @@ def test_get_all_findings():
|
|||
# This method fails due to mongomock not being able to simulate $unset, so don't test details
|
||||
MonkeyZTDetailsService.fetch_details_for_display = MagicMock(return_value=None)
|
||||
|
||||
findings = FindingService.get_all_findings()
|
||||
findings = FindingService.get_all_findings_for_ui()
|
||||
|
||||
description = TESTS_MAP[TEST_SCOUTSUITE_SERVICE_SECURITY]['finding_explanation'][STATUS_FAILED]
|
||||
expected_finding0 = EnrichedFinding(finding_id=findings[0].finding_id,
|
||||
finding_type=SCOUTSUITE_FINDING,
|
||||
pillars=[DEVICES, NETWORKS],
|
||||
status=STATUS_FAILED,
|
||||
test=description,
|
||||
|
@ -31,7 +31,6 @@ def test_get_all_findings():
|
|||
|
||||
description = TESTS_MAP[TEST_ENDPOINT_SECURITY_EXISTS]['finding_explanation'][STATUS_PASSED]
|
||||
expected_finding1 = EnrichedFinding(finding_id=findings[1].finding_id,
|
||||
finding_type=MONKEY_FINDING,
|
||||
pillars=[DEVICES],
|
||||
status=STATUS_PASSED,
|
||||
test=description,
|
||||
|
|
|
@ -36,10 +36,10 @@ export class FindingsTable extends Component {
|
|||
];
|
||||
|
||||
getFindingDetails(finding) {
|
||||
if (finding.finding_type === 'scoutsuite_finding') {
|
||||
if ('scoutsuite_rules' in finding.details) {
|
||||
return <ScoutSuiteRuleButton scoutsuite_rules={finding.details.scoutsuite_rules}
|
||||
scoutsuite_data={this.props.scoutsuite_data}/>;
|
||||
} else if (finding.finding_type === 'monkey_finding') {
|
||||
} else {
|
||||
return <EventsButton finding_id={finding.finding_id}
|
||||
latest_events={finding.details.latest_events}
|
||||
oldest_events={finding.details.oldest_events}
|
||||
|
|
Loading…
Reference in New Issue