From 2780e8de22c9134b2241006d092d9226587489b0 Mon Sep 17 00:00:00 2001 From: Mykola Borchuk Date: Sun, 26 Apr 2026 15:34:39 +0200 Subject: [PATCH] feat: sign report PDFs with visual/digital signatures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reports page shows signing checkboxes when pdf_sign capabilities are available (from pdf_signature module). After PDF generation, selected signatures are applied before download/ZIP. Uses existing pdf_sign capability contract — reports module doesn't know about pdf_signature module directly. --- modules/reports/index.py | 15 +++++++++++++++ modules/reports/templates/reports.html | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/modules/reports/index.py b/modules/reports/index.py index d403d6f..f554c52 100644 --- a/modules/reports/index.py +++ b/modules/reports/index.py @@ -286,6 +286,21 @@ def _generate_report(self): buffer = io.BytesIO() template_module.generate_report(buffer, report_data, settings) + # Apply PDF signatures if requested + if mgr: + signers = mgr.find_capabilities('pdf_sign') + selected_signers = [i for i in range(len(signers)) + if request.form.get(f'sign_cap_{i}')] + if selected_signers: + pdf_bytes = buffer.getvalue() + for idx in selected_signers: + try: + pdf_bytes = signers[idx]['action'](pdf_bytes) + except Exception as e: + self.logger.error('Report signing failed (%s): %s', + signers[idx].get('name', '?'), e) + buffer = io.BytesIO(pdf_bytes) + # Check if any section requested file inclusion include_files = {} if mgr: diff --git a/modules/reports/templates/reports.html b/modules/reports/templates/reports.html index 7b9cf4b..e0976d3 100644 --- a/modules/reports/templates/reports.html +++ b/modules/reports/templates/reports.html @@ -124,6 +124,23 @@

Additional Options

+ + {% if module_manager %} + {% set signers = module_manager.find_capabilities('pdf_sign') %} + {% if signers %} +
+ +
+ {% for cap in signers %} + + {% endfor %} +
+
+ {% endif %} + {% endif %}