diff --git a/isso/__init__.py b/isso/__init__.py index b83975e..7890118 100644 --- a/isso/__init__.py +++ b/isso/__init__.py @@ -85,7 +85,10 @@ class Isso(object): self.conf = conf self.db = db.SQLite3(conf.get('general', 'dbpath'), conf) self.signer = URLSafeTimedSerializer(self.db.preferences.get("session-key")) - self.markup = html.Markup(conf.section('markup')) + self.markup = html.Markup( + conf.getlist("markup", "options"), + conf.getlist("markup", "allowed-elements"), + conf.getlist("markup", "allowed-attributes")) self.hasher = hash.new( conf.get("hash", "algorithm"), conf.get("hash", "salt")) diff --git a/isso/tests/test_html.py b/isso/tests/test_html.py index 541712b..e60916e 100644 --- a/isso/tests/test_html.py +++ b/isso/tests/test_html.py @@ -5,8 +5,6 @@ try: except ImportError: import unittest - -from isso import config from isso.utils import html @@ -55,13 +53,6 @@ class TestHTML(unittest.TestCase): self.assertEqual(html.sanitize(sanitizer, input), expected) def test_render(self): - conf = config.new({ - "markup": { - "options": "autolink", - "allowed-elements": "", - "allowed-attributes": "" - } - }) - renderer = html.Markup(conf.section("markup")).render + renderer = html.Markup(["autolink", ]).render self.assertEqual(renderer("http://example.org/ and sms:+1234567890"), '

http://example.org/ and sms:+1234567890

') diff --git a/isso/utils/html.py b/isso/utils/html.py index 212875d..4d540de 100644 --- a/isso/utils/html.py +++ b/isso/utils/html.py @@ -26,10 +26,15 @@ def Sanitizer(elements, attributes): "pre", "code", "blockquote", "del", "ins", "strong", "em", "h1", "h2", "h3", "h4", "h5", "h6", - "table", "thead", "tbody", "th", "td"] + elements + "table", "thead", "tbody", "th", "td"] # href for and align for - allowed_attributes = ["align", "href"] + attributes + allowed_attributes = ["align", "href"] + + def __init__(self, *args, **kwargs): + super(Inner, self).__init__(*args, **kwargs) + self.allowed_elements = Inner.allowed_elements + elements + self.allowed_attributes = Inner.allowed_attributes + attributes # remove disallowed tokens from the output def disallowed_token(self, token, token_type): @@ -65,13 +70,23 @@ def Markdown(extensions=("strikethrough", "superscript", "autolink")): class Markup(object): + """Text to HTML conversion using Markdown (+ configurable extensions) and + an HTML sanitizer to remove malicious elements. + + :param options: a list of parameters for the used renderer + :param elements: allowed HTML elements in the output + :param attributes: allowed HTML attributes in the output + """ + + def __init__(self, options, elements=None, attributes=None): + if elements is None: + elements = [] - def __init__(self, conf): + if attributes is None: + attributes = [] - parser = Markdown(conf.getlist("options")) - sanitizer = Sanitizer( - conf.getlist("allowed-elements"), - conf.getlist("allowed-attributes")) + parser = Markdown(options) + sanitizer = Sanitizer(elements, attributes) self._render = lambda text: sanitize(sanitizer, parser(text))