Commit 96f46153 authored by Serge S. Koval's avatar Serge S. Koval

Merge pull request #766 from pawl/fix_delete_csrf

fix index_view csrf value rendering
parents 10b2f19a c01277a3
...@@ -21,8 +21,8 @@ Getting started ...@@ -21,8 +21,8 @@ Getting started
To start using the form rendering rules, put a list of form field names into the `form_create_rules` To start using the form rendering rules, put a list of form field names into the `form_create_rules`
property one of your admin views:: property one of your admin views::
class RuleView(sqla.ModelView): class RuleView(sqla.ModelView):
form_create_rules = ('email', 'first_name', 'last_name') form_create_rules = ('email', 'first_name', 'last_name')
In this example, only three fields will be rendered and `email` field will be above other two fields. In this example, only three fields will be rendered and `email` field will be above other two fields.
...@@ -32,10 +32,10 @@ form field reference and creates a :class:`flask.ext.admin.form.rules.Field` cla ...@@ -32,10 +32,10 @@ form field reference and creates a :class:`flask.ext.admin.form.rules.Field` cla
Lets say we want to display some text between the `email` and `first_name` fields. This can be accomplished by Lets say we want to display some text between the `email` and `first_name` fields. This can be accomplished by
using the :class:`flask.ext.admin.form.rules.Text` class:: using the :class:`flask.ext.admin.form.rules.Text` class::
from flask.ext.admin.form import rules from flask.ext.admin.form import rules
class RuleView(sqla.ModelView): class RuleView(sqla.ModelView):
form_create_rules = ('email', rules.Text('Foobar'), 'first_name', 'last_name') form_create_rules = ('email', rules.Text('Foobar'), 'first_name', 'last_name')
Built-in rules Built-in rules
-------------- --------------
...@@ -58,44 +58,66 @@ Form Rendering Rule Description ...@@ -58,44 +58,66 @@ Form Rendering Rule Description
Enabling CSRF Validation Enabling CSRF Validation
--------------- ---------------
Adding CSRF validation will require overriding the :class:`flask.ext.admin.form.BaseForm` by using :attr:`flask.ext.admin.model.BaseModelView.form_base_class`.
Flask-Admin does not use Flask-WTF Form class - it uses the wtforms Form class, which does not have CSRF validation.
Adding CSRF validation will require importing flask_wtf and overriding the :class:`flask.ext.admin.form.BaseForm` by using :attr:`flask.ext.admin.model.BaseModelView.form_base_class`:: WTForms >=2::
import os from wtforms.csrf.session import SessionCSRF
import flask from wtforms.meta import DefaultMeta
**import flask_wtf** from flask import session
import flask_admin from datetime import timedelta
import flask_sqlalchemy from flask.ext.admin import form
from flask_admin.contrib.sqla import ModelView from flask.ext.admin.contrib import sqla
DBFILE = 'app.db' class SecureForm(form.BaseForm):
class Meta(DefaultMeta):
app = flask.Flask(__name__) csrf = True
app.config['SECRET_KEY'] = 'Dnit7qz7mfcP0YuelDrF8vLFvk0snhwP' csrf_class = SessionCSRF
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + DBFILE csrf_secret = b'EPj00jpfj8Gx1SjnyLxwBBSQfnQ9DJYe0Ym'
**app.config['CSRF_ENABLED'] = True** csrf_time_limit = timedelta(minutes=20)
**flask_wtf.CsrfProtect(app)** @property
db = flask_sqlalchemy.SQLAlchemy(app) def csrf_context(self):
admin = flask_admin.Admin(app, name='Admin') return session
## Here is the fix: class ModelAdmin(sqla.ModelView):
class MyModelView(ModelView): form_base_class = SecureForm
**form_base_class = flask_wtf.Form**
For WTForms 1, you can use use Flask-WTF's Form class::
class User(db.Model):
id = db.Column(db.Integer, primary_key=True) import os
username = db.Column(db.String) import flask
password = db.Column(db.String) import flask_wtf
import flask_admin
if not os.path.exists(DBFILE): import flask_sqlalchemy
db.create_all() from flask_admin.contrib.sqla import ModelView
## The subclass is used here: DBFILE = 'app.db'
admin.add_view( MyModelView(User, db.session, name='User') )
app = flask.Flask(__name__)
app.run(debug=True) app.config['SECRET_KEY'] = 'Dnit7qz7mfcP0YuelDrF8vLFvk0snhwP'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + DBFILE
app.config['CSRF_ENABLED'] = True
flask_wtf.CsrfProtect(app)
db = flask_sqlalchemy.SQLAlchemy(app)
admin = flask_admin.Admin(app, name='Admin')
class MyModelView(ModelView):
# Here is the fix:
form_base_class = flask_wtf.Form
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String)
password = db.Column(db.String)
if not os.path.exists(DBFILE):
db.create_all()
admin.add_view( MyModelView(User, db.session, name='User') )
app.run(debug=True)
Further reading Further reading
--------------- ---------------
......
...@@ -111,7 +111,7 @@ ...@@ -111,7 +111,7 @@
<input type="hidden" name="id" value="{{ get_pk_value(row) }}"/> <input type="hidden" name="id" value="{{ get_pk_value(row) }}"/>
<input type="hidden" name="url" value="{{ return_url }}"/> <input type="hidden" name="url" value="{{ return_url }}"/>
{% if delete_form.csrf_token %} {% if delete_form.csrf_token %}
<input type="hidden" name="csrf_token" value="{{ delete_form.csrf_token() }}"/> <input name="csrf_token" type="hidden" value="{{ delete_form.csrf_token._value() }}"/>
{% endif %} {% endif %}
<button onclick="return confirm('{{ _gettext('Are you sure you want to delete this record?') }}');" title="{{ _gettext('Delete record') }}"> <button onclick="return confirm('{{ _gettext('Are you sure you want to delete this record?') }}');" title="{{ _gettext('Delete record') }}">
<i class="icon-trash"></i> <i class="icon-trash"></i>
......
...@@ -111,7 +111,7 @@ ...@@ -111,7 +111,7 @@
<input type="hidden" name="id" value="{{ get_pk_value(row) }}"/> <input type="hidden" name="id" value="{{ get_pk_value(row) }}"/>
<input type="hidden" name="url" value="{{ return_url }}"/> <input type="hidden" name="url" value="{{ return_url }}"/>
{% if delete_form.csrf_token %} {% if delete_form.csrf_token %}
<input type="hidden" name="csrf_token" value="{{ delete_form.csrf_token() }}"/> <input name="csrf_token" type="hidden" value="{{ delete_form.csrf_token() }}"/>
{% endif %} {% endif %}
<button onclick="return confirm('{{ _gettext('Are you sure you want to delete this record?') }}');" title="Delete record"> <button onclick="return confirm('{{ _gettext('Are you sure you want to delete this record?') }}');" title="Delete record">
<span class="glyphicon glyphicon-trash"></span> <span class="glyphicon glyphicon-trash"></span>
......
...@@ -366,7 +366,7 @@ def test_csrf(): ...@@ -366,7 +366,7 @@ def test_csrf():
def get_csrf_token(data): def get_csrf_token(data):
data = data.split('name="csrf_token" type="hidden" value="')[1] data = data.split('name="csrf_token" type="hidden" value="')[1]
token = data.split('">')[0] token = data.split('"')[0]
return token return token
app, admin = setup() app, admin = setup()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment