Torsten Irländer  committed 5760b9e

Added support for CSRF protection. Added csrf_token parameter on
form initialisation to render a additional hidden field in the form with the
given token value.

  • Participants
  • Parent commits 480f513

Comments (0)

Files changed (3)

 - Improved "tabbing" in forms. Markers for required fields aren't links
   anymore which are tabable.
+- Added support for CSRF protection. The form can now be initialised with a
+  token for CSRF protection which is rendered as hidden field in the forms.

File formbar/

     def __init__(self, config, item=None, dbsession=None, translate=None,
-                 change_page_callback={}, renderers={}, request=None):
+                 change_page_callback={}, renderers={}, request=None,
+                 csrf_token=None):
         """Initialize the form with ``Form`` configuration instance and
         optional an SQLAlchemy mapped object.
         :request: Current request (See
         when using in connection with ringo)
+        :csrf_token: Token to which will be included as hidden field in
+        the form to prevent CSRF attacks.
         self._config = config
         self._item = item
         self._dbsession = dbsession
         self._request = request
+        self._csrf_token = csrf_token
         if translate:
             self._translate = translate
         # has the serialized data of the loaded item (GET) or the
         # submitted error data on POST.
         if self.validated and not self.has_errors():
-            return htmlfill.render(form, values or self.serialize(
-        return htmlfill.render(form, values or
+            values = values or self.serialize(
+        else:
+            values = values or
+        # Add csrf_token to the values dictionary
+        values['csrf_token'] = self._csrf_token
+        return htmlfill.render(form, values)
     def _add_error(self, fieldname, error):
         field = self.get_field(fieldname)

File formbar/

         html.append('<form id="%(id)s" class="%(css)s" '
                     'method="%(method)s" action="%(action)s" '
                     'autocomplete="%(autocomplete)s" enctype="%(enctype)s">' % attr)
+        # Add hidden field with csrf_token if this is not None.
+        if self._form._csrf_token:
+            html.append('<input type="hidden" name="csrf_token" value="%s"/>'
+                        % self._form._csrf_token)
         return "".join(html)
     def _render_form_body(self):