Skip to content

Commit

Permalink
[feature/OPT-1021] to dev (#330)
Browse files Browse the repository at this point in the history
* [OPT-1021] Implemented DrawioValidator

* [OPT-1021] workaround DiagramMapper implementation

* [OPT-1021] fix merge conflicts

* [OPT-1021] fix otm representation issue

* [OPT-1021] Updated drawio xsd

---------

Co-authored-by: PacoCid <117292868+PacoCid@users.noreply.github.com>
  • Loading branch information
smaneroiriusrisk and PacoCid authored Oct 23, 2023
1 parent 9b2d6aa commit dfaabce
Show file tree
Hide file tree
Showing 20 changed files with 380 additions and 20 deletions.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
'networkx==3.1',
'dependency-injector==4.41.0',
'google-re2==1.0',
'xmlschema==2.5.0',
# Do not upgrade pygraphviz unless security issues because it is heavily dependent on the underlying OS
'pygraphviz==1.10'
],
Expand Down
4 changes: 4 additions & 0 deletions sl_util/sl_util/secure_regex.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ def findall(regex, string, options=None):

def split(pattern, text, maxsplit=0, options=None):
return re2.split(pattern, text, maxsplit, options)


def compile(pattern, options=None):
return re2.compile(pattern, options)
Empty file added sl_util/tests/util/__init__.py
Empty file.
File renamed without changes.
22 changes: 14 additions & 8 deletions slp_base/slp_base/provider_type.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
from otm.otm.entity.representation import RepresentationType
from otm.otm.provider import Provider

application_json = 'application/json'
text_plain = 'text/plain'
application_octet_stream = 'application/octet-stream'
application_xml = 'application/xml'


class IacType(str, Provider):
CLOUDFORMATION = ("CLOUDFORMATION", "CloudFormation", RepresentationType.CODE,
['application/json', 'text/yaml', 'text/plain', 'application/octet-stream'])
[application_json, 'text/yaml', text_plain, application_octet_stream])
TERRAFORM = ("TERRAFORM", "Terraform", RepresentationType.CODE,
['text/plain', 'application/octet-stream', 'application/json'])
[text_plain, application_octet_stream, application_json])
TFPLAN = ("TFPLAN", "Terraform Plan", RepresentationType.CODE,
['text/plain', 'application/json', 'application/msword', 'text/vnd.graphviz', 'application/octet-stream'])
[text_plain, application_json, 'application/msword', 'text/vnd.graphviz', application_octet_stream])


class DiagramType(str, Provider):
VISIO = ("VISIO", "Visio", RepresentationType.DIAGRAM,
['application/vnd.ms-visio.drawing.main+xml', 'application/octet-stream'])
['application/vnd.ms-visio.drawing.main+xml', application_octet_stream])
LUCID = ("LUCID", "Lucidchart", RepresentationType.DIAGRAM,
['application/vnd.ms-visio.drawing.main+xml', 'application/octet-stream', 'application/zip'])
# DRAWIO = ("DRAWIO", "Drawio", RepresentationType.DIAGRAM,
# ['application/octet-stream', 'application/xml', 'text/plain'])
['application/vnd.ms-visio.drawing.main+xml', application_octet_stream, 'application/zip'])
DRAWIO = ("DRAWIO", "Drawio", RepresentationType.DIAGRAM,
[application_octet_stream, application_xml, text_plain])


class EtmType(str, Provider):

MTMT = ("MTMT", "Microsoft Threat Modeling Tool", RepresentationType.THREAT_MODEL,
['application/octet-stream', 'application/xml', 'text/plain'])
[application_octet_stream, application_xml, text_plain])
5 changes: 5 additions & 0 deletions slp_base/slp_base/provider_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ def generate_size_error(provider: Provider, source_file_name: str, exception=Sou
message=f'Provided {source_file_name} is not valid. Invalid size')


def generate_schema_error(provider: Provider, source_file_name: str, exception=SourceFileNotValidError):
return exception(title=f'{provider.provider_name} file is not valid',
message=f'Provided {source_file_name} is not valid. It does not comply with schema')


