Kitti U
4 years ago
10 changed files with 143 additions and 69 deletions
-
28report_qweb_encrypt/__manifest__.py
-
47report_qweb_encrypt/controllers/main.py
-
61report_qweb_encrypt/models/ir_actions_report.py
-
1report_qweb_encrypt/readme/CONTRIBUTORS.rst
-
6report_qweb_encrypt/readme/DESCRIPTION.rst
-
2report_qweb_encrypt/readme/USAGE.rst
-
10report_qweb_encrypt/static/src/js/report/action_manager_report.js
-
1report_qweb_encrypt/tests/__init__.py
-
33report_qweb_encrypt/tests/test_report_qweb_encrypt.py
-
9report_qweb_encrypt/views/ir_actions_report.xml
@ -1,21 +1,21 @@ |
|||||
# Copyright 2020 Creu Blanca |
# Copyright 2020 Creu Blanca |
||||
|
# Copyright 2020 Ecosoft Co., Ltd. |
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
|
|
||||
{ |
{ |
||||
'name': 'Report Qweb Encrypt', |
|
||||
'summary': """ |
|
||||
Allow to encrypt qweb pdfs""", |
|
||||
'version': '12.0.1.0.0', |
|
||||
'license': 'AGPL-3', |
|
||||
'author': 'Creu Blanca,Odoo Community Association (OCA)', |
|
||||
'website': 'https://github.com/OCA/reporting-engine', |
|
||||
'depends': [ |
|
||||
'web', |
|
||||
|
"name": "Report Qweb Encrypt", |
||||
|
"summary": "Allow to encrypt qweb pdfs", |
||||
|
"version": "12.0.1.0.0", |
||||
|
"license": "AGPL-3", |
||||
|
"author": "Creu Blanca,Ecosoft,Odoo Community Association (OCA)", |
||||
|
"website": "https://github.com/OCA/reporting-engine", |
||||
|
"depends": [ |
||||
|
"web", |
||||
], |
], |
||||
'data': [ |
|
||||
'views/ir_actions_report.xml', |
|
||||
'templates/assets.xml' |
|
||||
], |
|
||||
'demo': [ |
|
||||
|
"data": [ |
||||
|
"views/ir_actions_report.xml", |
||||
|
"templates/assets.xml" |
||||
], |
], |
||||
|
"installable": True, |
||||
|
"maintainers": ["kittiu"], |
||||
} |
} |
@ -1,42 +1,33 @@ |
|||||
|
# Copyright 2020 Creu Blanca |
||||
|
# Copyright 2020 Ecosoft Co., Ltd. |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). |
||||
from odoo.addons.web.controllers import main as report |
from odoo.addons.web.controllers import main as report |
||||
from odoo.http import route |
|
||||
|
from odoo.http import route, request |
||||
from werkzeug.urls import url_decode |
from werkzeug.urls import url_decode |
||||
import json |
import json |
||||
import logging |
|
||||
from io import BytesIO |
|
||||
|
|
||||
_logger = logging.getLogger(__name__) |
|
||||
try: |
|
||||
from PyPDF2 import PdfFileReader, PdfFileWriter |
|
||||
except ImportError as err: |
|
||||
_logger.debug(err) |
|
||||
|
|
||||
|
|
||||
class ReportController(report.ReportController): |
class ReportController(report.ReportController): |
||||
@route() |
@route() |
||||
def report_download(self, data, token): |
def report_download(self, data, token): |
||||
result = super().report_download(data, token) |
result = super().report_download(data, token) |
||||
|
# When report is downloaded from print action, this function is called, |
||||
|
# but this function cannot pass context (manually entered password) to |
||||
|
# report.render_qweb_pdf(), encrypton for manual password is done here. |
||||
requestcontent = json.loads(data) |
requestcontent = json.loads(data) |
||||
url, type = requestcontent[0], requestcontent[1] |
|
||||
|
url, ttype = requestcontent[0], requestcontent[1] |
||||
if ( |
if ( |
||||
type in ['qweb-pdf'] and |
|
||||
result.headers['Content-Type'] == "application/pdf" and |
|
||||
'?' in url |
|
||||
|
ttype in ["qweb-pdf"] and |
||||
|
result.headers["Content-Type"] == "application/pdf" and |
||||
|
"?" in url |
||||
): |
): |
||||
url_data = dict(url_decode(url.split('?')[1]).items()) |
|
||||
if 'context' in url_data: |
|
||||
context_data = json.loads(url_data['context']) |
|
||||
if 'encrypt_password' in context_data: |
|
||||
# We need to encrypt here because this function is not |
|
||||
# passing context, so we need to implement this again |
|
||||
|
|
||||
|
url_data = dict(url_decode(url.split("?")[1]).items()) |
||||
|
if "context" in url_data: |
||||
|
context = json.loads(url_data["context"]) |
||||
|
if "encrypt_password" in context: |
||||
|
Report = request.env["ir.actions.report"] |
||||
data = result.get_data() |
data = result.get_data() |
||||
output_pdf = PdfFileWriter() |
|
||||
in_buff = BytesIO(data) |
|
||||
pdf = PdfFileReader(in_buff) |
|
||||
output_pdf.appendPagesFromReader(pdf) |
|
||||
output_pdf.encrypt(context_data['encrypt_password']) |
|
||||
buff = BytesIO() |
|
||||
output_pdf.write(buff) |
|
||||
result.set_data(buff.getvalue()) |
|
||||
|
encrypted_data = Report._encrypt_pdf( |
||||
|
data, context["encrypt_password"]) |
||||
|
result.set_data(encrypted_data) |
||||
return result |
return result |
@ -1,2 +1,3 @@ |
|||||
* Enric Tobella <etobella@creublanca.es> |
* Enric Tobella <etobella@creublanca.es> |
||||
* Jaime Arroyo <jaime.arroyo@creublanca.es> |
* Jaime Arroyo <jaime.arroyo@creublanca.es> |
||||
|
* Kitti U. <kittiu@ecosoft.co.th> |
@ -1,2 +1,4 @@ |
|||||
This module allows you to encrypt pdf files with a password when |
|
||||
downloading them. |
|
||||
|
This module allow you to encrypt PDF with a password seting option, |
||||
|
|
||||
|
* Manually keyin password (only applicable for record print action) |
||||
|
* Auto generated password based on object data (python) |
@ -1 +1 @@ |
|||||
To make a report encryptable mark the field `Encryptable` in the report record. |
|
||||
|
To make a report encryptable mark the field `Encryption` in the report record. |
@ -0,0 +1 @@ |
|||||
|
from . import test_report_qweb_encrypt |
@ -0,0 +1,33 @@ |
|||||
|
# © 2016 Therp BV <http://therp.nl> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
from odoo.exceptions import ValidationError |
||||
|
from odoo.tests.common import HttpCase |
||||
|
|
||||
|
|
||||
|
class TestReportQwebEncrypt(HttpCase): |
||||
|
|
||||
|
def test_report_qweb_no_encrypt(self): |
||||
|
ctx = {"force_report_rendering": True} |
||||
|
report = self.env.ref("web.action_report_internalpreview") |
||||
|
report.encrypt = False |
||||
|
pdf, _ = report.with_context(ctx).render_qweb_pdf([1]) |
||||
|
self.assertFalse(pdf.count(b"/Encrypt")) |
||||
|
|
||||
|
def test_report_qweb_auto_encrypt(self): |
||||
|
ctx = {"force_report_rendering": True} |
||||
|
report = self.env.ref("web.action_report_internalpreview") |
||||
|
report.encrypt = "auto" |
||||
|
report.encrypt_password = False |
||||
|
# If no encrypt_password, still not encrypted |
||||
|
pdf, _ = report.with_context(ctx).render_qweb_pdf([1]) |
||||
|
self.assertFalse(pdf.count(b"/Encrypt")) |
||||
|
# If invalid encrypt_password, show error |
||||
|
report.encrypt_password = "invalid python syntax" |
||||
|
with self.assertRaises(ValidationError): |
||||
|
pdf, _ = report.with_context(ctx).render_qweb_pdf([1]) |
||||
|
# Valid python string for password |
||||
|
report.encrypt_password = "'secretcode'" |
||||
|
pdf, _ = report.with_context(ctx).render_qweb_pdf([1]) |
||||
|
self.assertTrue(pdf.count(b"/Encrypt")) |
||||
|
|
||||
|
# TODO: test_report_qweb_manual_encrypt, require JS test? |
Write
Preview
Loading…
Cancel
Save
Reference in new issue