Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature/OPT-1029] to dev #333

Merged
merged 3 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions slp_drawio/slp_drawio/objects/diagram_objects.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
from otm.otm.entity import representation
from typing import List

from otm.otm.entity import representation
from otm.otm.entity.component import Component
from otm.otm.entity.dataflow import Dataflow
from otm.otm.entity.parent_type import ParentType
from otm.otm.entity.representation import RepresentationType
from otm.otm.entity.representation import RepresentationType, RepresentationElement
from otm.otm.entity.trustzone import Trustzone


class DiagramTrustZone:
def __init__(self, type: str, id: str = None, name: str = None, default: bool = False):
self.otm: Trustzone = Trustzone(trustzone_id=id, name=name or '', type=type)
def __init__(self, type_: str, id_: str = None, name: str = None, default: bool = False, shape_parent_id=None):
self.otm: Trustzone = Trustzone(trustzone_id=id_, name=name or '', type=type_)
self.default = default
self.shape_parent_id = shape_parent_id


class DiagramComponent:

def __init__(self,
id: str = None,
name: str = None):
name: str = None,
shape_type: str = None,
shape_parent_id: str = None,
representations: List[RepresentationElement] = None
):
self.otm: Component = Component(component_id=id,
name=name or '',
component_type=None,
parent_type=ParentType.TRUST_ZONE,
parent=None)
representations=representations,
)
self.shape_type = shape_type
self.shape_parent_id = shape_parent_id

def __str__(self) -> str:
return '{otm: ' + str(self.otm) + '}'
Expand Down
2 changes: 2 additions & 0 deletions slp_drawio/slp_drawio/parse/drawio_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from slp_drawio.slp_drawio.load.drawio_mapping_file_loader import DrawioMapping
from slp_drawio.slp_drawio.objects.diagram_objects import Diagram
from slp_drawio.slp_drawio.parse.diagram_mapper import DiagramMapper
from slp_drawio.slp_drawio.parse.tranformers.parent_calculator_transformer import ParentCalculatorTransformer


class DrawioParser(ProviderParser):
Expand All @@ -23,6 +24,7 @@ def build_otm(self) -> OTM:
self.map_components_and_trustzones()

# TODO Implement and call Transformers here
ParentCalculatorTransformer(self.diagram).transform()

otm = self.__build_otm()

Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from typing import Optional

from otm.otm.entity.parent_type import ParentType
from slp_drawio.slp_drawio.objects.diagram_objects import DiagramComponent, DiagramTrustZone
from slp_drawio.slp_drawio.parse.transformer.transformer import Transformer

PARENT_TYPES = {
DiagramComponent: ParentType.COMPONENT,
DiagramTrustZone: ParentType.TRUST_ZONE
}


def get_parent_type(element) -> Optional[ParentType]:
try:
return PARENT_TYPES[element.__class__]
except KeyError:
return None


class ParentCalculatorTransformer(Transformer):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parent calculator should be used at DrawioParser.build_otm bellow the line # TODO Implement and call Transformers here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is the right task to do that, but also done anyway


def transform(self):
self.set_otm_parents()

def set_otm_parents(self):
for element in self.diagram.components + self.diagram.trustzones:
parent_id = element.shape_parent_id
if parent_id:
element.otm.parent = parent_id
parent = self.__find_by_id(parent_id)
parent_type = get_parent_type(parent)
element.otm.parent_type = parent_type
a = element

def __find_by_id(self, id_: str):
for element in self.diagram.components + self.diagram.trustzones:
if element.otm.id == id_:
return element
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from slp_drawio.slp_drawio.objects.diagram_objects import Diagram, DiagramTrustZone, DiagramComponent
from slp_drawio.slp_drawio.parse.transformer.default_trustzone_transformer import DefaultTrustZoneTransformer

DEFAULT_TRUSTZONE: DiagramTrustZone = DiagramTrustZone('dtz', 'Default TrustZone', True)
DEFAULT_TRUSTZONE: DiagramTrustZone = DiagramTrustZone('dtz', 'Default TrustZone', default=True)


