hasgeek / funnel

Website for hasgeek.com
https://hasgeek.com/
GNU Affero General Public License v3.0
47 stars 52 forks source link

Audit Jinja templates #2025

Closed jace closed 7 months ago

jace commented 7 months ago

Jinja templates are a source of runtime errors because they have no static analysis of syntax or variable typing. This PR introduces a declarative syntax for template files and their context variables, allowing for static checks:

  1. [x] Confirm the template file exists
  2. [x] Validate syntax of the template
  3. [x] Confirm all variables referenced from the template are declared with their expected type
  4. [ ] Perform static type checks of var usage in templates (this is advanced: intercept Jinja2 compiler, annotate AST with type definitions, generate Python source output, handover to Mypy for type check)
  5. [x] Ensure any call to render_template supplies all the expected variables (implemented with dataclass_transform)
  6. [ ] Solve for use in @render_with(template_file_name, ...)
jace commented 7 months ago

Sample output from flask shell, showing the template files and line numbers where variables are referenced without being supplied in the context:

>>> from pprint import pprint
>>> from funnel.views.index import IndexTemplate
>>> pprint(IndexTemplate.jinja_validate_vars())
{'index.html.jinja2': set(),
 'js/schedule.js.jinja2': set(),
 'layout.html.jinja2': {(15, 'title'),
                        (18, 'title_suffix'),
                        (75, 'account'),
                        (75, 'profile'),
                        (75, 'project'),
                        (226, 'query')},
 'macros.html.jinja2': {(220, 'path')},
 'profile_layout.html.jinja2': {(4, 'profile'),
                                (167, 'calendarwidget_compact'),
                                (493, 'profile')}}