plugins/vex/vex.py (56 lines of code) (raw):

import os import sys import json from re import sub from uuid import UUID, uuid5 from hashlib import md5 from pelican import signals from jsonschema import validate import jsonref def pelican_init(pelicanobj): with open('vex-input.json', 'r') as input: vex_input = json.loads(input.read()) # Our own input format - feel free to change as needed, # but remember to also update this plugin and the templates in # /themes/solr/templates/security.html with open('plugins/vex/schema/vex-input.schema.json', 'r') as file: from pathlib import Path loaded = jsonref.load(file, base_uri=Path('./plugins/vex/schema/base').absolute().as_uri()) validate(vex_input, loaded) ns = UUID('4f298c2c-eb7c-4968-a827-1482b1e5c095') ref = str(uuid5(ns, md5(json.dumps(vex_input).encode()).hexdigest())) vulns = [] for v in vex_input: for id in v['ids']: vulns.append({ "id": id, "analysis": v['analysis'], "affects": [ { "ref": ref } ] }) vex = { # we're not committing to doing exactly what CycloneDX comes # up with, but it seems like one of the promising formats, so # let's align with it as much as possible: "bomFormat": "CycloneDX", "specVersion": "1.4", "version": 1, "metadata": { "component": { "name": "solr", "version": "SNAPSHOT", "type": "application", "bom-ref": ref } }, "vulnerabilities": vulns } # From https://github.com/CycloneDX/specification/tree/master/schema with open('plugins/vex/schema/bom-1.4.schema.json', 'r') as schema: validate(vex, json.load(schema)) output_path = pelicanobj.settings['OUTPUT_PATH'] os.makedirs(output_path, exist_ok=True) with open('%s/solr.vex.json' % output_path, 'w') as out: json.dump(vex, out, indent=2) def generator_initialized(generator): generator.context["vex"] = json.load(open('vex-input.json')) generator.context["sub"] = sub def register(): """Plugin registration""" signals.initialized.connect(pelican_init) signals.generator_init.connect(generator_initialized)