def _create_diagram(default_trustzone: DiagramTrustZone = None, trustzones: List[DiagramTrustZone] = None,
Expand Down Expand Up @@ -98,7 +98,7 @@ def test_some_orphan_components(self, repr_calc_mock):
def test_no_orphan_components(self, default_trustzone: DiagramTrustZone):
# GIVEN a Diagram with a DiagramTrustZone set as default
# AND some DiagramComponents all of them with the parent set
trustzone = DiagramTrustZone(id='tz', name='tz', type='tzt')
trustzone = DiagramTrustZone(id_='tz', name='tz', type_='tzt')
components = [_create_component(component_id='c', parent_id=trustzone.otm.id)]
diagram = _create_diagram(
components=components,
Expand All @@ -116,7 +116,7 @@ def test_no_orphan_components(self, default_trustzone: DiagramTrustZone):
assert DEFAULT_TRUSTZONE not in diagram.trustzones

@mark.parametrize('trustzones', [
param([DiagramTrustZone('tz')] , id='with trustzones'),
param([DiagramTrustZone('tz')], id='with trustzones'),
param(None, id='without trustzones')
])
def test_orphan_components_and_no_default_trustzone(self, trustzones: List[DiagramTrustZone]):
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from otm.otm.entity.parent_type import ParentType
from slp_drawio.slp_drawio.objects.diagram_objects import Diagram, DiagramComponent, DiagramTrustZone, DiagramDataflow
from slp_drawio.slp_drawio.parse.tranformers.parent_calculator_transformer import ParentCalculatorTransformer, \
get_parent_type


class TestParentCalculatorTransformer:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class lacks tests to set the parent for:

  1. Component has a TrustZone as parent
  2. Trustzone has a Component as a parent
  3. Trustzone has another TZ as a parent

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these use cases are out of scope of the MVP, but I have done it anyway. I had to modify the DiagramTrustzone class.


def test_transform_with_parent_set(self):
# GIVEN the trust zones
tz0 = DiagramTrustZone('1a', id_='tz0', name='trustzone0', default=True)
tz1 = DiagramTrustZone('2b', id_='tz1', name='trustzone1')
tz2 = DiagramTrustZone('3c', id_='tz2', name='trustzone2', shape_parent_id='c2.1')
tz3 = DiagramTrustZone('4d', id_='tz3', name='trustzone3', shape_parent_id='tz2')
# AND the components
c1 = DiagramComponent(id='c1', name='component1')
c21 = DiagramComponent(id='c2.1', name='component2.1', shape_parent_id='tz1')
c22 = DiagramComponent(id='c2.2', name='component2.2', shape_parent_id='tz1')
c23 = DiagramComponent(id='c2.3', name='component2.3', shape_parent_id='tz1')
c31 = DiagramComponent(id='c3.1', name='component3.1', shape_parent_id='tz3')
c32 = DiagramComponent(id='c3.2', name='component3.2', shape_parent_id='tz3')
c33 = DiagramComponent(id='c3.3', name='component3.3', shape_parent_id='tz3')
c41 = DiagramComponent(id='c4.1', name='component4.1', shape_parent_id='c3.3')
c42 = DiagramComponent(id='c4.2', name='component4.2', shape_parent_id='c3.3')
# AND the Diagram
diagram: Diagram = Diagram(
components=[c1, c21, c22, c23, c31, c32, c33, c41, c42],
trustzones=[tz1, tz2, tz3],
default_trustzone=tz0)
# AND the ParentCalculator transformer
transformer = ParentCalculatorTransformer(diagram)

# WHEN we transform the diagram
transformer.transform()

# THEN the diagram elements have the excepted parents
assert len(diagram.components) == 9
assert len(diagram.trustzones) == 3
assert diagram.components[0].otm.json() == {'id': 'c1', 'name': 'component1', 'parent': {'None': None},
'type': None}
assert diagram.components[1].otm.json() == {'id': 'c2.1', 'name': 'component2.1',
'parent': {'trustZone': 'tz1'},
'type': None}
assert diagram.components[2].otm.json() == {'id': 'c2.2', 'name': 'component2.2',
'parent': {'trustZone': 'tz1'},
'type': None}
assert diagram.components[3].otm.json() == {'id': 'c2.3', 'name': 'component2.3',
'parent': {'trustZone': 'tz1'},
'type': None}
assert diagram.components[4].otm.json() == {'id': 'c3.1', 'name': 'component3.1',
'parent': {'trustZone': 'tz3'},
'type': None}
assert diagram.components[5].otm.json() == {'id': 'c3.2', 'name': 'component3.2',
'parent': {'trustZone': 'tz3'},
'type': None}
assert diagram.components[6].otm.json() == {'id': 'c3.3', 'name': 'component3.3',
'parent': {'trustZone': 'tz3'},
'type': None}
assert diagram.components[7].otm.json() == {'id': 'c4.1', 'name': 'component4.1',
'parent': {'component': 'c3.3'},
'type': None}
assert diagram.components[8].otm.json() == {'id': 'c4.2', 'name': 'component4.2',
'parent': {'component': 'c3.3'},
'type': None}
assert diagram.trustzones[0].otm.json() == {'id': 'tz1', 'name': 'trustzone1', 'risk': {'trustRating': 10},
'type': '2b'}
assert diagram.trustzones[1].otm.json() == {'id': 'tz2', 'name': 'trustzone2', 'parent': {'component': 'c2.1'},
'risk': {'trustRating': 10}, 'type': '3c'}
assert diagram.trustzones[2].otm.json() == {'id': 'tz3', 'name': 'trustzone3', 'parent': {'trustZone': 'tz2'},
'risk': {'trustRating': 10}, 'type': '4d'}

def test_get_parent_type(self):
assert get_parent_type(DiagramTrustZone('8a')) == ParentType.TRUST_ZONE
assert get_parent_type(DiagramComponent('99')) == ParentType.COMPONENT
assert get_parent_type(DiagramDataflow('zz')) is None