Consider adding CSP support - nonce attr for inline style/script elements
It would be great when calling rendering functions to be able to use nonce value string, ie. keyword nonce=... - which value then get used as nonce attribute in
The embedding will be then feasible in website using more strict CSP policy.
Possibly the nonce attr. might be useful in the
Once (hacky) way to handle this is:
import pygal
from pygal.svg import Svg # optional you can use fully specified name
pgSvg_add_styles = pygal.svg.Svg.add_styles
pgSvg_add_scripts = Svg.add_scripts
def new_add_styles(self, *args, **named_args):
pgSvg_add_styles(self, *args, **named_args)
for style in self.root.find('defs').findall('style'): # there is only one currently
style.set('nonce', self.graph.nonce)
def new_add_scripts(self, *args, **named_args):
pgSvg_add_scripts(self, *args, **named_args)
for script in self.root.find('defs').findall('script'): # there are two or more depending on self.graph.js.
script.set('nonce', self.graph.nonce)
pygal.svg.Svg.add_styles = new_add_styles
Svg.add_scripts = new_add_scripts
...
chart = pygal.Pie(config, # or Line, XY, BAR etc.
width=300,
height=300,
)
chart.nonce="xyzzyj"
...
svg = chart.render...
This isn't quite enough as the tooltip uses inline styles:
<g xmlns="http://www.w3.org/2000/svg" transform="translate(0 0)" style="opacity: 0; display: none;" class="tooltip"><rect rx="0" ry="0" width="0" height="0" class="tooltip-box"/><g class="text"/></g>
You may be able to get around this by adding:
sha256-Ph/DRJgQxC9kaAejV16+vexw0vvCmrIeynsT5eboVl4=
to your style-src csp so the style contents are allowed.
The patch to the source shouldn't be too bad. In add_styles and add_scripts if self.graph.nonce exists just add the nonce attribute to the nodes. The patch is left as an exercise for the reader.