Skip to content

Commit

Permalink
Merge pull request #1634 from bloomberg/fix-flash-markup
Browse files Browse the repository at this point in the history
unescape markup
  • Loading branch information
teleyinex committed Aug 28, 2017
2 parents 5b30ecd + de1c656 commit f5fa746
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 27 deletions.
17 changes: 12 additions & 5 deletions pybossa/view/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from flask import url_for
from flask import current_app
from flask import Response
from flask import Markup
from flask.ext.login import login_required, current_user
from flask.ext.babel import gettext
from flask_wtf.csrf import generate_csrf
Expand Down Expand Up @@ -137,8 +138,10 @@ def users(user_id=None):
if user.id != current_user.id]
[ensure_authorized_to('update', found_user) for found_user in found]
if not found:
flash("<strong>Ooops!</strong> We didn't find a user "
"matching your query: <strong>%s</strong>" % form.user.data)
markup = Markup('<strong>{}</strong> {} <strong>{}</strong>')
flash(markup.format(gettext("Ooops!"),
gettext("We didn't find a user matching your query:"),
form.user.data))
response = dict(template='/admin/users.html', found=found, users=users,
title=gettext("Manage Admin Users"),
form=form)
Expand Down Expand Up @@ -420,7 +423,8 @@ def respond():
announcement_repo.save(announcement)

msg_1 = gettext('Annnouncement created!')
flash('<i class="icon-ok"></i> ' + msg_1, 'success')
markup = Markup('<i class="icon-ok"></i> {}')
flash(markup.format(msg_1), 'success')

return redirect_content_type(url_for('admin.announcement'))

Expand Down Expand Up @@ -458,7 +462,8 @@ def respond():
announcement_repo.update(announcement)

msg_1 = gettext('Announcement updated!')
flash('<i class="icon-ok"></i> ' + msg_1, 'success')
markup = '<i class="icon-ok"></i> {}'
flash(markup.format(msg_1), 'success')

return redirect_content_type(url_for('admin.announcement'))

Expand All @@ -473,7 +478,9 @@ def delete_announcement(id):

ensure_authorized_to('delete', announcement)
announcement_repo.delete(announcement)
flash('<i class="icon-ok"></i> ' + 'Announcement deleted!', 'success')
msg_1 = gettext('Announcement deleted!')
markup = '<i class="icon-ok"></i> {}'
flash(markup.format(msg_1), 'success')
return redirect_content_type(url_for('admin.announcement'))


Expand Down
44 changes: 25 additions & 19 deletions pybossa/view/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

from flask import Blueprint, request, url_for, flash, redirect, abort, Response, current_app
from flask import render_template, make_response, session
from flask import Markup
from flask.ext.login import login_required, current_user
from flask.ext.babel import gettext
from flask_wtf.csrf import generate_csrf
Expand Down Expand Up @@ -271,13 +272,14 @@ def _description_from_long_description():
project_repo.save(project)

