Links the indicators for the threat to the threat object and updates the metrics dictionary with the indicators
"""
componentId=self.componentID# Define the ID of 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:# Checks if the threat is the source or destination
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
sourceComponent=df.loc[df[const.Id]==lineTwo[const.From].item()]# Defines the source of the line connecting threats/consequences and attacks
destinationComponent=df.loc[df[const.Id]==lineTwo[const.To].item()]# Defines the destination of the line connecting threats/consequences and attacks
ifcomponentType==const.ThreatDynamic:# * If the component is a threat
ifsourceComponent[const.textArea1].item()==const.Threat:# Checks if source or destination is the threat
self.associatedThreat=sourceComponent
self.associatedAttack=destinationComponent
else:
self.associatedThreat=destinationComponent
self.associatedAttack=sourceComponent
elifcomponentType==const.ConsequenceDynamic:# * If the component is a consequence
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
"""
componentId=self.componentID# Define the ID of 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
self.linkMetric(df,metricsDict)
return# The attack is the only component associated with the dynamic
sourceComponent=df.loc[df[const.Id]==lineTwo[const.From].item()]# Defines the source of the line connecting threats/consequences and attacks
destinationComponent=df.loc[df[const.Id]==lineTwo[const.To].item()]# Defines the destination of the line connecting threats/consequences and attacks
ifcomponentType==const.ThreatDynamic:# * If the component is a threat
ifsourceComponent[const.textArea1].item()==const.Threat:# Checks if source or destination is the threat
self.associatedThreat=sourceComponent
self.associatedAttack=destinationComponent
else:
self.associatedThreat=destinationComponent
self.associatedAttack=sourceComponent
elifcomponentType==const.ConsequenceDynamic:# * If the component is a consequence
returnf"Metric: {self.name}, Value: {self.value} Last update: {self.date}"