[IMP] email_template: render mako templates with jinja2 sandboxed environment

bzr revid: rco@openerp.com-20121213095643-czuw8ls0he5ru1lx
This commit is contained in:
Raphael Collet 2012-12-13 10:56:43 +01:00
parent d6ea61789f
commit 42ad6511e6
1 changed files with 33 additions and 11 deletions

View File

@ -29,12 +29,32 @@ from osv import fields
import tools
from tools.translate import _
from urllib import quote as quote
_logger = logging.getLogger(__name__)
try:
from mako.template import Template as MakoTemplate
# We use a jinja2 sandboxed environment to render mako templates.
# Note that the rendering does not cover all the mako syntax, in particular
# arbitrary Python statements are not accepted, and not all expressions are
# allowed: only "public" attributes (not starting with '_') of objects may
# be accessed.
# This is done on purpose: it prevents incidental or malicious execution of
# Python code that may break the security of the server.
from jinja2.sandbox import SandboxedEnvironment
mako_template_env = SandboxedEnvironment(
block_start_string="<%",
block_end_string="%>",
variable_start_string="${",
variable_end_string="}",
comment_start_string="<%doc>",
comment_end_string="</%doc>",
line_statement_prefix="%",
line_comment_prefix="##",
trim_blocks=True, # do not output newline after blocks
autoescape=True, # XML/HTML automatic escaping
)
except ImportError:
_logger.warning("email_template: mako templates not available, templating features will not work!")
_logger.warning("jinja2 not available, templating features will not work!")
class email_template(osv.osv):
"Templates for sending email"
@ -55,7 +75,8 @@ class email_template(osv.osv):
:param str model: model name of the document record this mail is related to.
:param int res_id: id of the document record this mail is related to.
"""
if not template: return u""
if not template:
return u""
if context is None:
context = {}
try:
@ -64,14 +85,15 @@ class email_template(osv.osv):
if res_id:
record = self.pool.get(model).browse(cr, uid, res_id, context=context)
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
result = MakoTemplate(template).render_unicode(object=record,
user=user,
# context kw would clash with mako internals
ctx=context,
quote=quote,
format_exceptions=True)
if result == u'False':
result = u''
variables = {
'object': record,
'user': user,
'ctx': context, # context kw would clash with mako internals
'quote': quote,
}
result = mako_template_env.from_string(template).render(variables)
if result == u"False":
result = u""
return result
except Exception:
_logger.exception("failed to render mako template value %r", template)