Skip to content

Commit

Permalink
Turn on/off HTML escaping in flash messages
Browse files Browse the repository at this point in the history
  • Loading branch information
amol- committed May 21, 2015
1 parent da851da commit 4e4bdea
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 14 deletions.
4 changes: 2 additions & 2 deletions tests/test_stack/dispatch/controllers/root.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,13 @@ def hello_cookie(self):

@expose()
def flash_redirect(self):
tg.flash("Wow, flash!")
tg.flash("Wow, <br/>flash!")
tg.redirect("/flash_after_redirect")

@expose()
def flash_render(self, using_js=False, with_message=True):
if asbool(with_message):
tg.flash('JS Flash')
tg.flash('JS <br/>Flash')

return tg.flash.render('flash', asbool(using_js))

Expand Down
27 changes: 18 additions & 9 deletions tests/test_stack/dispatch/test_url_dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@
from tg._compat import PY3, u_
import json

def setup_noDB():
base_config = TestConfig(folder = 'dispatch',
values = {'use_sqlalchemy': False,
'use_toscawidgets': False,
'use_toscawidgets2': False,
'ignore_parameters': ["ignore", "ignore_me"]
})
def setup_noDB(html_flash=False):
config = {'use_sqlalchemy': False,
'use_toscawidgets': False,
'use_toscawidgets2': False,
'ignore_parameters': ["ignore", "ignore_me"]}

if html_flash:
config['flash.allow_html'] = True

base_config = TestConfig(folder='dispatch',
values=config)
return app_from_config(base_config)


Expand Down Expand Up @@ -110,7 +114,7 @@ def test_redirect_to_list_of_strings():

def test_flash_redirect():
resp = app.get('/flash_redirect').follow()
assert 'Wow, flash!' in resp, resp
assert 'Wow, <br/>flash!' in resp, resp

def test_bigflash_redirect():
try:
Expand Down Expand Up @@ -141,7 +145,12 @@ def test_flash_javascript():

def test_flash_render_plain():
resp = app.get('/flash_render')
assert 'JS Flash' in resp
assert 'JS &lt;br/&gt;Flash' in resp, resp

def test_flash_render_plain_with_html():
app = setup_noDB(html_flash=True)
resp = app.get('/flash_render')
assert 'JS <br/>Flash' in resp, resp

def test_flash_render_no_message():
resp = app.get('/flash_render?with_message=False')
Expand Down
16 changes: 13 additions & 3 deletions tg/flash.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,17 @@ class TGFlash(GlobalConfigurable):

CONFIG_NAMESPACE = 'flash.'
CONFIG_OPTIONS = {'template': converters.astemplate,
'js_template': converters.astemplate}
'js_template': converters.astemplate,
'allow_html': converters.asbool}

def __init__(self, **options):
self.configure(**options)

def configure(self, cookie_name="webflash", default_status="ok",
template=DEFAULT_FLASH_TEMPLATE,
js_call='webflash.render()',
js_template=DEFAULT_JSFLASH_TEMPLATE):
js_template=DEFAULT_JSFLASH_TEMPLATE,
allow_html=False):
"""Flash messages can be configured through :class:`.AppConfig` (``app_cfg.base_config``)
using the following options:
Expand All @@ -82,6 +84,7 @@ def configure(self, cookie_name="webflash", default_status="ok",
- ``flash.template`` -> :class:`string.Template` instance used as the flash template when
rendered from server side, will receive ``$container_id``, ``$message`` and ``$status``
variables.
- ``flash.allow_html`` -> Turns on/off escaping in flash messages, by default HTML is not allowed.
- ``flash.js_call`` -> javascript code which will be run when displaying the flash
from javascript. Default is ``webflash.render()``, you can use ``webflash.payload()``
to retrieve the message and show it with your favourite library.
Expand All @@ -98,6 +101,7 @@ def configure(self, cookie_name="webflash", default_status="ok",
self.static_template = template
self.js_call = js_call
self.js_template = js_template
self.allow_html = allow_html

def __call__(self, message, status=None, **extra_payload):
"""Registers a flash message for display on current or next request."""
Expand All @@ -121,6 +125,12 @@ def __call__(self, message, status=None, **extra_payload):
def _prepare_payload(self, **data):
return url_quote(json.dumps(data))

def _get_message(self, payload):
msg = payload.get('message','')
if self.allow_html is False:
msg = escape(msg)
return msg

def render(self, container_id, use_js=True):
"""Render the flash message inside template or provide Javascript support for them.
Expand All @@ -137,7 +147,7 @@ def _render_static_version(self, container_id):
payload = self.pop_payload()
if not payload:
return ''
payload['message'] = escape(payload.get('message',''))
payload['message'] = self._get_message(payload)
payload['container_id'] = container_id
return self.static_template.substitute(payload)

Expand Down

0 comments on commit 4e4bdea

Please sign in to comment.