Source code for flowstrider.models.threat
# SPDX-FileCopyrightText: 2025 German Aerospace Center (DLR)
#
# SPDX-License-Identifier: BSD-3-Clause
import typing
from dataclasses import dataclass
from flowstrider.models import common_models, dataflowdiagram
Location: typing.TypeAlias = typing.Union[
common_models.Node, common_models.Edge, dataflowdiagram.DataflowDiagram, str
]
[docs]
def location_str(location: Location, dfd: dataflowdiagram.DataflowDiagram):
if isinstance(location, common_models.Node):
return location.name if location.name != "" else location.id
elif isinstance(location, common_models.Edge):
return (
f"{location.name if location.name != '' else location.id}: "
+ f"{location_str(dfd.nodes[location.source_id], dfd)} -> "
+ f"{location_str(dfd.nodes[location.sink_id], dfd)}"
)
elif isinstance(location, dataflowdiagram.DataflowDiagram):
return location.name if location.name != "" else location.id
else:
return location
[docs]
@dataclass(frozen=True)
class Threat:
source: str
source_internal: str
location: Location
severity: float # 0 is lowest severity
short_description: str
long_description: str
mitigation_options: typing.List[str]
requirement: str
req_status: str
[docs]
def uid(self) -> str:
"""Unique identifier for each individal threat"""
if isinstance(self.location, str):
return f"{self.source_internal}@{self.location}"
else:
return f"{self.source_internal}@{self.location.id}"
[docs]
def display_id(self, dfd: dataflowdiagram.DataflowDiagram) -> str:
"""Display identifier for each individal threat; takes names instead of id of
elements and is localized; not suitable as a unique id
"""
return f"{self.source}@{location_str(self.location, dfd)}"
[docs]
def location_str(self, dfd: dataflowdiagram.DataflowDiagram) -> str:
return location_str(self.location, dfd)