Don't store the post-markdown HTML in our database content column.

(imported from commit bb81e84acc04ea0930be1026149618fbb60174fd)
This commit is contained in:
Tim Abbott
2012-09-26 14:41:54 -04:00
parent 97b20a8cb6
commit c8220ee057
3 changed files with 26 additions and 27 deletions

View File

@@ -229,8 +229,8 @@ def send_zephyrs(data):
saved_data = '' saved_data = ''
new_zephyr = Zephyr() new_zephyr = Zephyr()
length = random.randint(1, 5) length = random.randint(1, 5)
lines = (t.strip() + '<br />' for t in texts[offset: offset + length]) lines = (t.strip() for t in texts[offset: offset + length])
new_zephyr.content = '<p>' + ''.join(lines) + '</p>' new_zephyr.content = '\n'.join(lines)
offset += length offset += length
offset = offset % len(texts) offset = offset % len(texts)

View File

@@ -10,6 +10,11 @@ import datetime
from zephyr.lib.cache import cache_with_key from zephyr.lib.cache import cache_with_key
from django.db.models.signals import class_prepared from django.db.models.signals import class_prepared
import markdown
md_engine = markdown.Markdown(
extensions = ['fenced_code', 'codehilite'],
safe_mode = True,
output_format = 'xhtml' )
def get_display_recipient(recipient): def get_display_recipient(recipient):
""" """
@@ -162,7 +167,7 @@ class Zephyr(models.Model):
'display_recipient': get_display_recipient(self.recipient), 'display_recipient': get_display_recipient(self.recipient),
'recipient_id' : self.recipient.id, 'recipient_id' : self.recipient.id,
'instance' : self.instance, 'instance' : self.instance,
'content' : self.content, 'content' : md_engine.convert(self.content),
'timestamp' : calendar.timegm(self.pub_date.timetuple()), 'timestamp' : calendar.timegm(self.pub_date.timetuple()),
'gravatar_hash' : hashlib.md5(settings.HASH_SALT + self.sender.user.email).hexdigest(), 'gravatar_hash' : hashlib.md5(settings.HASH_SALT + self.sender.user.email).hexdigest(),
} }

View File

