log.info(f"Added metric {newMetric} to GLOBAL dynamics list with ID: {self.id}")
else:
log.info(f"Metric {newMetric} already exists in GLOBAL dynamics list with ID: {self.id}")
self.metrics.append(metric)
log.info(f"Added metric {newMetric} to LOCAL dynamics list with ID: {self.id}")
#Metric class, will be used for all dynamics
#Metric class, will be used for all dynamics
classMetric:
classMetric:
def__init__(self,ID,name)->None:
def__init__(self,ID,name)->None:
...
@@ -45,7 +22,7 @@ class Metric:
...
@@ -45,7 +22,7 @@ class Metric:
self.ID=ID# ID of the metric used to locate in dynamics matrics
self.ID=ID# ID of the metric used to locate in dynamics matrics
self.name=name# Name of the metric
self.name=name# Name of the metric
# Metrics found in the metric table
# Metrics found in the metric table
...
@@ -57,17 +34,112 @@ class BowtieDynamic(DynamicComponent):
...
@@ -57,17 +34,112 @@ class BowtieDynamic(DynamicComponent):
def__init__(self,componentID,type)->None:
def__init__(self,componentID,type)->None:
super().__init__(componentID)
super().__init__(componentID)
self.type=type# Type of dynamicM
self.type=type# Type of dynamicM
self.associatedThreat=None# List of threats associated with the dynamic
self.associatedThreat=None# Threat associated with the dynamic
self.associatedAttack=None# List of attacks associated with the dynamic
self.associatedAttack=None# Attack associated with the dynamic
self.associatedConsequence=None# Consequence associated with the dynamic
"""_summary_
Handles the associated dynamics for the bowtie model as they are different from the ER model
ER model has one type of dynamic component with metrics however, the bowtie model has three dynamic types and needs more parsing
than the ER model du to the modeling annotation.
Abstracting this saves time
"""
defassociateBowtie(self,df,componentType):
componentId=self.componentID# Define the ID of the component
#Find the lines associated with the component
lines=df.loc[df['Name']=='Line']# Find all lines in the diagram
lineSource=lines.loc[lines[const.From]==componentId]# Find the line where the component is the source
lineDestination=lines.loc[lines[const.To]==componentId]# ! The component SHOULD be source however, to error handle we need to check for destination as well
iflineSource.isnull().values.any()==True:
lineOne=lineSource
else:
lineOne=lineDestination
iflineOne[const.From].item()==componentId:# If the component is the source
lineTwo=df.loc[df[const.Id]==lineOne[const.To].item()]# Find the component associated with the line
else:
lineTwo=df.loc[df[const.Id]==lineOne[const.From].item()]# Find the component associated with the line
# ! Edge case, if the second line is in fact not a second line it is an attack meaning that the dynamic component is an attack
ifcomponentType==const.Attack:# If the associated component is an attack
self.associatedAttack=lineTwo# ! The "line" is an attack, not a line, we add it to the associated attack field and move on
return# The attack is the only component associated with the dynamic