From a9b98a88a954189bcc701cdcbebf5852df128702 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 9 Dec 2013 12:05:11 +0100 Subject: [PATCH] [IMP] font: add security rule, lazy loading at first report rendering bzr revid: mat@openerp.com-20131209110511-l72dgop00bfdeq3v --- openerp/addons/base/res/res_company.py | 11 +++---- openerp/addons/base/res/res_font.py | 32 +++++++++++++------ .../addons/base/security/ir.model.access.csv | 2 ++ openerp/report/render/rml2pdf/customfonts.py | 8 ++--- openerp/report/report_sxw.py | 14 ++++++++ 5 files changed, 47 insertions(+), 20 deletions(-) diff --git a/openerp/addons/base/res/res_company.py b/openerp/addons/base/res/res_company.py index 07464d2db4d..2977270b04c 100644 --- a/openerp/addons/base/res/res_company.py +++ b/openerp/addons/base/res/res_company.py @@ -27,7 +27,6 @@ from openerp.osv import fields, osv from openerp.tools.translate import _ from openerp.tools.safe_eval import safe_eval as eval from openerp.tools import image_resize_image -from openerp.report.render.rml2pdf import customfonts class multi_company_default(osv.osv): """ @@ -297,12 +296,12 @@ class res_company(osv.osv): def _get_font(self, cr, uid, ids): font_obj = self.pool.get('res.font') - res = font_obj.search(cr, uid, [('family', '=', 'Helvetica'), ('mode', '=', 'normal')], limit=1) + res = font_obj.search(cr, uid, [('family', '=', 'Helvetica'), ('mode', '=', 'all')], limit=1) if res: return res[0] - - font_obj.init_scan(cr, uid) - res = font_obj.search(cr, uid, [('family', '=', 'Helvetica'), ('mode', '=', 'normal')], limit=1) + # not even the basic pdf fonts, initiate the db + font_obj._base_populate_font(cr, uid) + res = font_obj.search(cr, uid, [('family', '=', 'Helvetica'), ('mode', '=', 'all')], limit=1) return res and res[0] or False _header = """ @@ -400,7 +399,7 @@ class res_company(osv.osv): return {'value': {'rml_header': self._header_a4}} def act_discover_fonts(self, cr, uid, ids, context=None): - return self.pool.get("res.font").init_scan(cr, uid, context) + return self.pool.get("res.font").font_scan(cr, uid, context) _defaults = { 'currency_id': _get_euro, diff --git a/openerp/addons/base/res/res_font.py b/openerp/addons/base/res/res_font.py index 172e2bead9f..d19eabacf85 100644 --- a/openerp/addons/base/res/res_font.py +++ b/openerp/addons/base/res/res_font.py @@ -53,14 +53,24 @@ class res_font(osv.Model): ('name_font_uniq', 'unique(family, name)', 'You can not register two fonts with the same name'), ] - def init_scan(self, cr, uid, context=None): - self.discover_fonts(cr, uid, context=context) - return self.register_fonts(cr, uid, context=context) + def _base_populate_font(self, cr, uid, context=None): + if not self.search(cr, uid, [('path', '=', '/dev/null')], context=context): + # populate db with basic pdf fonts + for family, name, path, mode in customfonts.BasePDFFonts: + self.create(cr, uid, { + 'family': family, 'name': name, + 'path': path, 'mode': mode, + }, context=context) + return True - def discover_fonts(self, cr, uid, context=None): + def font_scan(self, cr, uid, context=None): + self._discover_fonts(cr, uid, context=context) + return self._register_fonts(cr, uid, context=context) + + def _discover_fonts(self, cr, uid, context=None): """Scan fonts on the file system, add them to the list of known fonts and create font object for the new ones""" - customfonts.CustomTTFonts = list(customfonts.BaseCustomTTFonts) + customfonts.CustomTTFonts = [] found_fonts = {} for font_path in customfonts.list_all_sysfonts(): @@ -76,16 +86,18 @@ class res_font(osv.Model): except ttfonts.TTFError: _logger.warning("Could not register Font %s", font_path) - def register_fonts(self, cr, uid, context=None): + def _register_fonts(self, cr, uid, context=None): # add new custom fonts for family, name, path, mode in customfonts.CustomTTFonts: if not self.search(cr, uid, [('family', '=', family), ('name', '=', name)], context=context): self.create(cr, uid, { - 'family': family, 'name': name, - 'path': path, 'mode': mode, - }, context=context) + 'family': family, 'name': name, + 'path': path, 'mode': mode, + }, context=context) # remove fonts not present on disk existing_font_names = [name for (family, name, path, mode) in customfonts.CustomTTFonts] inexistant_fonts = self.search(cr, uid, [('name', 'not in', existing_font_names)], context=context) - return self.unlink(cr, uid, inexistant_fonts, context=context) + if inexistant_fonts: + return self.unlink(cr, uid, inexistant_fonts, context=context) + return True diff --git a/openerp/addons/base/security/ir.model.access.csv b/openerp/addons/base/security/ir.model.access.csv index 167c18ae884..ecae0109d8c 100644 --- a/openerp/addons/base/security/ir.model.access.csv +++ b/openerp/addons/base/security/ir.model.access.csv @@ -43,6 +43,8 @@ "access_ir_values_group_all","ir_values group_all","model_ir_values",,1,1,1,1 "access_res_company_group_erp_manager","res_company group_erp_manager","model_res_company","group_erp_manager",1,1,1,1 "access_res_company_group_user","res_company group_user","model_res_company",,1,0,0,0 +"access_res_font_group_user","res_font group_user","model_res_font","group_user",1,1,1,1 +"access_res_font_group_all","res_font group_all","model_res_font",,1,0,0,0 "access_res_country_group_all","res_country group_user_all","model_res_country",,1,0,0,0 "access_res_country_state_group_all","res_country_state group_user_all","model_res_country_state",,1,0,0,0 "access_res_country_group_user","res_country group_user","model_res_country","group_partner_manager",1,1,1,1 diff --git a/openerp/report/render/rml2pdf/customfonts.py b/openerp/report/render/rml2pdf/customfonts.py index b1007bfeb78..66e6b38b11c 100644 --- a/openerp/report/render/rml2pdf/customfonts.py +++ b/openerp/report/render/rml2pdf/customfonts.py @@ -40,9 +40,9 @@ _logger = logging.getLogger(__name__) # Basic fonts family included in PDF standart, will always be in the font list BasePDFFonts = [ - 'Helvetica', - 'Times', - 'Courier' + ('Helvetica', 'Helvetica', '/dev/null', 'all'), + ('Times', 'Times', '/dev/null', 'all'), + ('Courier', 'Courier', '/dev/null', 'all'), ] # List of fonts found on the disk @@ -59,7 +59,7 @@ BaseCustomTTFonts = [ ('Helvetica', "DejaVu Sans", "DejaVuSans.ttf", 'normal'), ('Courier', "FreeMono Oblique", "FreeMonoOblique.ttf", 'italic'), ('Courier', "FreeMono BoldOblique", "FreeMonoBoldOblique.ttf", 'bolditalic'), ] -CustomTTFonts = list(BaseCustomTTFonts) +CustomTTFonts = [] # Search path for TTF files, in addition of rl_config.TTFSearchPath TTFSearchPath = [ diff --git a/openerp/report/report_sxw.py b/openerp/report/report_sxw.py index 548a3f833f5..4726716a587 100644 --- a/openerp/report/report_sxw.py +++ b/openerp/report/report_sxw.py @@ -35,6 +35,7 @@ import common import openerp from openerp.osv.fields import float as float_field, function as function_field, datetime as datetime_field +from openerp.report.render.rml2pdf import customfonts from openerp.tools.translate import _ from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT @@ -419,10 +420,23 @@ class report_sxw(report_rml, preprocess.report): context = {} if self.internal_header: context.update(internal_header=self.internal_header) + # skip osv.fields.sanitize_binary_value() because we want the raw bytes in all cases context.update(bin_raw=True) registry = openerp.registry(cr.dbname) ir_obj = registry['ir.actions.report.xml'] + font_obj = registry['res.font'] + + found_fonts_ids = font_obj.search(cr, uid, [('path', '!=', '/dev/null')], context=context) + if not found_fonts_ids: + # no scan yet or no font found on the system, scan the filesystem + font_obj.font_scan(cr, uid, context=context) + else: + customfonts.CustomTTFonts = [] + for font in font_obj.browse(cr, uid, found_fonts_ids, context=context): + customfonts.CustomTTFonts.append((font.family, font.name, font.path, font.mode)) + + report_xml_ids = ir_obj.search(cr, uid, [('report_name', '=', self.name[7:])], context=context) if report_xml_ids: