Skip to content

Commit 71070b5

Browse files
committed
[MIG] report_qweb_signer: Migration to 18.0
Refactor to use pyHanko and the new Odoo core `certificate.certificate` model. For now, a minimal refactor has been made as PoC to: - Use PyHanko as the signer library (more complete, mantained and reliable) - Remove all the forme java pdfsigner stuff. - Be able to use Odoo core certificates. Main pain points: - `cryptography` version is fixed in Odoo `requirements.txt`. This makes very hard for other libraries to work with that version. - The approach has been using the `pyhanko-cli` tool as backend so we can install it in it's own `venv` (or whatever isolation method is desired). MT-11131
1 parent a5d346f commit 71070b5

31 files changed

Lines changed: 359 additions & 1003 deletions

report_qweb_signer/README.rst

Lines changed: 40 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Qweb PDF reports signer
77
!! This file is generated by oca-gen-addon-readme !!
88
!! changes will be overwritten. !!
99
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10-
!! source digest: sha256:98ab01f40082429507d6180e23d3ffba607dff06c259e5adf5e41fd07bf25b76
10+
!! source digest: sha256:8e3e54c5fb4cf809950609cadd0a782a02940ee7a40be85ffbc935d24ec465fa
1111
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1212
1313
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
@@ -28,8 +28,8 @@ Qweb PDF reports signer
2828

2929
|badge1| |badge2| |badge3| |badge4| |badge5|
3030

31-
This module extends the functionality of report module to sign PDFs
32-
using a PKCS#12 certificate.
31+
This module extends the functionality of reports to sign PDFs using a
32+
PKCS#12 certificate.
3333

3434
**Table of contents**
3535

@@ -39,49 +39,36 @@ using a PKCS#12 certificate.
3939
Installation
4040
============
4141

42-
To install this module, you need to install Java JDK Headlees, e.g.:
42+
To install this module, you need to install pyhanko-cli, e.g.:
4343

44-
apt-get install default-jre-headless
44+
pipx install pyhanko-cli
4545

4646
Configuration
4747
=============
4848

49-
In order to start signing PDF documents you need to configure
50-
certificate(s) to use in your company.
49+
To start signing PDF reports you'll need first to configure your desired
50+
certificate. To do so:
5151

52-
- Go to ``Settings > Companies > Companies > Your company``
53-
- Go to ``Report configuration`` tab
54-
- Click ``Edit``
55-
- Add a new item in ``PDF report certificates`` list
56-
- Click ``Create``
57-
- Set name, certificate file, password file and model
58-
- Optionally you can set a domain and filename pattern for saving as
59-
attachment
52+
- Go to *Settings > General Settings* and then to the section
53+
*Certificates and Keys*. Then click on **Certificates**.
54+
- Add the cert you want to use: upload the file and set the password.
6055

61-
For example, if you want to sign only customer invoices in posted state:
56+
Now you need to configure the reports using this certificate:
6257

63-
- Model: ``account.move``
64-
- Domain:
65-
``[('move_type','=','out_invoice'), ('state', '=', 'posted')]``
66-
- Save as attachment:
67-
``(object.name or '').replace('/','_') + '.signed.pdf'``
58+
- Go to *Settings > Thecnical > Reporting > Reports*.
59+
- Search for the pdf report you want to sign.
60+
- In the report form, open the **Sign** tab.
61+
- Choose the **Certificate** you created before.
62+
- Optionally, you can set:
6863

