possibilité de n'autoriser que certaines expressions python (#76103) #218
|
@ -185,7 +185,7 @@ def test_python_datasource_errors(pub, error_email, http_requests, emails, caplo
|
||||||
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
|
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
|
||||||
pub.site_options.write(fd)
|
pub.site_options.write(fd)
|
||||||
|
|
||||||
# running with disabled python expressions
|
# running with forbidden python expressions
|
||||||
pub.loggederror_class.wipe()
|
pub.loggederror_class.wipe()
|
||||||
datasource = {
|
datasource = {
|
||||||
'type': 'formula',
|
'type': 'formula',
|
||||||
|
@ -202,6 +202,25 @@ def test_python_datasource_errors(pub, error_email, http_requests, emails, caplo
|
||||||
assert logged_error.workflow_id is None
|
assert logged_error.workflow_id is None
|
||||||
assert logged_error.summary == 'Unauthorized Python Usage'
|
assert logged_error.summary == 'Unauthorized Python Usage'
|
||||||
|
|
||||||
|
# exception list
|
||||||
|
with open(os.path.join(pub.app_dir, 'allowed-python.txt'), 'w') as fd:
|
||||||
|
fd.write('blah\n')
|
||||||
|
|
||||||
|
pub.loggederror_class.wipe()
|
||||||
|
assert data_sources.get_items(datasource) == []
|
||||||
|
assert pub.loggederror_class.count() == 1
|
||||||
|
assert pub.loggederror_class.select()[0].summary == 'Unauthorized Python Usage'
|
||||||
|
|
||||||
|
with open(os.path.join(pub.app_dir, 'allowed-python.txt'), 'a') as fd:
|
||||||
|
fd.write('%r\n' % ['foo', 'bar'])
|
||||||
|
|
||||||
|
pub.loggederror_class.wipe()
|
||||||
|
assert data_sources.get_items(datasource) == [
|
||||||
|
('foo', 'foo', 'foo', {'id': 'foo', 'text': 'foo'}),
|
||||||
|
('bar', 'bar', 'bar', {'id': 'bar', 'text': 'bar'}),
|
||||||
|
]
|
||||||
|
assert pub.loggederror_class.count() == 0
|
||||||
|
|
||||||
|
|
||||||
def test_python_datasource_with_evalutils(pub):
|
def test_python_datasource_with_evalutils(pub):
|
||||||
plain_list = [
|
plain_list = [
|
||||||
|
|
|
@ -3462,7 +3462,9 @@ class FormBackOfficeStatusPage(FormStatusPage):
|
||||||
('template', '%s / %s' % (_('Template'), _('Django Expression')), 'template'),
|
('template', '%s / %s' % (_('Template'), _('Django Expression')), 'template'),
|
||||||
('html_template', _('HTML Template (WYSIWYG)'), 'html_template'),
|
('html_template', _('HTML Template (WYSIWYG)'), 'html_template'),
|
||||||
]
|
]
|
||||||
if get_publisher().has_site_option('disable-python-expressions'):
|
if get_publisher().has_site_option('disable-python-expressions') or get_publisher().has_site_option(
|
||||||
|
'forbid-python-expressions'
|
||||||
|
):
|
||||||
options = [x for x in options if x[0] != 'python-condition']
|
options = [x for x in options if x[0] != 'python-condition']
|
||||||
form.add(
|
form.add(
|
||||||
RadiobuttonsWidget,
|
RadiobuttonsWidget,
|
||||||
|
@ -3481,7 +3483,10 @@ class FormBackOfficeStatusPage(FormStatusPage):
|
||||||
'data-dynamic-display-value': 'django-condition',
|
'data-dynamic-display-value': 'django-condition',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if not get_publisher().has_site_option('disable-python-expressions'):
|
if not (
|
||||||
|
get_publisher().has_site_option('disable-python-expressions')
|
||||||
|
or get_publisher().has_site_option('forbid-python-expressions')
|
||||||
|
):
|
||||||
form.add(
|
form.add(
|
||||||
StringWidget,
|
StringWidget,
|
||||||
'python-condition',
|
'python-condition',
|
||||||
|
|
|
@ -1187,12 +1187,19 @@ class UnauthorizedPythonUsage(Exception):
|
||||||
def eval_python(expression, *args, **kwargs):
|
def eval_python(expression, *args, **kwargs):
|
||||||
# Inherently unsafe, abort if support is forbidden.
|
# Inherently unsafe, abort if support is forbidden.
|
||||||
if get_publisher().has_site_option('forbid-python-expressions'):
|
if get_publisher().has_site_option('forbid-python-expressions'):
|
||||||
get_publisher().record_error(
|
allowed_python_filename = os.path.join(get_publisher().app_dir, 'allowed-python.txt')
|
||||||
_('Unauthorized Python Usage'),
|
allowed = False
|
||||||
notify=True,
|
if os.path.exists(allowed_python_filename):
|
||||||
record=True,
|
with open(allowed_python_filename) as fd:
|
||||||
)
|
if expression in fd.read().splitlines():
|
||||||
raise UnauthorizedPythonUsage()
|
allowed = True
|
||||||
|
if not allowed:
|
||||||
|
get_publisher().record_error(
|
||||||
|
_('Unauthorized Python Usage'),
|
||||||
|
notify=True,
|
||||||
|
record=True,
|
||||||
|
)
|
||||||
|
raise UnauthorizedPythonUsage()
|
||||||
# noqa pylint: disable=eval-used
|
# noqa pylint: disable=eval-used
|
||||||
return eval(expression, *args, **kwargs)
|
return eval(expression, *args, **kwargs)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue