Format fix
This commit is contained in:
parent
56844d93f2
commit
db1503ad7b
@ -19,24 +19,32 @@ from openslides.utils.person import PersonFormField, MultiplePersonFormField
|
||||
from .models import Motion, Category
|
||||
|
||||
|
||||
class BaseMotionForm(CleanHtmlFormMixin, forms.ModelForm, CssClassMixin):
|
||||
"""Base FormClass for a Motion.
|
||||
class BaseMotionForm(CleanHtmlFormMixin, CssClassMixin, forms.ModelForm):
|
||||
"""
|
||||
Base FormClass for a Motion.
|
||||
|
||||
For it's own, it append the version data to the fields.
|
||||
|
||||
The class can be mixed with the following mixins to add fields for the
|
||||
submitter, supporters etc.
|
||||
"""
|
||||
clean_html_fields = ('text', 'reason')
|
||||
|
||||
title = forms.CharField(widget=forms.TextInput(), label=_("Title"))
|
||||
"""Title of the motion. Will be saved in a MotionVersion object."""
|
||||
"""
|
||||
Title of the motion. Will be saved in a MotionVersion object.
|
||||
"""
|
||||
|
||||
text = forms.CharField(widget=forms.Textarea(), label=_("Text"))
|
||||
"""Text of the motion. Will be saved in a MotionVersion object."""
|
||||
"""
|
||||
Text of the motion. Will be saved in a MotionVersion object.
|
||||
"""
|
||||
|
||||
reason = forms.CharField(
|
||||
widget=forms.Textarea(), required=False, label=_("Reason"))
|
||||
"""Reason of the motion. will be saved in a MotionVersion object."""
|
||||
"""
|
||||
Reason of the motion. will be saved in a MotionVersion object.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Motion
|
||||
@ -52,12 +60,6 @@ class BaseMotionForm(CleanHtmlFormMixin, forms.ModelForm, CssClassMixin):
|
||||
self.initial['reason'] = self.motion.reason
|
||||
super(BaseMotionForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def get_clean_html_fields(self):
|
||||
'''
|
||||
The fields 'text' and 'reason' contain HTML, clean them
|
||||
'''
|
||||
return ('text', 'reason',)
|
||||
|
||||
|
||||
class MotionSubmitterMixin(forms.ModelForm):
|
||||
"""Mixin to append the submitter field to a MotionForm."""
|
||||
|
@ -3,33 +3,33 @@
|
||||
*/
|
||||
$(function() {
|
||||
var ck_options = {
|
||||
|
||||
|
||||
// Using a custom CSS file allows us to specifically style elements entered
|
||||
// using the editor. Using the CSS prefix class .ckeditor_html prevents these
|
||||
// styles from meddling with the main layout
|
||||
|
||||
|
||||
contentsCss: "/static/styles/ckeditor.css",
|
||||
bodyClass: "ckeditor_html",
|
||||
|
||||
|
||||
allowedContent:
|
||||
'h1 h2 h3 pre blockquote b i u strike;' +
|
||||
|
||||
|
||||
// A workaround for the problem described in http://dev.ckeditor.com/ticket/10192
|
||||
// Hopefully, the problem will be solved in the final version of CKEditor 4.1
|
||||
// If so, then {margin-left} can be removed
|
||||
'p{margin-left};' +
|
||||
|
||||
|
||||
'a[!href];' +
|
||||
'table tr th td caption;' +
|
||||
'ol ul li;' +
|
||||
'span{!font-family};' +
|
||||
'span{!color};',
|
||||
removePlugins: "save, print, preview, pagebreak, templates, showblocks, magicline",
|
||||
|
||||
|
||||
// Not part of the standard package of CKEditor
|
||||
// http://ckeditor.com/addon/insertpre
|
||||
extraPlugins: "insertpre",
|
||||
|
||||
|
||||
toolbar_Full: [
|
||||
{ name: 'document', items : [ 'Source','-','Save','DocProps','Preview','Print','-','Templates' ] },
|
||||
{ name: 'clipboard', items : [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ] },
|
||||
@ -44,10 +44,6 @@ $(function() {
|
||||
toolbar: 'Full'
|
||||
};
|
||||
|
||||
// Override the tags 'strong' and 'em' so that reportlab can read it
|
||||
CKEDITOR.config.coreStyles_bold = { element : 'b', overrides : 'strong' };
|
||||
CKEDITOR.config.coreStyles_italic = { element : 'i', overrides : 'em' };
|
||||
|
||||
CKEDITOR.replace('id_text', ck_options);
|
||||
CKEDITOR.replace('id_reason', ck_options);
|
||||
});
|
||||
});
|
||||
|
@ -13,15 +13,16 @@
|
||||
import bleach
|
||||
|
||||
from django import forms
|
||||
from django.views.generic.edit import FormMixin
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy
|
||||
|
||||
|
||||
# Allowed tags, attributes and styles allowed in textareas edited with a JS
|
||||
# editor. Everything not in these whitelists is stripped.
|
||||
HTML_TAG_WHITELIST = ('a',
|
||||
'i',
|
||||
'em',
|
||||
'b',
|
||||
'strong',
|
||||
'ul',
|
||||
'ol',
|
||||
'li',
|
||||
@ -36,11 +37,10 @@ HTML_TAG_WHITELIST = ('a',
|
||||
'h3',)
|
||||
|
||||
HTML_ATTRIBUTES_WHITELIST = {
|
||||
'*': ['style'],
|
||||
'a': ['href'],
|
||||
}
|
||||
|
||||
HTML_STYLES_WHITELIST = ('text-decoration',)
|
||||
HTML_STYLES_WHITELIST = ()
|
||||
|
||||
|
||||
class CssClassMixin(object):
|
||||
@ -60,26 +60,27 @@ class LocalizedModelMultipleChoiceField(forms.ModelMultipleChoiceField):
|
||||
c = []
|
||||
for (id, text) in super(LocalizedModelMultipleChoiceField, self)._get_choices():
|
||||
text = text.split(' | ')[-1]
|
||||
c.append((id, _(text)))
|
||||
c.append((id, ugettext_lazy(text)))
|
||||
return c
|
||||
|
||||
choices = property(_localized_get_choices, forms.ChoiceField._set_choices)
|
||||
|
||||
|
||||
class CleanHtmlFormMixin(FormMixin):
|
||||
'''
|
||||
class CleanHtmlFormMixin(object):
|
||||
"""
|
||||
A form mixin that pre-processes the form, cleaning up the HTML code found
|
||||
in the fields in clean_html. All HTML tags, attributes and styles not in the
|
||||
whitelists are stripped from the output, leaving only the text content:
|
||||
|
||||
<table><tr><td>foo</td></tr></table> simply becomes 'foo'
|
||||
'''
|
||||
"""
|
||||
clean_html_fields = ()
|
||||
|
||||
def get_clean_html_fields(self):
|
||||
'''
|
||||
the list of elements to strip of potential malicious HTML
|
||||
'''
|
||||
return()
|
||||
"""
|
||||
The list of elements to strip of potential malicious HTML.
|
||||
"""
|
||||
return self.clean_html_fields
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(CleanHtmlFormMixin, self).clean()
|
||||
@ -89,7 +90,4 @@ class CleanHtmlFormMixin(FormMixin):
|
||||
attributes=HTML_ATTRIBUTES_WHITELIST,
|
||||
styles=HTML_STYLES_WHITELIST,
|
||||
strip=True)
|
||||
|
||||
# Needed for reportlab
|
||||
cleaned_data[field] = cleaned_data[field].replace('<br>', '</br>')
|
||||
return cleaned_data
|
||||
|
@ -45,7 +45,6 @@ PAGE_WIDTH = defaultPageSize[0]
|
||||
stylesheet = StyleSheet1()
|
||||
stylesheet.add(ParagraphStyle(
|
||||
name='Normal',
|
||||
#fontName='Ubuntu',
|
||||
fontSize=10,
|
||||
leading=12,
|
||||
))
|
||||
|
@ -1,12 +1,12 @@
|
||||
# Requirements for OpenSlides Core
|
||||
Django==1.5.1
|
||||
django-mptt==0.5.5
|
||||
beautifulsoup4==4.1.3
|
||||
bleach==1.2.1
|
||||
pillow==2.0.0
|
||||
qrcode==2.7
|
||||
reportlab==2.7
|
||||
tornado==3.0.1
|
||||
bleach==1.2.1
|
||||
beautifulsoup4==4.1.3
|
||||
|
||||
# required for travis
|
||||
Fabric==1.6.0
|
||||
|
0
tests/forms/__init__.py
Normal file
0
tests/forms/__init__.py
Normal file
@ -1,33 +1,26 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Unit test for OpenSlides __init__.py
|
||||
Test the openslides forms.
|
||||
|
||||
:copyright: 2011, 2012, 2013 by the OpenSlides team, see AUTHORS.
|
||||
:license: GNU GPL, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
from django import forms
|
||||
from django.db import models
|
||||
|
||||
from openslides.utils.test import TestCase
|
||||
from openslides.utils.forms import CleanHtmlFormMixin
|
||||
from openslides.motion.models import Motion
|
||||
|
||||
|
||||
class HtmlTestForm(CleanHtmlFormMixin, forms.Form):
|
||||
text = forms.CharField()
|
||||
text2 = forms.CharField()
|
||||
|
||||
def get_clean_html_fields(self):
|
||||
'''
|
||||
The field 'text' contains HTML, clean it
|
||||
'''
|
||||
return ('text', )
|
||||
clean_html_fields = ('text',)
|
||||
|
||||
|
||||
class CleanHtmlTest(TestCase):
|
||||
|
||||
def clean_html(self, dirty='', clean=False):
|
||||
form = HtmlTestForm({'text': dirty, 'text2': dirty})
|
||||
form.is_valid()
|
||||
@ -38,31 +31,31 @@ class CleanHtmlTest(TestCase):
|
||||
|
||||
# Something was removed
|
||||
else:
|
||||
self.assertEqual(form.cleaned_data['text'], cleaned)
|
||||
self.assertEqual(form.cleaned_data['text'], clean)
|
||||
|
||||
# Field text2 has the same content, but is never passed through the
|
||||
# HTML-cleanup and should never change
|
||||
self.assertEqual(form.cleaned_data['text2'], dirty)
|
||||
|
||||
def test_clean_html(self):
|
||||
'''
|
||||
"""
|
||||
Test that the correct HTML tags and attributes are removed
|
||||
'''
|
||||
"""
|
||||
|
||||
# Forbidden tags and attributes
|
||||
self.clean_html('<script>do_evil();</script>', 'do_evil();')
|
||||
self.clean_html('<html>evil</html>', 'evil')
|
||||
self.clean_html('<a href="evil.com">good?</a>', 'good?')
|
||||
self.clean_html('<p href="evil.com">good?</p>', '<p>good?</p>')
|
||||
self.clean_html('<p onclick="javascript:evil();">Not evil</p>', '<p>Not evil</p>')
|
||||
self.clean_html('<div style="margin-top: 100000em;">evil</div>', 'evil')
|
||||
self.clean_html('<p style="font-weight:bold;">bad</p>', '<p style="">bad</p>')
|
||||
self.clean_html('<p style="font-weight:bold;">bad</p>', '<p>bad</p>')
|
||||
self.clean_html('<table><tbody><tr><td>OK</td></tr></tbody></table>', 'OK')
|
||||
self.clean_html('<blockquote>OK</blockquote>', 'OK')
|
||||
self.clean_html('<p style="text-decoration: underline;">OK</p>', '<p>OK</p>')
|
||||
|
||||
# Allowed tags and attributes
|
||||
self.clean_html('<a href="evil.com">good?</a>')
|
||||
self.clean_html('<p>OK</p>')
|
||||
self.clean_html('<table><tbody><tr><td>OK</td></tr></tbody></table>')
|
||||
self.clean_html('<p><strong>OK</strong></p>')
|
||||
self.clean_html('<pre>OK</pre>')
|
||||
self.clean_html('<blockquote>OK</blockquote>')
|
||||
self.clean_html('<ul><li>OK</li></ul>')
|
||||
self.clean_html('<p style="text-decoration: underline;">OK</p>')
|
||||
|
Loading…
Reference in New Issue
Block a user