Coverage for website/thaliawebsite/templatetags/bleach_tags.py: 90.48%
17 statements
« prev ^ index » next coverage.py v7.6.7, created at 2025-08-14 10:31 +0000
« prev ^ index » next coverage.py v7.6.7, created at 2025-08-14 10:31 +0000
1"""Bleach allows to clean up user input to make it safe to display, but allow some HTML."""
3from django import template
4from django.template.defaultfilters import stringfilter
5from django.utils.safestring import mark_safe
7from bleach import clean
8from bleach.css_sanitizer import CSSSanitizer
10register = template.Library()
13def _allow_iframe_attrs(tag, name, value):
14 """Filter to allow certain attributes for tags.
16 :param tag: the tag
17 :param name: the attribute name
18 :param value: the value of the item.
19 """
20 # these are fine
21 if name in ("class", "width", "height", "frameborder", "allowfullscreen"):
22 return True
24 # youtube is allowed to have `src`
25 if tag == "iframe" and name == "src": 25 ↛ 33line 25 didn't jump to line 33 because the condition on line 25 was always true
26 return value.startswith(
27 (
28 "https://www.youtube.com/embed/",
29 "https://www.youtube-nocookie.com/embed/",
30 )
31 )
33 return False
36@register.filter(is_safe=True)
37@stringfilter
38def bleach(value):
39 """Bleach dangerous html from the input.
41 Examples::
43 >>> bleach('<script></script>')
44 ''
45 >>> bleach('simple')
46 'simple'
47 >>> bleach('<a href="http://example.com/">ex</a>')
48 '<a href="http://example.com/">ex</a>'
49 >>> bleach('<div class="bla"></div>')
50 '<div class="bla"></div>'
51 >>> bleach('<img src="https://i.redd.it/22kypw2l93gz.jpg" alt="bees">')
52 '<img src="https://i.redd.it/22kypw2l93gz.jpg" alt="bees">'
53 >>> bleach('<iframe width="560" height="315" '
54 ... 'src="https://www.youtube.com/embed/dQw4w9WgXcQ?rel=0" '
55 ... 'frameborder="0" allowfullscreen></iframe>')
56 '<iframe width="560" height="315" src="https://www.youtube.com/embed/dQw4w9WgXcQ?rel=0" frameborder="0" allowfullscreen=""></iframe>'
57 >>> bleach('<iframe src="https://clearlyreta.rded.nl/ivo/"></iframe>')
58 '<iframe></iframe>'
59 """
60 css_sanitizer = CSSSanitizer(allowed_css_properties=["text-decoration"])
61 return mark_safe(
62 clean(
63 value,
64 tags={
65 "h2",
66 "h3",
67 "p",
68 "a",
69 "div",
70 "strong",
71 "em",
72 "i",
73 "b",
74 "ul",
75 "li",
76 "br",
77 "ol",
78 "iframe",
79 "img",
80 "span",
81 },
82 attributes={
83 "*": ["class", "style"],
84 "iframe": _allow_iframe_attrs,
85 "a": ["href", "rel", "target", "title"],
86 "img": ["alt", "title", "src"],
87 },
88 css_sanitizer=css_sanitizer,
89 strip=True,
90 )
91 )