msg_1 = gettext('Project created!')
flash('<i class="icon-ok"></i> ' + msg_1, 'success')
flash('<i class="icon-bullhorn"></i> ' +
gettext('You can check the ') +
'<strong><a href="https://docs.pybossa.com">' +
gettext('Guide and Documentation') +
'</a></strong> ' +
gettext('for adding tasks, a thumbnail, using PYBOSSA.JS, etc.'),
flash(Markup('<i class="icon-ok"></i> {}').format(msg_1), 'success')
markup = Markup('<i class="icon-bullhorn"></i> {} ' +
'<strong><a href="https://docs.pybossa.com"> {}' +
'</a></strong> {}')
flash(markup.format(
gettext('You can check the '),
gettext('Guide and Documentation'),
gettext('for adding tasks, a thumbnail, using PYBOSSA.JS, etc.')),
'success')
auditlogger.add_log_entry(None, project, current_user)

Expand Down Expand Up @@ -308,7 +310,8 @@ def task_presenter_editor(short_name):
auditlogger.add_log_entry(old_project, db_project, current_user)
project_repo.update(db_project)
msg_1 = gettext('Task presenter added!')
flash('<i class="icon-ok"></i> ' + msg_1, 'success')
markup = Markup('<i class="icon-ok"></i> {}')
flash(markup.format(msg_1), 'success')
return redirect_content_type(url_for('.tasks',
short_name=project.short_name))

Expand All @@ -330,7 +333,7 @@ def task_presenter_editor(short_name):
url = '<a href="%s"> %s</a>' % (url_for('project.import_task',
short_name=project.short_name), msg_2)
msg = msg_1 + url + msg_3
flash(msg, 'info')
flash(Markup(msg), 'info')

wrap = lambda i: "projects/presenters/%s.html" % i
pres_tmpls = map(wrap, current_app.config.get('PRESENTERS'))
Expand Down Expand Up @@ -361,7 +364,7 @@ def task_presenter_editor(short_name):
msg = 'Your code will be <em>automagically</em> rendered in \
the <strong>preview section</strong>. Click in the \
preview button!'
flash(gettext(msg), 'info')
flash(Markup(gettext(msg)), 'info')
project_sanitized, owner_sanitized = sanitize_project_owner(project,
owner,
current_user,
Expand Down Expand Up @@ -772,7 +775,7 @@ def task_presenter(short_name, task_id):
msg = ("Oops! You have to sign in to participate in "
"<strong>%s</strong>"
"project" % project.name)
flash(gettext(msg), 'warning')
flash(Markup(gettext(msg)), 'warning')
return redirect(url_for('account.signin',
next=url_for('.presenter',
short_name=project.short_name)))
Expand All @@ -781,10 +784,12 @@ def task_presenter(short_name, task_id):
"Ooops! You are an anonymous user and will not "
"get any credit"
" for your contributions.")
msg_2 = gettext('Sign in now!')
next_url = url_for('project.task_presenter',
short_name=short_name, task_id=task_id)
url = url_for('account.signin', next=next_url)
flash(msg_1 + "<a href=\"" + url + "\">Sign in now!</a>", "warning")
markup = Markup('{{}} <a href="{}">{{}}</a>'.format(url))
flash(markup.format(msg_1, msg_2), "warning")

title = project_title(project, "Contribute")
project_sanitized, owner_sanitized = sanitize_project_owner(project, owner,
Expand Down Expand Up @@ -841,7 +846,7 @@ def respond(tmpl):
if not project.allow_anonymous_contributors and current_user.is_anonymous():
msg = "Oops! You have to sign in to participate in <strong>%s</strong> \
project" % project.name
flash(gettext(msg), 'warning')
flash(Markup(gettext(msg)), 'warning')
return redirect(url_for('account.signin',
next=url_for('.presenter',
short_name=project.short_name)))
Expand Down Expand Up @@ -1003,8 +1008,8 @@ def delete_tasks(short_name):
n_volunteers = cached_projects.n_volunteers(project.id)
n_completed_tasks = cached_projects.n_completed_tasks(project.id)
project = add_custom_contrib_button_to(project, get_user_id_or_ip())
project_sanitized, owner_sanitized = sanitize_project_owner(project,
owner,
project_sanitized, owner_sanitized = sanitize_project_owner(project,
owner,
current_user,
ps)
response = dict(template='projects/tasks/delete.html',
Expand Down Expand Up @@ -1237,7 +1242,7 @@ def show_stats(short_name):
current_user,
ps)

# Handle JSON project stats depending of output
# Handle JSON project stats depending of output
# (needs to be escaped for HTML)
if request.headers.get('Content-Type') == 'application/json':
handle_projectStats = projectStats
Expand Down Expand Up @@ -1545,7 +1550,7 @@ def respond():
cached_projects.delete_project(short_name)

msg_1 = gettext('Blog post created!')
flash('<i class="icon-ok"></i> ' + msg_1, 'success')
flash(Markup('<i class="icon-ok"></i> {}').format(msg_1), 'success')

return redirect(url_for('.show_blogposts', short_name=short_name))

Expand Down Expand Up @@ -1594,7 +1599,7 @@ def respond():
cached_projects.delete_project(short_name)

msg_1 = gettext('Blog post updated!')
flash('<i class="icon-ok"></i> ' + msg_1, 'success')
flash(Markup('<i class="icon-ok"></i> {}').format(msg_1), 'success')

return redirect(url_for('.show_blogposts', short_name=short_name))

Expand All @@ -1610,7 +1615,8 @@ def delete_blogpost(short_name, id):
ensure_authorized_to('delete', blogpost)
blog_repo.delete(blogpost)
cached_projects.delete_project(short_name)
flash('<i class="icon-ok"></i> ' + 'Blog post deleted!', 'success')
msg_1 = gettext('Blog post deleted!')
flash(Markup('<i class="icon-ok"></i> {}').format(msg_1), 'success')
return redirect(url_for('.show_blogposts', short_name=short_name))


Expand Down
2 changes: 1 addition & 1 deletion test/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ def test_12_admin_user_search_json(self):
# warning should be issued for non-found users
data = {'user': 'nothingexists'}
res = self.app_post_json('/admin/users', data=data)
warning = ("We didn't find")
warning = ("We didn&#39;t find")
err_msg = "a flash message should be returned for non-found users"
dat = json.loads(res.data)
assert warning in dat.get('flash'), (err_msg, dat)
Expand Down
4 changes: 2 additions & 2 deletions test/test_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -4442,7 +4442,7 @@ def test_export_task_csv_ignore_keys(self):
# Now with a real project
project = ProjectFactory.create()
self.clear_temp_container(project.owner_id)

TaskFactory.create_batch(5, project=project, info={'question': 'qu',
'geojson':
'complexjson'})
Expand Down Expand Up @@ -5977,7 +5977,7 @@ def test_69_allow_anonymous_contributors(self):
res = self.app.get(url, follow_redirects=True)
err_msg = "User should be redirected to sign in"
project = db.session.query(Project).first()
msg = "Oops! You have to sign in to participate in &lt;strong&gt;%s&lt;/strong&gt;" % project.name
msg = "Oops! You have to sign in to participate in <strong>%s</strong>" % project.name
assert msg in res.data, err_msg

# As registered user
Expand Down

0 comments on commit f5fa746

Please sign in to comment.