class ProviderValidator(metaclass=abc.ABCMeta):
"""
Formal Interface to validate the provider source data
Expand Down
89 changes: 89 additions & 0 deletions slp_drawio/resources/schemas/drawio_schema.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="mxfile" type="mxfileType"/>
<xs:complexType name="mxCellType" mixed="true">
<xs:sequence>
<xs:element type="mxGeometryType" name="mxGeometry" minOccurs="0"/>
</xs:sequence>
<xs:attribute type="xs:string" name="id"/>
<xs:attribute type="xs:string" name="parent"/>
<xs:attribute type="xs:string" name="value"/>
<xs:attribute type="xs:string" name="style"/>
<xs:attribute type="xs:string" name="vertex"/>
<xs:attribute type="xs:string" name="source"/>
<xs:attribute type="xs:string" name="target"/>
<xs:attribute type="xs:string" name="edge"/>
<xs:attribute type="xs:string" name="connectable"/>
</xs:complexType>
<xs:complexType name="mxGeometryType" mixed="true">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element type="ArrayType" name="Array" minOccurs="0"/>
<xs:element type="mxPointType" name="mxPoint" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
<xs:attribute type="xs:string" name="x"/>
<xs:attribute type="xs:string" name="y"/>
<xs:attribute type="xs:string" name="width"/>
<xs:attribute type="xs:string" name="height"/>
<xs:attribute type="xs:string" name="as"/>
<xs:attribute type="xs:string" name="relative"/>
</xs:complexType>
<xs:complexType name="mxPointType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="x"/>
<xs:attribute type="xs:string" name="y"/>
<xs:attribute type="xs:string" name="as"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="ArrayType">
<xs:sequence>
<xs:element type="mxPointType" name="mxPoint" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
<xs:attribute type="xs:string" name="as"/>
</xs:complexType>
<xs:complexType name="rootType">
<xs:sequence>
<xs:element type="mxCellType" name="mxCell" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="mxGraphModelType">
<xs:sequence>
<xs:element type="rootType" name="root"/>
</xs:sequence>
<xs:attribute type="xs:string" name="dx"/>
<xs:attribute type="xs:string" name="dy"/>
<xs:attribute type="xs:string" name="grid"/>
<xs:attribute type="xs:string" name="gridSize"/>
<xs:attribute type="xs:string" name="guides"/>
<xs:attribute type="xs:string" name="tooltips"/>
<xs:attribute type="xs:string" name="connect"/>
<xs:attribute type="xs:string" name="arrows"/>
<xs:attribute type="xs:string" name="fold"/>
<xs:attribute type="xs:string" name="page"/>
<xs:attribute type="xs:string" name="pageScale"/>
<xs:attribute type="xs:string" name="pageWidth"/>
<xs:attribute type="xs:string" name="pageHeight"/>
<xs:attribute type="xs:string" name="math"/>
<xs:attribute type="xs:string" name="shadow"/>
</xs:complexType>
<xs:complexType name="diagramType" mixed="true">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element type="mxGraphModelType" name="mxGraphModel"/>
</xs:sequence>
<xs:attribute type="xs:string" name="id"/>
<xs:attribute type="xs:string" name="name"/>
</xs:complexType>
<xs:complexType name="mxfileType">
<xs:sequence maxOccurs="unbounded">
<xs:element type="diagramType" name="diagram" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
<xs:attribute type="xs:string" name="host"/>
<xs:attribute type="xs:string" name="modified"/>
<xs:attribute type="xs:string" name="agent"/>
<xs:attribute type="xs:string" name="etag"/>
<xs:attribute type="xs:string" name="version"/>
<xs:attribute type="xs:string" name="type"/>
<xs:attribute type="xs:string" name="pages"/>
</xs:complexType>
</xs:schema>
3 changes: 1 addition & 2 deletions slp_drawio/slp_drawio/drawio_processor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from slp_base import OTMProcessor, ProviderValidator, ProviderLoader, MappingValidator, MappingLoader, ProviderParser, \
DiagramType
from slp_base import OTMProcessor, ProviderValidator, ProviderLoader, MappingValidator, MappingLoader, ProviderParser
from slp_drawio.slp_drawio.load.drawio_loader import DrawioLoader
from slp_drawio.slp_drawio.load.drawio_mapping_file_loader import DrawioMappingFileLoader
from slp_drawio.slp_drawio.parse.drawio_parser import DrawioParser
Expand Down
8 changes: 5 additions & 3 deletions slp_drawio/slp_drawio/parse/diagram_mapper.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
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.objects.diagram_objects import Diagram, DiagramRepresentation


class DiagramMapper:
def __init__(self, diagram: Diagram, mapping: DrawioMapping):
def __init__(self, project_id: str, diagram: Diagram, mapping: DrawioMapping):
self.project_id = project_id
self.diagram = diagram
self.mapping = mapping
self.size = {'width': 1000, 'height': 1000}

def map(self):
pass
self.diagram.representation = DiagramRepresentation(self.project_id, self.size)
11 changes: 8 additions & 3 deletions slp_drawio/slp_drawio/parse/drawio_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,15 @@ def build_otm(self) -> OTM:
return otm

def map_components_and_trustzones(self):
DiagramMapper(self.diagram, self.mapping).map()
DiagramMapper(self.project_id, self.diagram, self.mapping).map()

def __build_otm(self):
# TODO waiting the parser implementation
pass
otm = OTMBuilder(self.project_id, self.project_name, DiagramType.DRAWIO).build()

otm.representations = [self.diagram.representation.otm]
otm.components = [c.otm for c in self.diagram.components]
otm.dataflows = [d.otm for d in self.diagram.dataflows]
otm.trustzones = [t.otm for t in self.diagram.trustzones]

return otm

40 changes: 37 additions & 3 deletions slp_drawio/slp_drawio/validate/drawio_validator.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,57 @@
import copy
import logging
import os
import string
import uuid

from slp_base import ProviderValidator
import xmlschema

from slp_base import ProviderValidator, DiagramFileNotValidError, DiagramType
from slp_base.slp_base.provider_validator import generate_size_error, generate_content_type_error, generate_schema_error

logger = logging.getLogger(__name__)

MAX_SIZE = 10 * 1024 * 1024
MIN_SIZE = 10

path = os.path.dirname(__file__)


class DrawioValidator(ProviderValidator):

def __init__(self, data):
super(DrawioValidator, self).__init__()
self.data = data
self.provider = DiagramType.DRAWIO
self.xsd_schema = f'{path}/../../resources/schemas/drawio_schema.xsd'

def validate(self):
logger.info('Validating Drawio file')
self.__validate_size()
self.__validate_content_type()
self.__sanitize_name()
self.__validate_schema()

def __validate_size(self):
pass
size = self.data.size
if size > MAX_SIZE or size < MIN_SIZE:
raise generate_size_error(self.provider, 'diag_file', DiagramFileNotValidError)

def __validate_content_type(self):
pass
mime = self.data.content_type
if mime not in self.provider.valid_mime:
raise generate_content_type_error(self.provider, 'diag_file', DiagramFileNotValidError)

def __sanitize_name(self):
ext = self.data.filename.split('.')[-1]
ext = "".join([c for c in ext if c in string.ascii_letters])
name = str(uuid.uuid4())
self.data.filename = f'{name}.{ext}'

def __validate_schema(self):
schema = xmlschema.XMLSchema(self.xsd_schema)
try:
file_copy = copy.deepcopy(self.data.file)
schema.validate(file_copy)
except Exception:
raise generate_schema_error(self.provider, 'diag_file', DiagramFileNotValidError)
2 changes: 2 additions & 0 deletions slp_drawio/tests/resources/drawio/not_xml.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
WRONG_CONTENT
NOT XML
23 changes: 23 additions & 0 deletions slp_drawio/tests/resources/drawio/wrong_mxcell.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="Electron" modified="2023-10-10T12:38:11.657Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/19.0.3 Chrome/102.0.5005.63 Electron/19.0.3 Safari/537.36" etag="IaZ6VWqQhPlsWStpV9DA" version="19.0.3" type="device">
<diagram id="pOeIjdqQ_qid1hbLa7JX" name="Page-1">
<mxGraphModel dx="1421" dy="904" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCel id="0" />
<mxCel id="1" parent="0" />
<mxCel id="5i7VU8sxTlh_DojUgWXD-1" value="AWS Cloud" style="points=[[0,0],[0.25,0],[0.5,0],[0.75,0],[1,0],[1,0.25],[1,0.5],[1,0.75],[1,1],[0.75,1],[0.5,1],[0.25,1],[0,1],[0,0.75],[0,0.5],[0,0.25]];outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_aws_cloud_alt;strokeColor=#232F3E;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#232F3E;dashed=0;" parent="1" vertex="1">
<mxGeometry x="210" y="230" width="130" height="130" as="geometry" />
</mxCel>
<mxCel id="xUHJV5QXkyTOu5aMK-rF-2" value="" style="image;html=1;image=img/lib/clip_art/computers/Database_128x128.png" parent="5i7VU8sxTlh_DojUgWXD-1" vertex="1">
<mxGeometry x="25" y="40" width="80" height="80" as="geometry" />
</mxCel>
<mxCel id="5i7VU8sxTlh_DojUgWXD-2" value="Region" style="points=[[0,0],[0.25,0],[0.5,0],[0.75,0],[1,0],[1,0.25],[1,0.5],[1,0.75],[1,1],[0.75,1],[0.5,1],[0.25,1],[0,1],[0,0.75],[0,0.5],[0,0.25]];outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_region;strokeColor=#147EBA;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#147EBA;dashed=1;" parent="1" vertex="1">
<mxGeometry x="440" y="230" width="130" height="130" as="geometry" />
</mxCel>
<mxCel id="xUHJV5QXkyTOu5aMK-rF-3" value="" style="outlineConnect=0;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;shape=mxgraph.aws3.ec2;fillColor=#F58534;gradientColor=none;" parent="5i7VU8sxTlh_DojUgWXD-2" vertex="1">
<mxGeometry x="26.75" y="27" width="76.5" height="93" as="geometry" />
</mxCel>
</root>
</mxGraphModel>
</diagram>
</mxfile>
23 changes: 23 additions & 0 deletions slp_drawio/tests/resources/drawio/wrong_mxfile.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<mxfilee host="Electron" modified="2023-10-10T12:38:11.657Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/19.0.3 Chrome/102.0.5005.63 Electron/19.0.3 Safari/537.36" etag="IaZ6VWqQhPlsWStpV9DA" version="19.0.3" type="device">
<diagram id="pOeIjdqQ_qid1hbLa7JX" name="Page-1">
<mxGraphModel dx="1421" dy="904" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="5i7VU8sxTlh_DojUgWXD-1" value="AWS Cloud" style="points=[[0,0],[0.25,0],[0.5,0],[0.75,0],[1,0],[1,0.25],[1,0.5],[1,0.75],[1,1],[0.75,1],[0.5,1],[0.25,1],[0,1],[0,0.75],[0,0.5],[0,0.25]];outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_aws_cloud_alt;strokeColor=#232F3E;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#232F3E;dashed=0;" parent="1" vertex="1">
<mxGeometry x="210" y="230" width="130" height="130" as="geometry" />
</mxCell>
<mxCell id="xUHJV5QXkyTOu5aMK-rF-2" value="" style="image;html=1;image=img/lib/clip_art/computers/Database_128x128.png" parent="5i7VU8sxTlh_DojUgWXD-1" vertex="1">
<mxGeometry x="25" y="40" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="5i7VU8sxTlh_DojUgWXD-2" value="Region" style="points=[[0,0],[0.25,0],[0.5,0],[0.75,0],[1,0],[1,0.25],[1,0.5],[1,0.75],[1,1],[0.75,1],[0.5,1],[0.25,1],[0,1],[0,0.75],[0,0.5],[0,0.25]];outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_region;strokeColor=#147EBA;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#147EBA;dashed=1;" parent="1" vertex="1">
<mxGeometry x="440" y="230" width="130" height="130" as="geometry" />
</mxCell>
<mxCell id="xUHJV5QXkyTOu5aMK-rF-3" value="" style="outlineConnect=0;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;shape=mxgraph.aws3.ec2;fillColor=#F58534;gradientColor=none;" parent="5i7VU8sxTlh_DojUgWXD-2" vertex="1">
<mxGeometry x="26.75" y="27" width="76.5" height="93" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfilee>
23 changes: 23 additions & 0 deletions slp_drawio/tests/resources/drawio/wrong_mxgraphmodel.drawio
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="Electron" modified="2023-10-10T12:38:11.657Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/19.0.3 Chrome/102.0.5005.63 Electron/19.0.3 Safari/537.36" etag="IaZ6VWqQhPlsWStpV9DA" version="19.0.3" type="device">
<diagram id="pOeIjdqQ_qid1hbLa7JX" name="Page-1">
<mxGraphModell dx="1421" dy="904" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="5i7VU8sxTlh_DojUgWXD-1" value="AWS Cloud" style="points=[[0,0],[0.25,0],[0.5,0],[0.75,0],[1,0],[1,0.25],[1,0.5],[1,0.75],[1,1],[0.75,1],[0.5,1],[0.25,1],[0,1],[0,0.75],[0,0.5],[0,0.25]];outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_aws_cloud_alt;strokeColor=#232F3E;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#232F3E;dashed=0;" parent="1" vertex="1">
<mxGeometry x="210" y="230" width="130" height="130" as="geometry" />
</mxCell>
<mxCell id="xUHJV5QXkyTOu5aMK-rF-2" value="" style="image;html=1;image=img/lib/clip_art/computers/Database_128x128.png" parent="5i7VU8sxTlh_DojUgWXD-1" vertex="1">
<mxGeometry x="25" y="40" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="5i7VU8sxTlh_DojUgWXD-2" value="Region" style="points=[[0,0],[0.25,0],[0.5,0],[0.75,0],[1,0],[1,0.25],[1,0.5],[1,0.75],[1,1],[0.75,1],[0.5,1],[0.25,1],[0,1],[0,0.75],[0,0.5],[0,0.25]];outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_region;strokeColor=#147EBA;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#147EBA;dashed=1;" parent="1" vertex="1">
<mxGeometry x="440" y="230" width="130" height="130" as="geometry" />
</mxCell>
<mxCell id="xUHJV5QXkyTOu5aMK-rF-3" value="" style="outlineConnect=0;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;shape=mxgraph.aws3.ec2;fillColor=#F58534;gradientColor=none;" parent="5i7VU8sxTlh_DojUgWXD-2" vertex="1">
<mxGeometry x="26.75" y="27" width="76.5" height="93" as="geometry" />
</mxCell>
</root>
</mxGraphModell>
</diagram>
</mxfile>
Loading

0 comments on commit dfaabce

Please sign in to comment.