69-
**Note**: Linux user that executes Odoo server process must have read
70-
access to certificate file and password file
71-
72-
Java Memory Settings
73-
--------------------
74-
75-
If you are signing large amounts of reports at the same time, or if you
76-
have a lower worker memory size than the JVM defaults, you may need to
77-
tune the JVM heap memory limits. Do so by adding a ``$JVM_ARGS``
78-
environment variable that contains the required flags. Check out these
79-
links too:
80-
81-
- `StackOverflow
82-
answer <https://stackoverflow.com/a/14763095/1468388>`__.
83-
- `Java
84-
docs <https://docs.oracle.com/cd/E15523_01/web.1111/e13814/jvm_tuning.htm#PERFM161>`__.
64+
- **Allow to sign only one document**: disallow signing a pdf that
65+
contains multiple docs.
66+
- **Save as attachment**: Set the signed document report file name
67+
pattern. Example:
68+
``(object.name or '').replace('/','_') + '.signed.pdf'``
69+
- **Signing domain**: Filter the document that will be signed.
70+
Example:
71+
``[('move_type','=','out_invoice'), ('state', '=', 'posted')]``
8572

8673
Usage
8774
=====
@@ -98,21 +85,25 @@ customer invoices.
9885
You can try the signing with the demo report that is included for
9986
customers called "Test PDF certificate".
10087

101-
You can set extra parameters of JSignPdf library in the system parameter
102-
named 'report_qweb_signer.java_position_parameters', for example '-V' to
103-
visible signature into pdf. You can also set extra parameters for Java
104-
in the system parameter named 'report_qweb_signer.java_parameters'.
105-
10688
Known issues / Roadmap
10789
======================
10890

