"""MitreId — validated MITRE ATT&CK technique identifier. Immutable value object that ensures the identifier follows the ATT&CK format: ``T`` followed by 4 digits, optionally a dot and 3 more digits for sub-techniques (e.g. ``T1059``, ``T1059.001``). """ # Enable future language features for compatibility from __future__ import annotations # Import re import re # Import dataclass from dataclasses from dataclasses import dataclass # Assign _MITRE_ID_RE = re.compile(r"^T\d{4}(\.\d{3})?$") _MITRE_ID_RE = re.compile(r"^T\d{4}(\.\d{3})?$") # Apply the @dataclass decorator @dataclass(frozen=True, slots=True) # Define class MitreId class MitreId: """Validated MITRE ATT&CK technique identifier.""" # value: str value: str # Define function __post_init__ def __post_init__(self) -> None: """Validate that *value* matches the expected MITRE ATT&CK ID format. Returns: None """ # Check: not _MITRE_ID_RE.match(self.value) if not _MITRE_ID_RE.match(self.value): # Raise ValueError raise ValueError( f"Invalid MITRE ATT&CK ID '{self.value}'. " # Literal argument value "Expected format: T1234 or T1234.001" ) # Apply the @property decorator @property # Define function is_subtechnique def is_subtechnique(self) -> bool: """Return True if this identifier represents a sub-technique. Returns: bool: True when the ID contains a dot (e.g. ``T1059.001``). """ # Return "." in self.value return "." in self.value # Apply the @property decorator @property # Define function parent_id def parent_id(self) -> str | None: """Return the parent technique ID (e.g. ``T1059`` for ``T1059.001``). Returns: str | None: The parent ID string, or None if this is not a sub-technique. """ # Check: not self.is_subtechnique if not self.is_subtechnique: # Return None return None # Return self.value.split(".")[0] return self.value.split(".")[0] # Define function __str__ def __str__(self) -> str: """Return the string representation of the MITRE ID. Returns: str: The raw identifier string (e.g. ``"T1059.001"``). """ # Return self.value return self.value # Define function __eq__ def __eq__(self, other: object) -> bool: """Compare this MitreId to another MitreId or a plain string. Args: other (object): The value to compare against; may be a :class:`MitreId` instance or a plain ``str``. Returns: bool: True if the identifiers are equal, NotImplemented for unsupported types. """ # Check: isinstance(other, MitreId) if isinstance(other, MitreId): # Return self.value == other.value return self.value == other.value # Check: isinstance(other, str) if isinstance(other, str): # Return self.value == other return self.value == other # Return NotImplemented return NotImplemented # Define function __hash__ def __hash__(self) -> int: """Return the hash of the identifier string. Returns: int: Hash value derived from the raw identifier string. """ # Return hash(self.value) return hash(self.value)