@@ -20,7 +20,6 @@ import datetime
import simplejson import simplejson
import socket import socket
import re import re
import markdown
import hashlib import hashlib
def require_post(view_func): def require_post(view_func):
@@ -42,23 +41,23 @@ def json_success(data={}):
def json_error(msg, data={}): def json_error(msg, data={}):
return json_response(res_type="error", msg=msg, data=data, status=400) return json_response(res_type="error", msg=msg, data=data, status=400)
def sanitize_identifier(x): def strip_html(x):
"""Sanitize an email, class name, etc.""" """Sanitize an email, class name, etc."""
# We remove <> in order to avoid </script> within JSON embedded in HTML. # We remove <> in order to avoid </script> within JSON embedded in HTML.
# #
# FIXME: consider a whitelist # FIXME: consider a whitelist
return x.replace('<','').replace('>','') return x.replace('<','&lt;').replace('>','&gt;')
def register(request): def register(request):
if request.method == 'POST': if request.method == 'POST':
form = RegistrationForm(request.POST) form = RegistrationForm(request.POST)
if form.is_valid(): if form.is_valid():
email = sanitize_identifier(request.POST['email']) email = strip_html(request.POST['email'])
password = request.POST['password'] password = request.POST['password']
full_name = sanitize_identifier(request.POST['full_name']) full_name = strip_html(request.POST['full_name'])
short_name = sanitize_identifier(request.POST['short_name']) short_name = strip_html(request.POST['short_name'])
email = sanitize_identifier(request.POST['email']) email = strip_html(request.POST['email'])
domain = sanitize_identifier(request.POST['domain']) domain = strip_html(request.POST['domain'])
realm = Realm.objects.filter(domain=domain) realm = Realm.objects.filter(domain=domain)
if not realm: if not realm:
realm = Realm(domain=domain) realm = Realm(domain=domain)
@@ -177,7 +176,7 @@ def zephyr(request):
@login_required @login_required
@require_post @require_post
def forge_zephyr(request): def forge_zephyr(request):
email = sanitize_identifier(request.POST['sender']).lower() email = strip_html(request.POST['sender']).lower()
user_profile = UserProfile.objects.get(user=request.user) user_profile = UserProfile.objects.get(user=request.user)
if "time" not in request.POST: if "time" not in request.POST:
@@ -188,14 +187,14 @@ def forge_zephyr(request):
except User.DoesNotExist: except User.DoesNotExist:
# forge a user for this person # forge a user for this person
create_user(email, "test", user_profile.realm, create_user(email, "test", user_profile.realm,
sanitize_identifier(request.POST['fullname']), strip_html(request.POST['fullname']),
sanitize_identifier(request.POST['shortname'])) strip_html(request.POST['shortname']))
user = User.objects.get(email=email) user = User.objects.get(email=email)
if (request.POST['type'] == 'personal' and ',' in request.POST['recipient']): if (request.POST['type'] == 'personal' and ',' in request.POST['recipient']):
# Huddle message, need to make sure we're not syncing it twice! # Huddle message, need to make sure we're not syncing it twice!
if Zephyr.objects.filter(sender__user__email=email, if Zephyr.objects.filter(sender__user__email=email,
content=md_engine.convert(request.POST['new_zephyr']), content=request.POST['new_zephyr'],
pub_date__gt=datetime.datetime.utcfromtimestamp(float(request.POST['time']) - 1).replace(tzinfo=utc), pub_date__gt=datetime.datetime.utcfromtimestamp(float(request.POST['time']) - 1).replace(tzinfo=utc),
pub_date__lt=datetime.datetime.utcfromtimestamp(float(request.POST['time']) + 1).replace(tzinfo=utc)): pub_date__lt=datetime.datetime.utcfromtimestamp(float(request.POST['time']) + 1).replace(tzinfo=utc)):
# This is a duplicate huddle message, deduplicate! # This is a duplicate huddle message, deduplicate!
@@ -213,11 +212,6 @@ def forge_zephyr(request):
return zephyr_backend(request, user) return zephyr_backend(request, user)
md_engine = markdown.Markdown(
extensions = ['fenced_code', 'codehilite'],
safe_mode = True,
output_format = 'xhtml' )
@login_required @login_required
@require_post @require_post
def zephyr_backend(request, sender): def zephyr_backend(request, sender):
@@ -234,7 +228,7 @@ def zephyr_backend(request, sender):
if "instance" not in request.POST: if "instance" not in request.POST:
return json_error("Missing instance") return json_error("Missing instance")
class_name = sanitize_identifier(request.POST['class']).strip() class_name = strip_html(request.POST['class']).strip()
my_classes = ZephyrClass.objects.filter(name=class_name, realm=user_profile.realm) my_classes = ZephyrClass.objects.filter(name=class_name, realm=user_profile.realm)
if my_classes: if my_classes:
my_class = my_classes[0] my_class = my_classes[0]
@@ -253,7 +247,7 @@ def zephyr_backend(request, sender):
if "recipient" not in request.POST: if "recipient" not in request.POST:
return json_error("Missing recipient") return json_error("Missing recipient")
recipient_data = sanitize_identifier(request.POST['recipient']) recipient_data = strip_html(request.POST['recipient'])
if ',' in recipient_data: if ',' in recipient_data:
# This is actually a huddle message, which shares the # This is actually a huddle message, which shares the
# "personal" zephyr sending form # "personal" zephyr sending form
@@ -285,10 +279,10 @@ def zephyr_backend(request, sender):
new_zephyr = Zephyr() new_zephyr = Zephyr()
new_zephyr.sender = UserProfile.objects.get(user=sender) new_zephyr.sender = UserProfile.objects.get(user=sender)
new_zephyr.content = md_engine.convert(request.POST['new_zephyr']) new_zephyr.content = strip_html(request.POST['new_zephyr'])
new_zephyr.recipient = recipient new_zephyr.recipient = recipient
if zephyr_type_name == 'class': if zephyr_type_name == 'class':
new_zephyr.instance = sanitize_identifier(request.POST['instance']) new_zephyr.instance = strip_html(request.POST['instance'])
if 'time' in request.POST: if 'time' in request.POST:
# Forged zephyrs come with a timestamp # Forged zephyrs come with a timestamp
new_zephyr.pub_date = datetime.datetime.utcfromtimestamp(float(request.POST['time'])).replace(tzinfo=utc) new_zephyr.pub_date = datetime.datetime.utcfromtimestamp(float(request.POST['time'])).replace(tzinfo=utc)
@@ -412,9 +406,9 @@ def change_settings(request):
old_password = request.POST['old_password'] old_password = request.POST['old_password']
new_password = request.POST['new_password'] new_password = request.POST['new_password']
confirm_password = request.POST['confirm_password'] confirm_password = request.POST['confirm_password']
full_name = sanitize_identifier(request.POST['full_name']) full_name = strip_html(request.POST['full_name'])
short_name = sanitize_identifier(request.POST['short_name']) short_name = strip_html(request.POST['short_name'])
timezone = sanitize_identifier(request.POST['timezone']) timezone = strip_html(request.POST['timezone'])
if new_password != "": if new_password != "":
if new_password != confirm_password: if new_password != confirm_password: