[MIG] report_qweb_signer: Migration to 14.0 updating java's lib for visible signatures
parent
0809bb7109
commit
54bf4b0ef3
|
@ -6,7 +6,7 @@
|
||||||
{
|
{
|
||||||
"name": "Qweb PDF reports signer",
|
"name": "Qweb PDF reports signer",
|
||||||
"summary": "Sign Qweb PDFs usign a PKCS#12 certificate",
|
"summary": "Sign Qweb PDFs usign a PKCS#12 certificate",
|
||||||
"version": "13.0.2.0.0",
|
"version": "14.0.1.0.0",
|
||||||
"category": "Reporting",
|
"category": "Reporting",
|
||||||
"website": "https://github.com/OCA/reporting-engine",
|
"website": "https://github.com/OCA/reporting-engine",
|
||||||
"author": "Tecnativa, " "Odoo Community Association (OCA)",
|
"author": "Tecnativa, " "Odoo Community Association (OCA)",
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
<odoo>
|
<odoo>
|
||||||
<record model="ir.config_parameter" id="report_qweb_signer_java_param">
|
<record model="ir.config_parameter" id="report_qweb_signer_java_param">
|
||||||
<field name="key">report_qweb_signer.java_parameters</field>
|
<field name="key">report_qweb_signer.java_parameters</field>
|
||||||
<field name="value">-Xms4M -Xmx4M -XX:CompressedClassSpaceSize=256m</field>
|
<field name="value">-Xms16M -Xmx16M -XX:CompressedClassSpaceSize=256m</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.config_parameter" id="report_qweb_signer_java_position_param">
|
||||||
|
<field name="key">report_qweb_signer.java_position_parameters</field>
|
||||||
|
<field name="value">-llx 400 -lly 820 -urx 600 -ury 100 -fs 8</field>
|
||||||
</record>
|
</record>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|
|
@ -33,14 +33,16 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
</t>
|
</t>
|
||||||
</t>
|
</t>
|
||||||
</template>
|
</template>
|
||||||
<report
|
<record id="partner_demo_report" model="ir.actions.report">
|
||||||
id="partner_demo_report"
|
<field name="name">Test PDF certificate</field>
|
||||||
model="res.partner"
|
<field name="model">res.partner</field>
|
||||||
string="Test PDF certificate"
|
<field name="report_type">qweb-pdf</field>
|
||||||
report_type="qweb-pdf"
|
<field name="report_name">report_qweb_signer.report_partner_demo</field>
|
||||||
name="report_qweb_signer.report_partner_demo"
|
<field
|
||||||
file="report_qweb_signer.report_partner_demo"
|
name="attachment"
|
||||||
attachment_use="True"
|
>'test_' + (object.name or '').replace(' ', '_').lower() + '.pdf'</field>
|
||||||
attachment="'test_' + (object.name or '').replace(' ', '_').lower() + '.pdf'"
|
<field name="attachment_use">True</field>
|
||||||
/>
|
<field name="binding_model_id" ref="base.model_res_partner" />
|
||||||
|
<field name="binding_type">report</field>
|
||||||
|
</record>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|
|
@ -8,7 +8,6 @@ import logging
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
|
|
||||||
from cryptography.hazmat import backends
|
from cryptography.hazmat import backends
|
||||||
|
@ -17,7 +16,7 @@ from endesive import pdf
|
||||||
|
|
||||||
from odoo import _, models
|
from odoo import _, models
|
||||||
from odoo.exceptions import AccessError, UserError
|
from odoo.exceptions import AccessError, UserError
|
||||||
from odoo.tools.safe_eval import safe_eval
|
from odoo.tools.safe_eval import safe_eval, time
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -122,8 +121,13 @@ class IrActionsReport(models.Model):
|
||||||
irc_param = self.env["ir.config_parameter"].sudo()
|
irc_param = self.env["ir.config_parameter"].sudo()
|
||||||
java_bin = "java -jar"
|
java_bin = "java -jar"
|
||||||
java_param = irc_param.get_param("report_qweb_signer.java_parameters")
|
java_param = irc_param.get_param("report_qweb_signer.java_parameters")
|
||||||
jar = "{}/../static/jar/jPdfSign.jar".format(me)
|
java_position_param = irc_param.get_param(
|
||||||
return "{} {} {} {}".format(java_bin, java_param, jar, opts)
|
"report_qweb_signer.java_position_parameters"
|
||||||
|
)
|
||||||
|
jar = "{}/../static/jar/JSignPdf.jar".format(me)
|
||||||
|
return "{} {} {} {} {}".format(
|
||||||
|
java_bin, java_param, jar, opts, java_position_param
|
||||||
|
)
|
||||||
|
|
||||||
def _get_endesive_params(self, certificate):
|
def _get_endesive_params(self, certificate):
|
||||||
date = datetime.datetime.utcnow() - datetime.timedelta(hours=12)
|
date = datetime.datetime.utcnow() - datetime.timedelta(hours=12)
|
||||||
|
@ -160,7 +164,7 @@ class IrActionsReport(models.Model):
|
||||||
return pdfsigned
|
return pdfsigned
|
||||||
|
|
||||||
def pdf_sign(self, pdf, certificate):
|
def pdf_sign(self, pdf, certificate):
|
||||||
pdfsigned = pdf + ".signed.pdf"
|
pdfsigned = pdf[:-4] + "_signed.pdf"
|
||||||
p12 = _normalize_filepath(certificate.path)
|
p12 = _normalize_filepath(certificate.path)
|
||||||
passwd = _normalize_filepath(certificate.password_file)
|
passwd = _normalize_filepath(certificate.password_file)
|
||||||
method_used = certificate.signing_method
|
method_used = certificate.signing_method
|
||||||
|
@ -169,7 +173,12 @@ class IrActionsReport(models.Model):
|
||||||
_("Signing report (PDF): " "Certificate or password file not found")
|
_("Signing report (PDF): " "Certificate or password file not found")
|
||||||
)
|
)
|
||||||
if method_used == "java":
|
if method_used == "java":
|
||||||
signer_opts = '"{}" "{}" "{}" "{}"'.format(p12, pdf, pdfsigned, passwd)
|
passwd_f = open(passwd, "tr")
|
||||||
|
passwd = passwd_f.read().strip()
|
||||||
|
passwd_f.close()
|
||||||
|
signer_opts = ' "{}" -ksf "{}" -ksp "{}" -V -d "/tmp"'.format(
|
||||||
|
pdf, p12, passwd
|
||||||
|
)
|
||||||
signer = self._signer_bin(signer_opts)
|
signer = self._signer_bin(signer_opts)
|
||||||
process = subprocess.Popen(
|
process = subprocess.Popen(
|
||||||
signer, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
|
signer, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
|
||||||
|
@ -188,7 +197,7 @@ class IrActionsReport(models.Model):
|
||||||
self._signer_endesive(params, p12, pdf, pdfsigned, passwd)
|
self._signer_endesive(params, p12, pdf, pdfsigned, passwd)
|
||||||
return pdfsigned
|
return pdfsigned
|
||||||
|
|
||||||
def render_qweb_pdf(self, res_ids=None, data=None):
|
def _render_qweb_pdf(self, res_ids=None, data=None):
|
||||||
certificate = self._certificate_get(res_ids)
|
certificate = self._certificate_get(res_ids)
|
||||||
if certificate and certificate.attachment:
|
if certificate and certificate.attachment:
|
||||||
signed_content = self._attach_signed_read(res_ids, certificate)
|
signed_content = self._attach_signed_read(res_ids, certificate)
|
||||||
|
@ -199,7 +208,7 @@ class IrActionsReport(models.Model):
|
||||||
res_ids,
|
res_ids,
|
||||||
)
|
)
|
||||||
return signed_content, "pdf"
|
return signed_content, "pdf"
|
||||||
content, ext = super(IrActionsReport, self).render_qweb_pdf(res_ids, data)
|
content, ext = super(IrActionsReport, self)._render_qweb_pdf(res_ids, data)
|
||||||
if certificate:
|
if certificate:
|
||||||
# Creating temporary origin PDF
|
# Creating temporary origin PDF
|
||||||
pdf_fd, pdf = tempfile.mkstemp(suffix=".pdf", prefix="report.tmp.")
|
pdf_fd, pdf = tempfile.mkstemp(suffix=".pdf", prefix="report.tmp.")
|
||||||
|
@ -220,7 +229,7 @@ class IrActionsReport(models.Model):
|
||||||
for fname in (pdf, signed):
|
for fname in (pdf, signed):
|
||||||
try:
|
try:
|
||||||
os.unlink(fname)
|
os.unlink(fname)
|
||||||
except (OSError, IOError):
|
except OSError:
|
||||||
_logger.error("Error when trying to remove file %s", fname)
|
_logger.error("Error when trying to remove file %s", fname)
|
||||||
if certificate.attachment:
|
if certificate.attachment:
|
||||||
self._attach_signed_write(res_ids, certificate, content)
|
self._attach_signed_write(res_ids, certificate, content)
|
||||||
|
|
|
@ -31,9 +31,11 @@ class ReportCertificate(models.Model):
|
||||||
required=True,
|
required=True,
|
||||||
comodel_name="ir.model",
|
comodel_name="ir.model",
|
||||||
help="Model where apply this certificate",
|
help="Model where apply this certificate",
|
||||||
|
ondelete="cascade",
|
||||||
)
|
)
|
||||||
domain = fields.Char(
|
domain = fields.Char(
|
||||||
string="Domain", help="Domain for filtering if sign or not the document",
|
string="Domain",
|
||||||
|
help="Domain for filtering if sign or not the document",
|
||||||
)
|
)
|
||||||
allow_only_one = fields.Boolean(
|
allow_only_one = fields.Boolean(
|
||||||
string="Allow only one document",
|
string="Allow only one document",
|
||||||
|
@ -67,5 +69,6 @@ class ReportCertificate(models.Model):
|
||||||
help="Location to include in digital signature (typically, a city name). ",
|
help="Location to include in digital signature (typically, a city name). ",
|
||||||
)
|
)
|
||||||
endesive_certificate_reason = fields.Char(
|
endesive_certificate_reason = fields.Char(
|
||||||
string="Signature reason", help="Reason text to include in digital signature.",
|
string="Signature reason",
|
||||||
|
help="Reason text to include in digital signature.",
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,3 +5,5 @@
|
||||||
* Pedro M. Baeza
|
* Pedro M. Baeza
|
||||||
* Jairo Llopis
|
* Jairo Llopis
|
||||||
* David Vidal
|
* David Vidal
|
||||||
|
* Santi Argüeso <santi@comunitea.com>
|
||||||
|
* Omar Castiñeira <omar@comunitea.com>
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
External utilities
|
External utilities
|
||||||
++++++++++++++++++
|
++++++++++++++++++
|
||||||
|
|
||||||
* iText v1.4.8: © 2000-2006, Paulo Soares, Bruno Lowagie and others - License `MPL <http://www.mozilla.org/MPL>`__ or `LGPL2 <http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>`__ - http://sourceforge.net/projects/itext
|
* JSignPdf: © Josef Cacek - License `MPL <http://www.mozilla.org/MPL>`__ or `LGPL2 <http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>`__ - http://jsignpdf.sourceforge.net/
|
||||||
* jPdfSign: © 2006 Jan Peter Stotz - License `MPL <http://www.mozilla.org/MPL>`__ or `LGPL2 <http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>`__ (inherited from iText) - http://private.sit.fraunhofer.de/~stotz/software/jpdfsign
|
|
||||||
* Modified jPdfSign: © 2015 Antonio Espinosa - License `MPL <http://www.mozilla.org/MPL>`__ or `LGPL2 <http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html>`__ (inherited from iText) - static/src/java/JPdfSign.java
|
|
||||||
|
|
||||||
Icon
|
Icon
|
||||||
++++
|
++++
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
* When signing multiple documents (if 'Allow only one document' is disable)
|
* When signing multiple documents (if 'Allow only one document' is disable)
|
||||||
then 'Save as attachment' is not applied and signed result is not
|
then 'Save as attachment' is not applied and signed result is not
|
||||||
saved as attachment.
|
saved as attachment.
|
||||||
* To have a visible signature through an image embedded in the resulting PDF.
|
|
||||||
* Add tests.
|
* Add tests.
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -13,7 +13,7 @@ class TestReportQwebSigner(HttpCase):
|
||||||
).with_context(force_report_rendering=True)
|
).with_context(force_report_rendering=True)
|
||||||
|
|
||||||
def test_report_qweb_signer(self):
|
def test_report_qweb_signer(self):
|
||||||
self.report.render_qweb_pdf(self.partner.ids)
|
self.report._render_qweb_pdf(self.partner.ids)
|
||||||
# Reprint again for taking the PDF from attachment
|
# Reprint again for taking the PDF from attachment
|
||||||
IrAttachment = self.env["ir.attachment"]
|
IrAttachment = self.env["ir.attachment"]
|
||||||
domain = [
|
domain = [
|
||||||
|
@ -21,6 +21,6 @@ class TestReportQwebSigner(HttpCase):
|
||||||
("res_model", "=", self.partner._name),
|
("res_model", "=", self.partner._name),
|
||||||
]
|
]
|
||||||
num_attachments = IrAttachment.search_count(domain)
|
num_attachments = IrAttachment.search_count(domain)
|
||||||
self.report.render_qweb_pdf(self.partner.ids)
|
self.report._render_qweb_pdf(self.partner.ids)
|
||||||
num_attachments_after = IrAttachment.search_count(domain)
|
num_attachments_after = IrAttachment.search_count(domain)
|
||||||
self.assertEqual(num_attachments, num_attachments_after)
|
self.assertEqual(num_attachments, num_attachments_after)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
# generated from manifests external_dependencies
|
# generated from manifests external_dependencies
|
||||||
|
cryptography
|
||||||
|
endesive
|
||||||
lxml
|
lxml
|
||||||
PyPDF2
|
PyPDF2
|
||||||
xlrd
|
xlrd
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
../../../../report_qweb_signer
|
|
@ -0,0 +1,6 @@
|
||||||
|
import setuptools
|
||||||
|
|
||||||
|
setuptools.setup(
|
||||||
|
setup_requires=['setuptools-odoo'],
|
||||||
|
odoo_addon=True,
|
||||||
|
)
|
Loading…
Reference in New Issue