mirror of https://github.com/MISP/misp-galaxy
111 lines
3.9 KiB
Python
111 lines
3.9 KiB
Python
import validators
|
|
|
|
|
|
class Cluster:
|
|
def __init__(self, uuid, galaxy, description=None, value=None, meta=None):
|
|
self.uuid = uuid
|
|
self.description = description
|
|
self.value = value
|
|
self.meta = meta
|
|
|
|
self.galaxy = galaxy # Reference to the Galaxy object this cluster belongs to
|
|
self.outbound_relationships = set()
|
|
self.inbound_relationships = set()
|
|
self.relationships = set()
|
|
|
|
def add_outbound_relationship(self, cluster):
|
|
self.outbound_relationships.add(cluster)
|
|
|
|
def add_inbound_relationship(self, cluster):
|
|
self.inbound_relationships.add(cluster)
|
|
|
|
def save_relationships(self, relationships):
|
|
self.relationships = relationships
|
|
|
|
def generate_entry(self):
|
|
entry = ""
|
|
entry += self._create_title_entry()
|
|
entry += self._create_description_entry()
|
|
entry += self._create_synonyms_entry()
|
|
entry += self._create_uuid_entry()
|
|
entry += self._create_refs_entry()
|
|
entry += self._create_associated_metadata_entry()
|
|
if self.relationships:
|
|
entry += self._create_related_entry()
|
|
return entry
|
|
|
|
def _create_title_entry(self):
|
|
entry = ""
|
|
entry += f"## {self.value}\n"
|
|
entry += f"\n"
|
|
return entry
|
|
|
|
def _create_description_entry(self):
|
|
entry = ""
|
|
if self.description:
|
|
entry += f"{self.description}\n"
|
|
return entry
|
|
|
|
def _create_synonyms_entry(self):
|
|
entry = ""
|
|
if isinstance(self.meta, dict) and self.meta.get("synonyms"):
|
|
entry += f"\n"
|
|
entry += f'??? info "Synonyms"\n'
|
|
entry += f"\n"
|
|
entry += f' "synonyms" in the meta part typically refer to alternate names or labels that are associated with a particular {self.value}.\n\n'
|
|
entry += f" | Known Synonyms |\n"
|
|
entry += f" |---------------------|\n"
|
|
synonyms_count = 0
|
|
for synonym in sorted(self.meta["synonyms"]):
|
|
synonyms_count += 1
|
|
entry += f" | `{synonym}` |\n"
|
|
return entry
|
|
|
|
def _create_uuid_entry(self):
|
|
entry = ""
|
|
if self.uuid:
|
|
entry += f"\n"
|
|
entry += f'??? tip "Internal MISP references"\n'
|
|
entry += f"\n"
|
|
entry += f" UUID `{self.uuid}` which can be used as unique global reference for `{self.value}` in MISP communities and other software using the MISP galaxy\n"
|
|
entry += f"\n"
|
|
return entry
|
|
|
|
def _create_refs_entry(self):
|
|
entry = ""
|
|
if isinstance(self.meta, dict) and self.meta.get("refs"):
|
|
entry += f"\n"
|
|
entry += f'??? info "External references"\n'
|
|
entry += f"\n"
|
|
|
|
for ref in self.meta["refs"]:
|
|
if validators.url(ref):
|
|
entry += f" - [{ref}]({ref}) - :material-archive: :material-arrow-right: [webarchive](https://web.archive.org/web/*/{ref})\n"
|
|
else:
|
|
entry += f" - {ref}\n"
|
|
|
|
entry += f"\n"
|
|
return entry
|
|
|
|
def _create_associated_metadata_entry(self):
|
|
entry = ""
|
|
if isinstance(self.meta, dict):
|
|
excluded_meta = ["synonyms", "refs"]
|
|
entry += f"\n"
|
|
entry += f'??? info "Associated metadata"\n'
|
|
entry += f"\n"
|
|
entry += f" |Metadata key {{ .no-filter }} |Value|\n"
|
|
entry += f" |-----------------------------------|-----|\n"
|
|
for meta in sorted(self.meta.keys()):
|
|
if meta not in excluded_meta:
|
|
entry += f" | {meta} | {self.meta[meta]} |\n"
|
|
return entry
|
|
|
|
def _create_related_entry(self):
|
|
entry = ""
|
|
entry += f"\n"
|
|
entry += f'??? info "Related clusters"\n'
|
|
entry += f"\n"
|
|
entry += f" To see the related clusters, click [here](./relations/{self.uuid}.md).\n"
|
|
return entry
|