109-
- When signing multiple documents (if 'Allow only one document' is
110-
disable) then 'Save as attachment' is not applied and signed result is
111-
not saved as attachment.
112-
- Add tests.
113-
- Why not taking the occasion to add the whole configuration at report
114-
level (if to be signed or not, the domain, etc...)? See
115-
https://github.com/OCA/reporting-engine/pull/533#issuecomment-898321161
91+
- This version 18.0 depends on pyhanko-cli for signing the documents,
92+
which isn't ideal at all but avoids the dependency hell coming from
93+
cryptography requisites.
94+
- In Odoo 19.0 Odoo implemented their own signing mechanism. We could
95+
backport it but it depends on python 12 which supports the proper
96+
cryptography library version and that would leave out any
97+
infrastructure using lower versions. So: for v19 we should get rid of
98+
all that external stuff and just use the core one. (ref:
99+
https://github.com/odoo/odoo/pull/194698)
100+
- When signing multiple documents (if *Allow only one document* is
101+
disabled) then *Save as attachment* is not applied and signed result
102+
is not saved as attachment.
103+
- Add more tests.
104+
- This module is incompatible with the ``account_edi_ubl_cii`` module,
105+
because the PDF content is altered after rendering. See:
106+
https://github.com/odoo/odoo/blob/5977da2c93d522ece984d2fa8a31624f4b612eca/addons/account_edi_ubl_cii/models/account_move_send.py#L131C9-L140
116107

117108
Bug Tracker
118109
===========
@@ -154,13 +145,6 @@ Contributors
154145
Other credits
155146
-------------
156147

157-
External utilities
158-
~~~~~~~~~~~~~~~~~~
159-
160-
- JSignPdf: © Josef Cacek - License `MPL <http://www.mozilla.org/MPL>`__
161-
or `LGPL2 <http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>`__
162-
- http://jsignpdf.sourceforge.net/
163-
164148
Icon
165149
~~~~
166150

report_qweb_signer/__manifest__.py

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,12 @@
66
{
77
"name": "Qweb PDF reports signer",
88
"summary": "Sign Qweb PDFs usign a PKCS#12 certificate",
9-
"version": "16.0.1.0.4",
9+
"version": "18.0.1.0.0",
1010
"category": "Reporting",
1111
"website": "https://github.com/OCA/reporting-engine",
12-
"author": "Tecnativa, " "Odoo Community Association (OCA)",
12+
"author": "Tecnativa, Odoo Community Association (OCA)",
1313
"license": "AGPL-3",
14-
"installable": True,
15-
"depends": ["web_editor"],
16-
"external_dependencies": {
17-
"python": [
18-
"endesive<=2.18.5 ; python_version < '3.12'",
19-
"endesive ; python_version >= '3.12'",
20-
"cryptography",
21-
],
22-
"deb": ["default-jre-headless"],
23-
},
24-
"data": [
25-
"data/defaults.xml",
26-
"security/ir.model.access.csv",
27-
"views/report_certificate_view.xml",
28-
"views/res_company_view.xml",
29-
],
30-
"demo": ["demo/report_partner_demo.xml", "demo/report_certificate_demo.xml"],
14+
"depends": ["certificate", "account"],
15+
"data": ["views/ir_actions_report_views.xml"],
16+
"demo": ["demo/certificate_demo.xml", "demo/report_partner_demo.xml"],
3117
}

report_qweb_signer/data/defaults.xml

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<odoo noupdate="1">
2+
<record id="demo_db_certificate" model="certificate.certificate">
3+
<field name="name">Demo Certificate Qweb</field>
4+
<field
5+
name="content"
6+
type="base64"
7+
file="report_qweb_signer/static/certificate/test.p12"
8+
/>
9+
<field name="pkcs12_password">admin</field>
10+
<field name="company_id" ref="base.main_company" />
11+
</record>
12+
</odoo>

report_qweb_signer/demo/report_certificate_demo.xml

Lines changed: 0 additions & 20 deletions
This file was deleted.

report_qweb_signer/demo/report_partner_demo.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,12 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
4141
<field
4242
name="attachment"
4343
>'test_' + (object.name or '').replace(' ', '_').lower() + '.pdf'</field>
44+
<field name="certificate_id" ref="report_qweb_signer.demo_db_certificate" />
45+
<field
46+
name="signed_attachment"
47+
>'test_' + (object.name or '').replace(' ', '_').lower() + '.signed.pdf'</field>
4448
<field name="attachment_use">True</field>
49+
<field name="signing_allow_only_one">True</field>
4550
<field name="binding_model_id" ref="base.model_res_partner" />
4651
<field name="binding_type">report</field>
4752
</record>

report_qweb_signer/i18n/report_qweb_signer.pot

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
msgid ""
66
msgstr ""
7-
"Project-Id-Version: Odoo Server 16.0\n"
7+
"Project-Id-Version: Odoo Server 17.0\n"
88
"Report-Msgid-Bugs-To: \n"
99
"Last-Translator: \n"
1010
"Language-Team: \n"
@@ -112,11 +112,6 @@ msgstr ""
112112
msgid "Java"
113113
msgstr ""
114114

115-
#. module: report_qweb_signer
116-
#: model:ir.model.fields,field_description:report_qweb_signer.field_report_certificate____last_update
117-
msgid "Last Modified on"
118-
msgstr ""
119-
120115
#. module: report_qweb_signer
121116
#: model:ir.model.fields,field_description:report_qweb_signer.field_report_certificate__write_uid
122117
msgid "Last Updated by"
@@ -134,6 +129,7 @@ msgstr ""
134129

135130
#. module: report_qweb_signer
136131
#: model:ir.model.fields,field_description:report_qweb_signer.field_report_certificate__model_id
132+
#: model:ir.model.fields,field_description:report_qweb_signer.field_report_certificate__model_name
137133
msgid "Model"
138134
msgstr ""
139135

@@ -153,11 +149,6 @@ msgstr ""
153149
msgid "PDF certificates"
154150
msgstr ""
155151

156-
#. module: report_qweb_signer
157-
#: model_terms:ir.ui.view,arch_db:report_qweb_signer.view_report_certificate_form
158-
msgid "PDF report certificate"
159-
msgstr ""
160-
161152
#. module: report_qweb_signer
162153
#: model:ir.model.fields,field_description:report_qweb_signer.field_res_company__report_certificate_ids
163154
msgid "PDF report certificates"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright 2025 Moduon Team S.L. <info@moduon.team>
2+
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
3+
4+
5+
def migrate(cr, version):
6+
# 1. Store certificate info (file path) to create the certs on post-mig
7+
# 2. Transform report.certificate to their reports values
8+
pass
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
11
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
2-
32
from . import ir_actions_report
4-
from . import report_certificate
5-
from . import res_company

0 commit comments

Comments
 (0)