From 63bdedff472d7710685b715c49e22e3d1b245f9a Mon Sep 17 00:00:00 2001
From: Alexandre Dulaunoy
Date: Mon, 1 Jan 2024 19:01:29 +0100
Subject: [PATCH] new: [misp-galaxy.org] First version of misp-galaxy.org
---
tools/mkdocs/build.sh | 6 ++++
tools/mkdocs/generator.py | 53 +++++++++++++++++++++++++++++-
tools/mkdocs/site/mkdocs.yml | 62 ++++++++++++++++++++++++++++++++++++
3 files changed, 120 insertions(+), 1 deletion(-)
create mode 100644 tools/mkdocs/build.sh
diff --git a/tools/mkdocs/build.sh b/tools/mkdocs/build.sh
new file mode 100644
index 0000000..71ff4d3
--- /dev/null
+++ b/tools/mkdocs/build.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+python3 generator.py
+cd site
+mkdocs build
+rsync --include ".*" -v -rz --checksum site/ circl@cppz.circl.lu:/var/www/misp-galaxy.org
diff --git a/tools/mkdocs/generator.py b/tools/mkdocs/generator.py
index 2e0ad90..0fafad0 100644
--- a/tools/mkdocs/generator.py
+++ b/tools/mkdocs/generator.py
@@ -3,6 +3,8 @@
import json
import os
+import validators
+
pathClusters = '../../clusters'
pathSite = './site/docs'
@@ -40,14 +42,63 @@ for f in galaxies_fnames:
cluster = json.load(fr)
cluster_filename = f.split('.')[0]
index_output += f'- [{cluster["name"]}](./{cluster_filename}/index.md)\n'
- galaxy_output[cluster_filename] = ""
+ galaxy_output[cluster_filename] = "---"
+ galaxy_output[cluster_filename] += f'title: {cluster["name"]}\n'
+ meta_description = cluster["description"].replace("\"", "-")
+ galaxy_output[cluster_filename] += f'description: {meta_description}\n'
+ galaxy_output[cluster_filename] += "---\n"
galaxy_output[cluster_filename] += f'# {cluster["name"]}\n'
galaxy_output[cluster_filename] += f'{cluster["description"]}\n'
for value in cluster["values"]:
galaxy_output[cluster_filename] += f'## {value["value"]}\n'
+ galaxy_output[cluster_filename] += f'\n'
if 'description' in value:
galaxy_output[cluster_filename] += f'{value["description"]}\n'
+ if 'meta' in value:
+ if 'synonyms' in value['meta']:
+ if value['meta']['synonyms']: # some cluster have an empty list of synomyms
+ galaxy_output[cluster_filename] += f'\n'
+ galaxy_output[cluster_filename] += f'??? info "Synonyms"\n'
+ galaxy_output[cluster_filename] += f'\n'
+ galaxy_output[cluster_filename] += f' "synonyms" in the meta part typically refer to alternate names or labels that are associated with a particular {cluster["name"]}.\n\n'
+ galaxy_output[cluster_filename] += f' | Known Synonyms |\n'
+ galaxy_output[cluster_filename] += f' |---------------------|\n'
+ for synonym in sorted(value['meta']['synonyms']):
+ galaxy_output[cluster_filename] += f' | `{synonym}` |\n'
+
+ if 'uuid' in value:
+ galaxy_output[cluster_filename] += f'\n'
+ galaxy_output[cluster_filename] += f'??? tip "Internal MISP references"\n'
+ galaxy_output[cluster_filename] += f'\n'
+ galaxy_output[cluster_filename] += f' UUID `{value["uuid"]}` which can be used as unique global reference for `{value["value"]}` in MISP communities and other software using the MISP galaxy\n'
+ galaxy_output[cluster_filename] += f'\n'
+
+ if 'meta' in value:
+ if 'refs' in value['meta']:
+ galaxy_output[cluster_filename] += f'\n'
+ galaxy_output[cluster_filename] += f'??? info "External references"\n'
+ galaxy_output[cluster_filename] += f'\n'
+
+ for ref in value["meta"]["refs"]:
+ if validators.url(ref): # some ref are not actual URL (TODO: check galaxy cluster sources)
+ galaxy_output[cluster_filename] += f' - [{ref}]({ref}) - :material-archive: :material-arrow-right: [webarchive](https://web.archive.org/web/*/{ref})\n'
+ else:
+ galaxy_output[cluster_filename] += f' - {ref}\n'
+
+ galaxy_output[cluster_filename] += f'\n'
+ excluded_meta = ['synonyms', 'refs']
+ galaxy_output[cluster_filename] += f'\n'
+ galaxy_output[cluster_filename] += f'??? info "Associated metadata"\n'
+ galaxy_output[cluster_filename] += f'\n'
+ galaxy_output[cluster_filename] += f' |Metadata key |Value|\n'
+ galaxy_output[cluster_filename] += f' |---------------------|-----|\n'
+ for meta in sorted(value['meta']):
+ if meta in excluded_meta:
+ continue
+ galaxy_output[cluster_filename] += f' | `{meta}` |{value["meta"][meta]}|\n'
+
+
with open(os.path.join(pathSite, 'index.md'), "w") as index:
index.write(index_output)
diff --git a/tools/mkdocs/site/mkdocs.yml b/tools/mkdocs/site/mkdocs.yml
index 66c6139..c1e75ba 100644
--- a/tools/mkdocs/site/mkdocs.yml
+++ b/tools/mkdocs/site/mkdocs.yml
@@ -1,3 +1,65 @@
site_name: MISP galaxy
+copyright: Copyright © 2015 - 2024 MISP Project - License for the MISP galaxy is CC0 or 2-clause BSD.
+#repo_url: https://github.com/MISP/misp-galaxy - wtf is mkdocs searching for the master branch
theme:
name: material
+ icon:
+ admonition:
+ note: octicons/tag-16
+ abstract: octicons/checklist-16
+ info: octicons/info-16
+ tip: octicons/squirrel-16
+ success: octicons/check-16
+ question: octicons/question-16
+ warning: octicons/alert-16
+ failure: octicons/x-circle-16
+ danger: octicons/zap-16
+ bug: octicons/bug-16
+ example: octicons/beaker-16
+ quote: octicons/quote-16
+ features:
+ - navigation.footer
+ - search.highlight
+ - search.share
+ palette:
+
+ # Palette toggle for automatic mode
+ - media: "(prefers-color-scheme)"
+ toggle:
+ icon: material/brightness-auto
+ name: Switch to light mode
+ # Palette toggle for light mode
+ - media: "(prefers-color-scheme: light)"
+ scheme: default
+ toggle:
+ icon: material/brightness-7
+ name: Switch to dark mode
+ # Palette toggle for dark mode
+ - media: "(prefers-color-scheme: dark)"
+ scheme: slate
+ toggle:
+ icon: material/brightness-4
+ name: Switch to system preference
+
+markdown_extensions:
+ - admonition
+ - pymdownx.details
+ - pymdownx.superfences
+ - tables
+ - attr_list
+ - pymdownx.emoji:
+ emoji_index: !!python/name:material.extensions.emoji.twemoji
+ emoji_generator: !!python/name:material.extensions.emoji.to_svg
+
+extra:
+ social:
+ - icon: fontawesome/brands/mastodon
+ link: https://misp-community.org/@misp
+ - icon: fontawesome/brands/github
+ link: https://github.com/misp
+ generator: false
+
+plugins:
+ - search
+ #- git-committers:
+# branch: main