forked from p34709852/monkey
Replaced Conclusive with Failed, and Positive with Passed
This commit is contained in:
parent
04005b14d7
commit
dfebf5e841
|
@ -16,11 +16,11 @@ DATA = u"Data"
|
||||||
PILLARS = (DATA, PEOPLE, NETWORKS, DEVICES, WORKLOADS, VISIBILITY_ANALYTICS, AUTOMATION_ORCHESTRATION)
|
PILLARS = (DATA, PEOPLE, NETWORKS, DEVICES, WORKLOADS, VISIBILITY_ANALYTICS, AUTOMATION_ORCHESTRATION)
|
||||||
|
|
||||||
STATUS_UNEXECUTED = u"Unexecuted"
|
STATUS_UNEXECUTED = u"Unexecuted"
|
||||||
STATUS_POSITIVE = u"Positive"
|
STATUS_PASSED = u"Passed"
|
||||||
STATUS_INCONCLUSIVE = u"Inconclusive"
|
STATUS_INCONCLUSIVE = u"Inconclusive"
|
||||||
STATUS_CONCLUSIVE = u"Conclusive"
|
STATUS_FAILED = u"Failed"
|
||||||
# Don't change order! The statuses are ordered by importance/severity.
|
# Don't change order! The statuses are ordered by importance/severity.
|
||||||
ORDERED_TEST_STATUSES = [STATUS_CONCLUSIVE, STATUS_INCONCLUSIVE, STATUS_POSITIVE, STATUS_UNEXECUTED]
|
ORDERED_TEST_STATUSES = [STATUS_FAILED, STATUS_INCONCLUSIVE, STATUS_PASSED, 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"
|
||||||
|
@ -61,12 +61,12 @@ TESTS_MAP = {
|
||||||
TEST_SEGMENTATION: {
|
TEST_SEGMENTATION: {
|
||||||
TEST_EXPLANATION_KEY: u"The Monkey tried to scan and find machines that it can communicate with from the machine it's running on, that belong to different network segments.",
|
TEST_EXPLANATION_KEY: u"The Monkey tried to scan and find machines that it can communicate with from the machine it's running on, that belong to different network segments.",
|
||||||
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
||||||
STATUS_CONCLUSIVE: "Monkey performed cross-segment communication. Check firewall rules and logs.",
|
STATUS_FAILED: "Monkey performed cross-segment communication. Check firewall rules and logs.",
|
||||||
STATUS_POSITIVE: "Monkey couldn't perform cross-segment communication. If relevant, check firewall logs."
|
STATUS_PASSED: "Monkey couldn't perform cross-segment communication. If relevant, check firewall logs."
|
||||||
},
|
},
|
||||||
RECOMMENDATION_KEY: RECOMMENDATION_SEGMENTATION,
|
RECOMMENDATION_KEY: RECOMMENDATION_SEGMENTATION,
|
||||||
PILLARS_KEY: [NETWORKS],
|
PILLARS_KEY: [NETWORKS],
|
||||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_POSITIVE, STATUS_CONCLUSIVE]
|
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_PASSED, STATUS_FAILED]
|
||||||
},
|
},
|
||||||
TEST_MALICIOUS_ACTIVITY_TIMELINE: {
|
TEST_MALICIOUS_ACTIVITY_TIMELINE: {
|
||||||
TEST_EXPLANATION_KEY: u"The Monkeys in the network performed malicious-looking actions, like scanning and attempting exploitation.",
|
TEST_EXPLANATION_KEY: u"The Monkeys in the network performed malicious-looking actions, like scanning and attempting exploitation.",
|
||||||
|
@ -80,22 +80,22 @@ TESTS_MAP = {
|
||||||
TEST_ENDPOINT_SECURITY_EXISTS: {
|
TEST_ENDPOINT_SECURITY_EXISTS: {
|
||||||
TEST_EXPLANATION_KEY: u"The Monkey checked if there is an active process of an endpoint security software.",
|
TEST_EXPLANATION_KEY: u"The Monkey checked if there is an active process of an endpoint security software.",
|
||||||
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
||||||
STATUS_CONCLUSIVE: "Monkey didn't find ANY active endpoint security processes. Install and activate anti-virus software on endpoints.",
|
STATUS_FAILED: "Monkey didn't find ANY active endpoint security processes. Install and activate anti-virus software on endpoints.",
|
||||||
STATUS_POSITIVE: "Monkey found active endpoint security processes. Check their logs to see if Monkey was a security concern."
|
STATUS_PASSED: "Monkey found active endpoint security processes. Check their logs to see if Monkey was a security concern."
|
||||||
},
|
},
|
||||||
RECOMMENDATION_KEY: RECOMMENDATION_ENDPOINT_SECURITY,
|
RECOMMENDATION_KEY: RECOMMENDATION_ENDPOINT_SECURITY,
|
||||||
PILLARS_KEY: [DEVICES],
|
PILLARS_KEY: [DEVICES],
|
||||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_CONCLUSIVE, STATUS_POSITIVE]
|
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED]
|
||||||
},
|
},
|
||||||
TEST_MACHINE_EXPLOITED: {
|
TEST_MACHINE_EXPLOITED: {
|
||||||
TEST_EXPLANATION_KEY: u"The Monkey tries to exploit machines in order to breach them and propagate in the network.",
|
TEST_EXPLANATION_KEY: u"The Monkey tries to exploit machines in order to breach them and propagate in the network.",
|
||||||
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
||||||
STATUS_CONCLUSIVE: "Monkey successfully exploited endpoints. Check IDS/IPS logs to see activity recognized and see which endpoints were compromised.",
|
STATUS_FAILED: "Monkey successfully exploited endpoints. Check IDS/IPS logs to see activity recognized and see which endpoints were compromised.",
|
||||||
STATUS_POSITIVE: "Monkey didn't manage to exploit an endpoint."
|
STATUS_PASSED: "Monkey didn't manage to exploit an endpoint."
|
||||||
},
|
},
|
||||||
RECOMMENDATION_KEY: RECOMMENDATION_ENDPOINT_SECURITY,
|
RECOMMENDATION_KEY: RECOMMENDATION_ENDPOINT_SECURITY,
|
||||||
PILLARS_KEY: [DEVICES],
|
PILLARS_KEY: [DEVICES],
|
||||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_CONCLUSIVE, STATUS_INCONCLUSIVE]
|
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_INCONCLUSIVE]
|
||||||
},
|
},
|
||||||
TEST_SCHEDULED_EXECUTION: {
|
TEST_SCHEDULED_EXECUTION: {
|
||||||
TEST_EXPLANATION_KEY: "The Monkey was executed in a scheduled manner.",
|
TEST_EXPLANATION_KEY: "The Monkey was executed in a scheduled manner.",
|
||||||
|
@ -109,22 +109,22 @@ TESTS_MAP = {
|
||||||
TEST_DATA_ENDPOINT_ELASTIC: {
|
TEST_DATA_ENDPOINT_ELASTIC: {
|
||||||
TEST_EXPLANATION_KEY: u"The Monkey scanned for unencrypted access to ElasticSearch instances.",
|
TEST_EXPLANATION_KEY: u"The Monkey scanned for unencrypted access to ElasticSearch instances.",
|
||||||
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
||||||
STATUS_CONCLUSIVE: "Monkey accessed ElasticSearch instances. Limit access to data by encrypting it in in-transit.",
|
STATUS_FAILED: "Monkey accessed ElasticSearch instances. Limit access to data by encrypting it in in-transit.",
|
||||||
STATUS_POSITIVE: "Monkey didn't find open ElasticSearch instances. If you have such instances, look for alerts that indicate attempts to access them."
|
STATUS_PASSED: "Monkey didn't find open ElasticSearch instances. If you have such instances, look for alerts that indicate attempts to access them."
|
||||||
},
|
},
|
||||||
RECOMMENDATION_KEY: RECOMMENDATION_DATA_TRANSIT,
|
RECOMMENDATION_KEY: RECOMMENDATION_DATA_TRANSIT,
|
||||||
PILLARS_KEY: [DATA],
|
PILLARS_KEY: [DATA],
|
||||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_CONCLUSIVE, STATUS_POSITIVE]
|
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED]
|
||||||
},
|
},
|
||||||
TEST_DATA_ENDPOINT_HTTP: {
|
TEST_DATA_ENDPOINT_HTTP: {
|
||||||
TEST_EXPLANATION_KEY: u"The Monkey scanned for unencrypted access to HTTP servers.",
|
TEST_EXPLANATION_KEY: u"The Monkey scanned for unencrypted access to HTTP servers.",
|
||||||
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
||||||
STATUS_CONCLUSIVE: "Monkey accessed HTTP servers. Limit access to data by encrypting it in in-transit.",
|
STATUS_FAILED: "Monkey accessed HTTP servers. Limit access to data by encrypting it in in-transit.",
|
||||||
STATUS_POSITIVE: "Monkey didn't find open HTTP servers. If you have such servers, look for alerts that indicate attempts to access them."
|
STATUS_PASSED: "Monkey didn't find open HTTP servers. If you have such servers, look for alerts that indicate attempts to access them."
|
||||||
},
|
},
|
||||||
RECOMMENDATION_KEY: RECOMMENDATION_DATA_TRANSIT,
|
RECOMMENDATION_KEY: RECOMMENDATION_DATA_TRANSIT,
|
||||||
PILLARS_KEY: [DATA],
|
PILLARS_KEY: [DATA],
|
||||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_CONCLUSIVE, STATUS_POSITIVE]
|
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,13 @@ class Finding(Document):
|
||||||
This model represents a Zero-Trust finding: A result of a test the monkey/island might perform to see if a
|
This model represents a Zero-Trust finding: A result of a test the monkey/island might perform to see if a
|
||||||
specific recommendation of zero trust is upheld or broken.
|
specific recommendation of zero trust is upheld or broken.
|
||||||
|
|
||||||
Findings might be
|
Findings might have the following statuses:
|
||||||
Negative ❌
|
Failed ❌
|
||||||
Conclusive, meaning that we are sure that something is wrong (example: segmentation issue).
|
Meaning that we are sure that something is wrong (example: segmentation issue).
|
||||||
Inconclusive, meaning that we need the user to check something himself (example: 2FA logs, AV missing).
|
Inconclusive ⁉
|
||||||
Positive ✔
|
Meaning that we need the user to check something himself (example: 2FA logs, AV missing).
|
||||||
Conclusive, meaning that we are sure that something is correct (example: Monkey failed exploiting).
|
Passed ✔
|
||||||
|
Meaning that we are sure that something is correct (example: Monkey failed exploiting).
|
||||||
|
|
||||||
This class has 2 main section:
|
This class has 2 main section:
|
||||||
* The schema section defines the DB fields in the document. This is the data of the object.
|
* The schema section defines the DB fields in the document. This is the data of the object.
|
||||||
|
|
|
@ -1,30 +1,34 @@
|
||||||
from mongoengine import StringField
|
from mongoengine import StringField
|
||||||
|
|
||||||
from common.data.zero_trust_consts import TEST_SEGMENTATION, STATUS_CONCLUSIVE, STATUS_POSITIVE
|
from common.data.zero_trust_consts import TEST_SEGMENTATION, STATUS_FAILED, STATUS_PASSED
|
||||||
from monkey_island.cc.models.zero_trust.finding import Finding
|
from monkey_island.cc.models.zero_trust.finding import Finding
|
||||||
|
|
||||||
|
|
||||||
def need_to_overwrite_status(saved_status, new_status):
|
def need_to_overwrite_status(saved_status, new_status):
|
||||||
return (saved_status == STATUS_POSITIVE) and (new_status == STATUS_CONCLUSIVE)
|
return (saved_status == STATUS_PASSED) and (new_status == STATUS_FAILED)
|
||||||
|
|
||||||
|
|
||||||
class SegmentationFinding(Finding):
|
class SegmentationFinding(Finding):
|
||||||
"""
|
|
||||||
trying to add conclusive:
|
|
||||||
If the finding doesn't exist at all: create conclusive
|
|
||||||
else:
|
|
||||||
if positive, turn to conclusive
|
|
||||||
add event
|
|
||||||
|
|
||||||
trying to add positive:
|
|
||||||
If the finding doesn't exist at all: create positive
|
|
||||||
else: add event
|
|
||||||
"""
|
|
||||||
first_subnet = StringField()
|
first_subnet = StringField()
|
||||||
second_subnet = StringField()
|
second_subnet = StringField()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_or_add_to_existing_finding(subnets, status, segmentation_event):
|
def create_or_add_to_existing_finding(subnets, status, segmentation_event):
|
||||||
|
"""
|
||||||
|
If you're trying to add a Failed finding:
|
||||||
|
If the finding doesn't exist at all: create failed
|
||||||
|
else:
|
||||||
|
if pass, turn to fail
|
||||||
|
add event
|
||||||
|
|
||||||
|
If you're trying to add a Passed finding:
|
||||||
|
If the finding doesn't exist at all: create Passed
|
||||||
|
else: add event
|
||||||
|
|
||||||
|
:param subnets: the 2 subnets of this finding.
|
||||||
|
:param status: STATUS_PASSED or STATUS_FAILED
|
||||||
|
:param segmentation_event: The specific event
|
||||||
|
"""
|
||||||
assert len(subnets) == 2
|
assert len(subnets) == 2
|
||||||
|
|
||||||
# Sort them so A -> B and B -> A segmentation findings will be the same one.
|
# Sort them so A -> B and B -> A segmentation findings will be the same one.
|
||||||
|
|
|
@ -19,7 +19,7 @@ class TestFinding(IslandTestCase):
|
||||||
self.clean_finding_db()
|
self.clean_finding_db()
|
||||||
|
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
_ = Finding.save_finding(test="bla bla", status=STATUS_CONCLUSIVE, events=[])
|
_ = Finding.save_finding(test="bla bla", status=STATUS_FAILED, events=[])
|
||||||
|
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
_ = Finding.save_finding(test=TEST_SEGMENTATION, status="bla bla", events=[])
|
_ = Finding.save_finding(test=TEST_SEGMENTATION, status="bla bla", events=[])
|
||||||
|
@ -32,7 +32,7 @@ class TestFinding(IslandTestCase):
|
||||||
|
|
||||||
event_example = Event.create_event(
|
event_example = Event.create_event(
|
||||||
title="Event Title", message="event message", event_type=EVENT_TYPE_MONKEY_NETWORK)
|
title="Event Title", message="event message", event_type=EVENT_TYPE_MONKEY_NETWORK)
|
||||||
Finding.save_finding(test=TEST_SEGMENTATION, status=STATUS_CONCLUSIVE, events=[event_example])
|
Finding.save_finding(test=TEST_SEGMENTATION, status=STATUS_FAILED, events=[event_example])
|
||||||
|
|
||||||
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION)), 1)
|
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION)), 1)
|
||||||
self.assertEquals(len(Finding.objects(status=STATUS_CONCLUSIVE)), 1)
|
self.assertEquals(len(Finding.objects(status=STATUS_FAILED)), 1)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from common.data.zero_trust_consts import STATUS_CONCLUSIVE, EVENT_TYPE_MONKEY_NETWORK
|
from common.data.zero_trust_consts import STATUS_FAILED, EVENT_TYPE_MONKEY_NETWORK
|
||||||
from monkey_island.cc.models.zero_trust.event import Event
|
from monkey_island.cc.models.zero_trust.event import Event
|
||||||
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
|
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
|
||||||
from monkey_island.cc.models.zero_trust.segmentation_finding import SegmentationFinding
|
from monkey_island.cc.models.zero_trust.segmentation_finding import SegmentationFinding
|
||||||
|
@ -16,7 +16,7 @@ class TestSegmentationFinding(IslandTestCase):
|
||||||
|
|
||||||
SegmentationFinding.create_or_add_to_existing_finding(
|
SegmentationFinding.create_or_add_to_existing_finding(
|
||||||
subnets=[first_segment, second_segment],
|
subnets=[first_segment, second_segment],
|
||||||
status=STATUS_CONCLUSIVE,
|
status=STATUS_FAILED,
|
||||||
segmentation_event=event
|
segmentation_event=event
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class TestSegmentationFinding(IslandTestCase):
|
||||||
SegmentationFinding.create_or_add_to_existing_finding(
|
SegmentationFinding.create_or_add_to_existing_finding(
|
||||||
# !!! REVERSE ORDER
|
# !!! REVERSE ORDER
|
||||||
subnets=[second_segment, first_segment],
|
subnets=[second_segment, first_segment],
|
||||||
status=STATUS_CONCLUSIVE,
|
status=STATUS_FAILED,
|
||||||
segmentation_event=event
|
segmentation_event=event
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class TestSegmentationFinding(IslandTestCase):
|
||||||
SegmentationFinding.create_or_add_to_existing_finding(
|
SegmentationFinding.create_or_add_to_existing_finding(
|
||||||
# !!! REVERSE ORDER
|
# !!! REVERSE ORDER
|
||||||
subnets=[first_segment, third_segment],
|
subnets=[first_segment, third_segment],
|
||||||
status=STATUS_CONCLUSIVE,
|
status=STATUS_FAILED,
|
||||||
segmentation_event=event
|
segmentation_event=event
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class TestSegmentationFinding(IslandTestCase):
|
||||||
SegmentationFinding.create_or_add_to_existing_finding(
|
SegmentationFinding.create_or_add_to_existing_finding(
|
||||||
# !!! REVERSE ORDER
|
# !!! REVERSE ORDER
|
||||||
subnets=[second_segment, third_segment],
|
subnets=[second_segment, third_segment],
|
||||||
status=STATUS_CONCLUSIVE,
|
status=STATUS_FAILED,
|
||||||
segmentation_event=event
|
segmentation_event=event
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"server_config": "testing",
|
"server_config": "standard",
|
||||||
"deployment": "develop"
|
"deployment": "develop"
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,9 @@ from monkey_island.cc.testing.IslandTestCase import IslandTestCase
|
||||||
|
|
||||||
def save_example_findings():
|
def save_example_findings():
|
||||||
# arrange
|
# arrange
|
||||||
Finding.save_finding(TEST_ENDPOINT_SECURITY_EXISTS, STATUS_POSITIVE, []) # devices positive = 1
|
Finding.save_finding(TEST_ENDPOINT_SECURITY_EXISTS, STATUS_PASSED, []) # devices passed = 1
|
||||||
Finding.save_finding(TEST_ENDPOINT_SECURITY_EXISTS, STATUS_POSITIVE, []) # devices positive = 2
|
Finding.save_finding(TEST_ENDPOINT_SECURITY_EXISTS, STATUS_PASSED, []) # devices passed = 2
|
||||||
Finding.save_finding(TEST_ENDPOINT_SECURITY_EXISTS, STATUS_CONCLUSIVE, []) # devices conclusive = 1
|
Finding.save_finding(TEST_ENDPOINT_SECURITY_EXISTS, STATUS_FAILED, []) # devices failed = 1
|
||||||
# devices unexecuted = 1
|
# devices unexecuted = 1
|
||||||
# people inconclusive = 1
|
# people inconclusive = 1
|
||||||
# networks inconclusive = 1
|
# networks inconclusive = 1
|
||||||
|
@ -17,22 +17,22 @@ def save_example_findings():
|
||||||
# people inconclusive = 2
|
# people inconclusive = 2
|
||||||
# networks inconclusive = 2
|
# networks inconclusive = 2
|
||||||
Finding.save_finding(TEST_SCHEDULED_EXECUTION, STATUS_INCONCLUSIVE, [])
|
Finding.save_finding(TEST_SCHEDULED_EXECUTION, STATUS_INCONCLUSIVE, [])
|
||||||
# data conclusive 1
|
# data failed 1
|
||||||
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_CONCLUSIVE, [])
|
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_FAILED, [])
|
||||||
# data conclusive 2
|
# data failed 2
|
||||||
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_CONCLUSIVE, [])
|
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_FAILED, [])
|
||||||
# data conclusive 3
|
# data failed 3
|
||||||
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_CONCLUSIVE, [])
|
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_FAILED, [])
|
||||||
# data conclusive 4
|
# data failed 4
|
||||||
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_CONCLUSIVE, [])
|
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_FAILED, [])
|
||||||
# data conclusive 5
|
# data failed 5
|
||||||
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_CONCLUSIVE, [])
|
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_FAILED, [])
|
||||||
# data inconclusive 1
|
# data inconclusive 1
|
||||||
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_INCONCLUSIVE, [])
|
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_INCONCLUSIVE, [])
|
||||||
# data inconclusive 2
|
# data inconclusive 2
|
||||||
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_INCONCLUSIVE, [])
|
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_INCONCLUSIVE, [])
|
||||||
# data positive 1
|
# data passed 1
|
||||||
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_POSITIVE, [])
|
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_PASSED, [])
|
||||||
|
|
||||||
|
|
||||||
class TestZeroTrustService(IslandTestCase):
|
class TestZeroTrustService(IslandTestCase):
|
||||||
|
@ -44,52 +44,52 @@ class TestZeroTrustService(IslandTestCase):
|
||||||
|
|
||||||
expected = [
|
expected = [
|
||||||
{
|
{
|
||||||
"Conclusive": 5,
|
STATUS_FAILED: 5,
|
||||||
"Inconclusive": 2,
|
STATUS_INCONCLUSIVE: 2,
|
||||||
"Positive": 1,
|
STATUS_PASSED: 1,
|
||||||
"Unexecuted": 1,
|
STATUS_UNEXECUTED: 1,
|
||||||
"pillar": "Data"
|
"pillar": "Data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Conclusive": 0,
|
STATUS_FAILED: 0,
|
||||||
"Inconclusive": 2,
|
STATUS_INCONCLUSIVE: 2,
|
||||||
"Positive": 0,
|
STATUS_PASSED: 0,
|
||||||
"Unexecuted": 0,
|
STATUS_UNEXECUTED: 0,
|
||||||
"pillar": "People"
|
"pillar": "People"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Conclusive": 0,
|
STATUS_FAILED: 0,
|
||||||
"Inconclusive": 2,
|
STATUS_INCONCLUSIVE: 2,
|
||||||
"Positive": 0,
|
STATUS_PASSED: 0,
|
||||||
"Unexecuted": 2,
|
STATUS_UNEXECUTED: 2,
|
||||||
"pillar": "Networks"
|
"pillar": "Networks"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Conclusive": 1,
|
STATUS_FAILED: 1,
|
||||||
"Inconclusive": 0,
|
STATUS_INCONCLUSIVE: 0,
|
||||||
"Positive": 2,
|
STATUS_PASSED: 2,
|
||||||
"Unexecuted": 1,
|
STATUS_UNEXECUTED: 1,
|
||||||
"pillar": "Devices"
|
"pillar": "Devices"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Conclusive": 0,
|
STATUS_FAILED: 0,
|
||||||
"Inconclusive": 0,
|
STATUS_INCONCLUSIVE: 0,
|
||||||
"Positive": 0,
|
STATUS_PASSED: 0,
|
||||||
"Unexecuted": 0,
|
STATUS_UNEXECUTED: 0,
|
||||||
"pillar": "Workloads"
|
"pillar": "Workloads"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Conclusive": 0,
|
STATUS_FAILED: 0,
|
||||||
"Inconclusive": 0,
|
STATUS_INCONCLUSIVE: 0,
|
||||||
"Positive": 0,
|
STATUS_PASSED: 0,
|
||||||
"Unexecuted": 1,
|
STATUS_UNEXECUTED: 1,
|
||||||
"pillar": "Visibility & Analytics"
|
"pillar": "Visibility & Analytics"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Conclusive": 0,
|
STATUS_FAILED: 0,
|
||||||
"Inconclusive": 0,
|
STATUS_INCONCLUSIVE: 0,
|
||||||
"Positive": 0,
|
STATUS_PASSED: 0,
|
||||||
"Unexecuted": 0,
|
STATUS_UNEXECUTED: 0,
|
||||||
"pillar": "Automation & Orchestration"
|
"pillar": "Automation & Orchestration"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -109,14 +109,14 @@ class TestZeroTrustService(IslandTestCase):
|
||||||
DATA: [
|
DATA: [
|
||||||
{
|
{
|
||||||
"recommendation": RECOMMENDATIONS[RECOMMENDATION_DATA_TRANSIT],
|
"recommendation": RECOMMENDATIONS[RECOMMENDATION_DATA_TRANSIT],
|
||||||
"status": STATUS_CONCLUSIVE,
|
"status": STATUS_FAILED,
|
||||||
"tests": [
|
"tests": [
|
||||||
{
|
{
|
||||||
"status": STATUS_UNEXECUTED,
|
"status": STATUS_UNEXECUTED,
|
||||||
"test": TESTS_MAP[TEST_DATA_ENDPOINT_ELASTIC][TEST_EXPLANATION_KEY]
|
"test": TESTS_MAP[TEST_DATA_ENDPOINT_ELASTIC][TEST_EXPLANATION_KEY]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"status": STATUS_CONCLUSIVE,
|
"status": STATUS_FAILED,
|
||||||
"test": TESTS_MAP[TEST_DATA_ENDPOINT_HTTP][TEST_EXPLANATION_KEY]
|
"test": TESTS_MAP[TEST_DATA_ENDPOINT_HTTP][TEST_EXPLANATION_KEY]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -125,10 +125,10 @@ class TestZeroTrustService(IslandTestCase):
|
||||||
DEVICES: [
|
DEVICES: [
|
||||||
{
|
{
|
||||||
"recommendation": RECOMMENDATIONS[RECOMMENDATION_ENDPOINT_SECURITY],
|
"recommendation": RECOMMENDATIONS[RECOMMENDATION_ENDPOINT_SECURITY],
|
||||||
"status": STATUS_CONCLUSIVE,
|
"status": STATUS_FAILED,
|
||||||
"tests": [
|
"tests": [
|
||||||
{
|
{
|
||||||
"status": STATUS_CONCLUSIVE,
|
"status": STATUS_FAILED,
|
||||||
"test": TESTS_MAP[TEST_ENDPOINT_SECURITY_EXISTS][TEST_EXPLANATION_KEY]
|
"test": TESTS_MAP[TEST_ENDPOINT_SECURITY_EXISTS][TEST_EXPLANATION_KEY]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -221,12 +221,12 @@ class TestZeroTrustService(IslandTestCase):
|
||||||
|
|
||||||
expected = {
|
expected = {
|
||||||
AUTOMATION_ORCHESTRATION: STATUS_UNEXECUTED,
|
AUTOMATION_ORCHESTRATION: STATUS_UNEXECUTED,
|
||||||
DEVICES: STATUS_CONCLUSIVE,
|
DEVICES: STATUS_FAILED,
|
||||||
NETWORKS: STATUS_INCONCLUSIVE,
|
NETWORKS: STATUS_INCONCLUSIVE,
|
||||||
PEOPLE: STATUS_INCONCLUSIVE,
|
PEOPLE: STATUS_INCONCLUSIVE,
|
||||||
VISIBILITY_ANALYTICS: STATUS_UNEXECUTED,
|
VISIBILITY_ANALYTICS: STATUS_UNEXECUTED,
|
||||||
WORKLOADS: STATUS_UNEXECUTED,
|
WORKLOADS: STATUS_UNEXECUTED,
|
||||||
DATA: STATUS_CONCLUSIVE
|
DATA: STATUS_FAILED
|
||||||
}
|
}
|
||||||
|
|
||||||
self.assertEquals(ZeroTrustService.get_pillars_to_statuses(), expected)
|
self.assertEquals(ZeroTrustService.get_pillars_to_statuses(), expected)
|
||||||
|
|
|
@ -16,9 +16,9 @@ class ZeroTrustService(object):
|
||||||
all_findings = Finding.objects()
|
all_findings = Finding.objects()
|
||||||
pillar_grade = {
|
pillar_grade = {
|
||||||
"pillar": pillar,
|
"pillar": pillar,
|
||||||
STATUS_CONCLUSIVE: 0,
|
STATUS_FAILED: 0,
|
||||||
STATUS_INCONCLUSIVE: 0,
|
STATUS_INCONCLUSIVE: 0,
|
||||||
STATUS_POSITIVE: 0,
|
STATUS_PASSED: 0,
|
||||||
STATUS_UNEXECUTED: 0
|
STATUS_UNEXECUTED: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,9 +123,9 @@ class ZeroTrustService(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_statuses_to_pillars():
|
def get_statuses_to_pillars():
|
||||||
results = {
|
results = {
|
||||||
STATUS_CONCLUSIVE: [],
|
STATUS_FAILED: [],
|
||||||
STATUS_INCONCLUSIVE: [],
|
STATUS_INCONCLUSIVE: [],
|
||||||
STATUS_POSITIVE: [],
|
STATUS_PASSED: [],
|
||||||
STATUS_UNEXECUTED: []
|
STATUS_UNEXECUTED: []
|
||||||
}
|
}
|
||||||
for pillar in PILLARS:
|
for pillar in PILLARS:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from monkey_island.cc.services.node import NodeService
|
from monkey_island.cc.services.node import NodeService
|
||||||
from monkey_island.cc.services.telemetry.zero_trust_tests.segmentation import \
|
from monkey_island.cc.services.telemetry.zero_trust_tests.segmentation import \
|
||||||
test_positive_findings_for_unreached_segments
|
test_passed_findings_for_unreached_segments
|
||||||
|
|
||||||
|
|
||||||
def process_state_telemetry(telemetry_json):
|
def process_state_telemetry(telemetry_json):
|
||||||
|
@ -12,4 +12,4 @@ def process_state_telemetry(telemetry_json):
|
||||||
NodeService.set_monkey_dead(monkey, False)
|
NodeService.set_monkey_dead(monkey, False)
|
||||||
|
|
||||||
if telemetry_json['data']['done']:
|
if telemetry_json['data']['done']:
|
||||||
test_positive_findings_for_unreached_segments(telemetry_json)
|
test_passed_findings_for_unreached_segments(telemetry_json)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from common.data.zero_trust_consts import EVENT_TYPE_MONKEY_LOCAL, EVENT_TYPE_ISLAND, \
|
from common.data.zero_trust_consts import EVENT_TYPE_MONKEY_LOCAL, EVENT_TYPE_ISLAND, \
|
||||||
STATUS_POSITIVE, STATUS_CONCLUSIVE, TEST_ENDPOINT_SECURITY_EXISTS
|
STATUS_PASSED, STATUS_FAILED, TEST_ENDPOINT_SECURITY_EXISTS
|
||||||
from monkey_island.cc.models import Monkey
|
from monkey_island.cc.models import Monkey
|
||||||
from monkey_island.cc.models.zero_trust.event import Event
|
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.finding import Finding
|
||||||
|
@ -28,9 +28,9 @@ def test_antivirus_existence(telemetry_json):
|
||||||
))
|
))
|
||||||
|
|
||||||
if len(av_processes) > 0:
|
if len(av_processes) > 0:
|
||||||
test_status = STATUS_POSITIVE
|
test_status = STATUS_PASSED
|
||||||
else:
|
else:
|
||||||
test_status = STATUS_CONCLUSIVE
|
test_status = STATUS_FAILED
|
||||||
Finding.save_finding(test=TEST_ENDPOINT_SECURITY_EXISTS, status=test_status, events=events)
|
Finding.save_finding(test=TEST_ENDPOINT_SECURITY_EXISTS, status=test_status, events=events)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ HTTP_SERVERS_SERVICES_NAMES = ['tcp-80']
|
||||||
def test_open_data_endpoints(telemetry_json):
|
def test_open_data_endpoints(telemetry_json):
|
||||||
services = telemetry_json["data"]["machine"]["services"]
|
services = telemetry_json["data"]["machine"]["services"]
|
||||||
current_monkey = Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid'])
|
current_monkey = Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid'])
|
||||||
found_http_server_status = STATUS_POSITIVE
|
found_http_server_status = STATUS_PASSED
|
||||||
found_elastic_search_server = STATUS_POSITIVE
|
found_elastic_search_server = STATUS_PASSED
|
||||||
|
|
||||||
events = [
|
events = [
|
||||||
Event.create_event(
|
Event.create_event(
|
||||||
|
@ -32,7 +32,7 @@ def test_open_data_endpoints(telemetry_json):
|
||||||
event_type=EVENT_TYPE_ISLAND
|
event_type=EVENT_TYPE_ISLAND
|
||||||
))
|
))
|
||||||
if service_name in HTTP_SERVERS_SERVICES_NAMES:
|
if service_name in HTTP_SERVERS_SERVICES_NAMES:
|
||||||
found_http_server_status = STATUS_CONCLUSIVE
|
found_http_server_status = STATUS_FAILED
|
||||||
events.append(Event.create_event(
|
events.append(Event.create_event(
|
||||||
title="Scan telemetry analysis",
|
title="Scan telemetry analysis",
|
||||||
message="Service {} on {} recognized as an open data endpoint! Service details: {}".format(
|
message="Service {} on {} recognized as an open data endpoint! Service details: {}".format(
|
||||||
|
@ -43,7 +43,7 @@ def test_open_data_endpoints(telemetry_json):
|
||||||
event_type=EVENT_TYPE_ISLAND
|
event_type=EVENT_TYPE_ISLAND
|
||||||
))
|
))
|
||||||
if service_name in 'elastic-search-9200':
|
if service_name in 'elastic-search-9200':
|
||||||
found_elastic_search_server = STATUS_CONCLUSIVE
|
found_elastic_search_server = STATUS_FAILED
|
||||||
events.append(Event.create_event(
|
events.append(Event.create_event(
|
||||||
title="Scan telemetry analysis",
|
title="Scan telemetry analysis",
|
||||||
message="Service {} on {} recognized as an open data endpoint! Service details: {}".format(
|
message="Service {} on {} recognized as an open data endpoint! Service details: {}".format(
|
||||||
|
|
|
@ -18,7 +18,7 @@ def test_machine_exploited(telemetry_json):
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
status = STATUS_POSITIVE
|
status = STATUS_PASSED
|
||||||
|
|
||||||
if telemetry_json['data']['result']:
|
if telemetry_json['data']['result']:
|
||||||
events.append(
|
events.append(
|
||||||
|
@ -31,7 +31,7 @@ def test_machine_exploited(telemetry_json):
|
||||||
event_type=EVENT_TYPE_MONKEY_NETWORK,
|
event_type=EVENT_TYPE_MONKEY_NETWORK,
|
||||||
timestamp=telemetry_json['timestamp'])
|
timestamp=telemetry_json['timestamp'])
|
||||||
)
|
)
|
||||||
status = STATUS_CONCLUSIVE
|
status = STATUS_FAILED
|
||||||
|
|
||||||
Finding.save_finding(
|
Finding.save_finding(
|
||||||
test=TEST_MACHINE_EXPLOITED,
|
test=TEST_MACHINE_EXPLOITED,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import itertools
|
import itertools
|
||||||
from six import text_type
|
from six import text_type
|
||||||
|
|
||||||
from common.data.zero_trust_consts import STATUS_CONCLUSIVE, EVENT_TYPE_MONKEY_NETWORK, STATUS_POSITIVE, \
|
from common.data.zero_trust_consts import STATUS_FAILED, EVENT_TYPE_MONKEY_NETWORK, STATUS_PASSED, \
|
||||||
EVENT_TYPE_ISLAND
|
EVENT_TYPE_ISLAND
|
||||||
from common.network.network_range import NetworkRange
|
from common.network.network_range import NetworkRange
|
||||||
from common.network.segmentation_utils import get_ip_in_src_and_not_in_dst, get_ip_if_in_subnet
|
from common.network.segmentation_utils import get_ip_in_src_and_not_in_dst, get_ip_if_in_subnet
|
||||||
|
@ -45,7 +45,7 @@ def test_segmentation_violation(scan_telemetry_json):
|
||||||
event = get_segmentation_violation_event(current_monkey, source_subnet, target_ip, target_subnet)
|
event = get_segmentation_violation_event(current_monkey, source_subnet, target_ip, target_subnet)
|
||||||
SegmentationFinding.create_or_add_to_existing_finding(
|
SegmentationFinding.create_or_add_to_existing_finding(
|
||||||
subnets=[source_subnet, target_subnet],
|
subnets=[source_subnet, target_subnet],
|
||||||
status=STATUS_CONCLUSIVE,
|
status=STATUS_FAILED,
|
||||||
segmentation_event=event
|
segmentation_event=event
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ def get_segmentation_violation_event(current_monkey, source_subnet, target_ip, t
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_positive_findings_for_unreached_segments(state_telemetry_json):
|
def test_passed_findings_for_unreached_segments(state_telemetry_json):
|
||||||
flat_all_subnets = [item for sublist in get_config_network_segments_as_subnet_groups() for item in sublist]
|
flat_all_subnets = [item for sublist in get_config_network_segments_as_subnet_groups() for item in sublist]
|
||||||
current_monkey = Monkey.get_single_monkey_by_guid(state_telemetry_json['monkey_guid'])
|
current_monkey = Monkey.get_single_monkey_by_guid(state_telemetry_json['monkey_guid'])
|
||||||
create_or_add_findings_for_all_pairs(flat_all_subnets, current_monkey)
|
create_or_add_findings_for_all_pairs(flat_all_subnets, current_monkey)
|
||||||
|
@ -87,7 +87,7 @@ def create_or_add_findings_for_all_pairs(all_subnets, current_monkey):
|
||||||
for subnet_pair in all_subnets_pairs_for_this_monkey:
|
for subnet_pair in all_subnets_pairs_for_this_monkey:
|
||||||
SegmentationFinding.create_or_add_to_existing_finding(
|
SegmentationFinding.create_or_add_to_existing_finding(
|
||||||
subnets=list(subnet_pair),
|
subnets=list(subnet_pair),
|
||||||
status=STATUS_POSITIVE,
|
status=STATUS_PASSED,
|
||||||
segmentation_event=Event.create_event(
|
segmentation_event=Event.create_event(
|
||||||
"Segmentation test done",
|
"Segmentation test done",
|
||||||
message="Monkey on {hostname} is done attempting cross-segment communications from `{src_seg}` "
|
message="Monkey on {hostname} is done attempting cross-segment communications from `{src_seg}` "
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from common.data.zero_trust_consts import TEST_SEGMENTATION, STATUS_POSITIVE, STATUS_CONCLUSIVE, \
|
from common.data.zero_trust_consts import TEST_SEGMENTATION, STATUS_PASSED, STATUS_FAILED, \
|
||||||
EVENT_TYPE_MONKEY_NETWORK
|
EVENT_TYPE_MONKEY_NETWORK
|
||||||
from monkey_island.cc.models import Monkey
|
from monkey_island.cc.models import Monkey
|
||||||
from monkey_island.cc.models.zero_trust.event import Event
|
from monkey_island.cc.models.zero_trust.event import Event
|
||||||
|
@ -32,20 +32,15 @@ class TestSegmentationTests(IslandTestCase):
|
||||||
create_or_add_findings_for_all_pairs(all_subnets, monkey)
|
create_or_add_findings_for_all_pairs(all_subnets, monkey)
|
||||||
|
|
||||||
# There are 2 subnets in which the monkey is NOT
|
# There are 2 subnets in which the monkey is NOT
|
||||||
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION, status=STATUS_POSITIVE)), 2)
|
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION, status=STATUS_PASSED)), 2)
|
||||||
|
|
||||||
# This is a monkey from 2nd subnet communicated with 1st subnet.
|
# This is a monkey from 2nd subnet communicated with 1st subnet.
|
||||||
SegmentationFinding.create_or_add_to_existing_finding(
|
SegmentationFinding.create_or_add_to_existing_finding(
|
||||||
[FIRST_SUBNET, SECOND_SUBNET],
|
[FIRST_SUBNET, SECOND_SUBNET],
|
||||||
STATUS_CONCLUSIVE,
|
STATUS_FAILED,
|
||||||
Event.create_event(title="sdf", message="asd", event_type=EVENT_TYPE_MONKEY_NETWORK)
|
Event.create_event(title="sdf", message="asd", event_type=EVENT_TYPE_MONKEY_NETWORK)
|
||||||
)
|
)
|
||||||
|
|
||||||
print("Printing all segmentation findings")
|
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION, status=STATUS_PASSED)), 1)
|
||||||
all_findings = Finding.objects(test=TEST_SEGMENTATION)
|
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION, status=STATUS_FAILED)), 1)
|
||||||
for f in all_findings:
|
|
||||||
print(f.to_json())
|
|
||||||
|
|
||||||
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION, status=STATUS_POSITIVE)), 1)
|
|
||||||
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION, status=STATUS_CONCLUSIVE)), 1)
|
|
||||||
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION)), 2)
|
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION)), 2)
|
||||||
|
|
|
@ -12,6 +12,7 @@ import StatusesToPillarsSummary from "../report-components/zerotrust/StatusesToP
|
||||||
import PrintReportButton from "../report-components/common/PrintReportButton";
|
import PrintReportButton from "../report-components/common/PrintReportButton";
|
||||||
import {extractExecutionStatusFromServerResponse} from "../report-components/common/ExecutionStatus";
|
import {extractExecutionStatusFromServerResponse} from "../report-components/common/ExecutionStatus";
|
||||||
import ZeroTrustReportLegend from "../report-components/zerotrust/ReportLegend";
|
import ZeroTrustReportLegend from "../report-components/zerotrust/ReportLegend";
|
||||||
|
import {ZeroTrustStatuses} from "../report-components/zerotrust/ZeroTrustPillars";
|
||||||
|
|
||||||
class ZeroTrustReportPageComponent extends AuthComponent {
|
class ZeroTrustReportPageComponent extends AuthComponent {
|
||||||
|
|
||||||
|
@ -179,14 +180,6 @@ class ZeroTrustReportPageComponent extends AuthComponent {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
anyIssuesFound() {
|
|
||||||
const severe = function(finding) {
|
|
||||||
return (finding.status === "Conclusive" || finding.status === "Inconclusive");
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.state.findings.some(severe);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ZeroTrustReportPageComponent;
|
export default ZeroTrustReportPageComponent;
|
||||||
|
|
|
@ -1,27 +1,11 @@
|
||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import PillarLabel from "./PillarLabel";
|
|
||||||
import * as PropTypes from "prop-types";
|
import * as PropTypes from "prop-types";
|
||||||
import ResponsiveVennDiagram from "./venn-components/ResponsiveVennDiagram";
|
import ResponsiveVennDiagram from "./venn-components/ResponsiveVennDiagram";
|
||||||
|
|
||||||
const columns = [
|
|
||||||
{
|
|
||||||
Header: 'Pillar Grading',
|
|
||||||
columns: [
|
|
||||||
{ Header: 'Pillar', id: 'Pillar', accessor: x => {
|
|
||||||
return (<PillarLabel pillar={x.pillar.name} status={x.pillar.status} />);
|
|
||||||
}},
|
|
||||||
{ Header: 'Conclusive', accessor: 'Conclusive'},
|
|
||||||
{ Header: 'Inconclusive', accessor: 'Inconclusive'},
|
|
||||||
{ Header: 'Unexecuted', accessor: 'Unexecuted'},
|
|
||||||
{ Header: 'Positive', accessor: 'Positive'},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
class PillarOverview extends Component {
|
class PillarOverview extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (<div id={this.constructor.name}>
|
return (<div id={this.constructor.name}>
|
||||||
<ResponsiveVennDiagram pillarsGrades={this.props.grades} />
|
<ResponsiveVennDiagram pillarsGrades={this.props.grades}/>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import AuthComponent from "../../AuthComponent";
|
||||||
import 'styles/ZeroTrustPillars.css'
|
import 'styles/ZeroTrustPillars.css'
|
||||||
import StatusLabel from "./StatusLabel";
|
import StatusLabel from "./StatusLabel";
|
||||||
import * as PropTypes from "prop-types";
|
import * as PropTypes from "prop-types";
|
||||||
|
import {ZeroTrustStatuses} from "./ZeroTrustPillars";
|
||||||
|
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
|
@ -30,17 +31,12 @@ const columns = [
|
||||||
|
|
||||||
class TestsStatus extends AuthComponent {
|
class TestsStatus extends AuthComponent {
|
||||||
render() {
|
render() {
|
||||||
const positiveStatus = "Positive";
|
|
||||||
const conclusiveStatus = "Conclusive";
|
|
||||||
const inconclusiveStatus = "Inconclusive";
|
|
||||||
const unexecutedStatus = "Unexecuted";
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{this.getFilteredTestsByStatusIfAny(conclusiveStatus)}
|
{this.getFilteredTestsByStatusIfAny(ZeroTrustStatuses.failed)}
|
||||||
{this.getFilteredTestsByStatusIfAny(inconclusiveStatus)}
|
{this.getFilteredTestsByStatusIfAny(ZeroTrustStatuses.inconclusive)}
|
||||||
{this.getFilteredTestsByStatusIfAny(positiveStatus)}
|
{this.getFilteredTestsByStatusIfAny(ZeroTrustStatuses.passed)}
|
||||||
{this.getFilteredTestsByStatusIfAny(unexecutedStatus)}
|
{this.getFilteredTestsByStatusIfAny(ZeroTrustStatuses.unexecuted)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ class ZeroTrustReportLegend extends Component {
|
||||||
<ul style={{listStyle: "none"}}>
|
<ul style={{listStyle: "none"}}>
|
||||||
<li>
|
<li>
|
||||||
<div style={{display: "inline-block"}}>
|
<div style={{display: "inline-block"}}>
|
||||||
<StatusLabel showText={true} status={ZeroTrustStatuses.conclusive}/>
|
<StatusLabel showText={true} status={ZeroTrustStatuses.failed}/>
|
||||||
</div>
|
</div>
|
||||||
{"\t"}The test failed; the monkeys found something wrong.
|
{"\t"}The test failed; the monkeys found something wrong.
|
||||||
</li>
|
</li>
|
||||||
|
@ -50,7 +50,7 @@ class ZeroTrustReportLegend extends Component {
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div style={{display: "inline-block"}}>
|
<div style={{display: "inline-block"}}>
|
||||||
<StatusLabel showText={true} status={ZeroTrustStatuses.positive}/>
|
<StatusLabel showText={true} status={ZeroTrustStatuses.passed}/>
|
||||||
</div>
|
</div>
|
||||||
{"\t"}This status means the test passed 🙂
|
{"\t"}This status means the test passed 🙂
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -2,16 +2,16 @@ import React, {Component} from "react";
|
||||||
import * as PropTypes from "prop-types";
|
import * as PropTypes from "prop-types";
|
||||||
|
|
||||||
const statusToIcon = {
|
const statusToIcon = {
|
||||||
"Positive": "fa-check",
|
"Passed": "fa-check",
|
||||||
"Inconclusive": "fa-exclamation-triangle",
|
"Inconclusive": "fa-exclamation-triangle",
|
||||||
"Conclusive": "fa-bomb",
|
"Failed": "fa-bomb",
|
||||||
"Unexecuted": "fa-question",
|
"Unexecuted": "fa-question",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const statusToLabelType = {
|
export const statusToLabelType = {
|
||||||
"Positive": "label-success",
|
"Passed": "label-success",
|
||||||
"Inconclusive": "label-warning",
|
"Inconclusive": "label-warning",
|
||||||
"Conclusive": "label-danger",
|
"Failed": "label-danger",
|
||||||
"Unexecuted": "label-default",
|
"Unexecuted": "label-default",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,15 @@ import React, {Component, Fragment} from "react";
|
||||||
import PillarLabel from "./PillarLabel";
|
import PillarLabel from "./PillarLabel";
|
||||||
import StatusLabel from "./StatusLabel";
|
import StatusLabel from "./StatusLabel";
|
||||||
import * as PropTypes from "prop-types";
|
import * as PropTypes from "prop-types";
|
||||||
|
import {ZeroTrustStatuses} from "./ZeroTrustPillars";
|
||||||
|
|
||||||
export default class StatusesToPillarsSummary extends Component {
|
export default class StatusesToPillarsSummary extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (<div id="piilar-summary">
|
return (<div id="piilar-summary">
|
||||||
{this.getStatusSummary("Conclusive")}
|
{this.getStatusSummary(ZeroTrustStatuses.failed)}
|
||||||
{this.getStatusSummary("Inconclusive")}
|
{this.getStatusSummary(ZeroTrustStatuses.inconclusive)}
|
||||||
{this.getStatusSummary("Positive")}
|
{this.getStatusSummary(ZeroTrustStatuses.passed)}
|
||||||
{this.getStatusSummary("Unexecuted")}
|
{this.getStatusSummary(ZeroTrustStatuses.unexecuted)}
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ export const ZeroTrustPillars = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ZeroTrustStatuses = {
|
export const ZeroTrustStatuses = {
|
||||||
conclusive: "Conclusive",
|
failed: "Failed",
|
||||||
inconclusive: "Inconclusive",
|
inconclusive: "Inconclusive",
|
||||||
positive: "Positive",
|
passed: "Passed",
|
||||||
unexecuted: "Unexecuted"
|
unexecuted: "Unexecuted"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import CircularNode from './CircularNode'
|
||||||
import ArcNode from './ArcNode'
|
import ArcNode from './ArcNode'
|
||||||
import {TypographicUtilities} from './Utility.js'
|
import {TypographicUtilities} from './Utility.js'
|
||||||
import './VennDiagram.css'
|
import './VennDiagram.css'
|
||||||
|
import {ZeroTrustStatuses} from "../ZeroTrustPillars";
|
||||||
|
|
||||||
class VennDiagram extends React.Component {
|
class VennDiagram extends React.Component {
|
||||||
constructor(props_) {
|
constructor(props_) {
|
||||||
|
@ -14,7 +15,7 @@ class VennDiagram extends React.Component {
|
||||||
this.width = this.height = 512;
|
this.width = this.height = 512;
|
||||||
|
|
||||||
this.prefix = 'vennDiagram';
|
this.prefix = 'vennDiagram';
|
||||||
this.suffices = ['', '|tests are|conclusive', '|tests were|inconclusive', '|tests|performed'];
|
this.suffices = ['', '|tests are|failed', '|tests were|inconclusive', '|tests|performed'];
|
||||||
this.fontStyles = [{size: Math.max(9, this.width / 32), color: 'white'}, {
|
this.fontStyles = [{size: Math.max(9, this.width / 32), color: 'white'}, {
|
||||||
size: Math.max(6, this.width / 52),
|
size: Math.max(6, this.width / 52),
|
||||||
color: 'black'
|
color: 'black'
|
||||||
|
@ -65,23 +66,23 @@ class VennDiagram extends React.Component {
|
||||||
this.rules = [
|
this.rules = [
|
||||||
|
|
||||||
{
|
{
|
||||||
id: 'Rule #1', status: 'Unexecuted', hex: '#777777', f: function (d_) {
|
id: 'Rule #1', status: ZeroTrustStatuses.unexecuted, hex: '#777777', f: function (d_) {
|
||||||
return d_['Conclusive'] + d_['Inconclusive'] + d_['Positive'] === 0;
|
return d_[ZeroTrustStatuses.failed] + d_[ZeroTrustStatuses.inconclusive] + d_[ZeroTrustStatuses.passed] === 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'Rule #2', status: 'Conclusive', hex: '#D9534F', f: function (d_) {
|
id: 'Rule #2', status: ZeroTrustStatuses.failed, hex: '#D9534F', f: function (d_) {
|
||||||
return d_['Conclusive'] > 0;
|
return d_[ZeroTrustStatuses.failed] > 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'Rule #3', status: 'Inconclusive', hex: '#F0AD4E', f: function (d_) {
|
id: 'Rule #3', status: 'Inconclusive', hex: '#F0AD4E', f: function (d_) {
|
||||||
return d_['Conclusive'] === 0 && d_['Inconclusive'] > 0;
|
return d_[ZeroTrustStatuses.failed] === 0 && d_['Inconclusive'] > 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'Rule #4', status: 'Positive', hex: '#5CB85C', f: function (d_) {
|
id: 'Rule #4', status: ZeroTrustStatuses.passed, hex: '#5CB85C', f: function (d_) {
|
||||||
return d_['Positive'] + d_['Unexecuted'] >= 2 && d_['Positive'] * d_['Unexecuted'] > 0;
|
return d_[ZeroTrustStatuses.passed] + d_[ZeroTrustStatuses.unexecuted] >= 2 && d_[ZeroTrustStatuses.passed] * d_[ZeroTrustStatuses.unexecuted] > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue