Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
flask-admin
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Python-Dev
flask-admin
Commits
e53fb6c8
Commit
e53fb6c8
authored
Sep 17, 2015
by
Serge S. Koval
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1053 from pawl/actions_csrf
Simplify implementing CSRF validation by adding SecureForm
parents
128d5e00
46958eb0
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
45 additions
and
42 deletions
+45
-42
advanced.rst
doc/advanced.rst
+15
-0
introduction.rst
doc/introduction.rst
+0
-21
__init__.py
flask_admin/form/__init__.py
+27
-1
test_model.py
flask_admin/tests/test_model.py
+3
-20
No files found.
doc/advanced.rst
View file @
e53fb6c8
...
@@ -3,6 +3,21 @@
...
@@ -3,6 +3,21 @@
Advanced Functionality
Advanced Functionality
======================
======================
Enabling CSRF Validation
------------------------
To add CSRF protection to the forms that are generated by *ModelView* instances, use the
SecureForm class in your *ModelView* subclass by specifying the *form_base_class* parameter::
from flask_admin.form import SecureForm
from flask_admin.contrib.sqla import ModelView
class CarAdmin(ModelView):
form_base_class = SecureForm
SecureForm requires WTForms 2 or greater. It uses the WTForms SessionCSRF class
to generate the tokens for you, and validate them when the forms are submitted.
Localization With Flask-Babelex
Localization With Flask-Babelex
-------------------------------
-------------------------------
...
...
doc/introduction.rst
View file @
e53fb6c8
...
@@ -55,27 +55,6 @@ There are many options available for customizing the display and functionality o
...
@@ -55,27 +55,6 @@ There are many options available for customizing the display and functionality o
For more details on that, see :ref:`customising-builtin-views`. For more details on the other
For more details on that, see :ref:`customising-builtin-views`. For more details on the other
ORM backends that are available, see :ref:`database-backends`.
ORM backends that are available, see :ref:`database-backends`.
Enabling CSRF Validation
------------------------
To add CSRF protection to the forms that are generated by *ModelView* instances, use the
`FlaskWTF <https://flask-wtf.readthedocs.org/>`_ form class in your *ModelView*
subclass by specifying the *form_base_class* parameter::
from flask_admin.contrib.sqla import ModelView
import flask_wtf
# Flask and Flask-SQLAlchemy initialization here
app.config['CSRF_ENABLED'] = True
flask_wtf.CsrfProtect(app)
class MicroBlogModelView(ModelView):
form_base_class = flask_wtf.Form
The FlaskWTF form class comes with CSRF protection builtin, so it will generate
the tokens for you, and validate them when the forms are submitted.
Adding Content to the Index Page
Adding Content to the Index Page
--------------------------------
--------------------------------
The first thing you'll notice when you visit `http://localhost:5000/admin/ <http://localhost:5000/admin/>`_
The first thing you'll notice when you visit `http://localhost:5000/admin/ <http://localhost:5000/admin/>`_
...
...
flask_admin/form/__init__.py
View file @
e53fb6c8
from
wtforms
import
form
from
wtforms
import
form
,
__version__
as
wtforms_version
from
wtforms.fields.core
import
UnboundField
from
wtforms.fields.core
import
UnboundField
from
.fields
import
*
from
.fields
import
*
...
@@ -32,3 +32,29 @@ def recreate_field(unbound):
...
@@ -32,3 +32,29 @@ def recreate_field(unbound):
raise
ValueError
(
'recreate_field expects UnboundField instance,
%
s was passed.'
%
type
(
unbound
))
raise
ValueError
(
'recreate_field expects UnboundField instance,
%
s was passed.'
%
type
(
unbound
))
return
unbound
.
field_class
(
*
unbound
.
args
,
**
unbound
.
kwargs
)
return
unbound
.
field_class
(
*
unbound
.
args
,
**
unbound
.
kwargs
)
if
int
(
wtforms_version
[
0
])
>
1
:
# only WTForms 2+ has built-in CSRF functionality
from
os
import
urandom
from
flask
import
session
from
wtforms.csrf.session
import
SessionCSRF
class
SecureForm
(
BaseForm
):
"""
BaseForm with CSRF token generation and validation support.
Requires WTForms 2+
"""
class
Meta
:
csrf
=
True
csrf_class
=
SessionCSRF
csrf_secret
=
urandom
(
24
)
@
property
def
csrf_context
(
self
):
return
session
else
:
class
SecureForm
(
BaseForm
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
raise
Exception
(
"SecureForm requires WTForms 2+"
)
flask_admin/tests/test_model.py
View file @
e53fb6c8
...
@@ -2,7 +2,7 @@ import wtforms
...
@@ -2,7 +2,7 @@ import wtforms
from
nose.tools
import
eq_
,
ok_
from
nose.tools
import
eq_
,
ok_
from
flask
import
Flask
,
session
from
flask
import
Flask
from
werkzeug.wsgi
import
DispatcherMiddleware
from
werkzeug.wsgi
import
DispatcherMiddleware
from
werkzeug.test
import
Client
from
werkzeug.test
import
Client
...
@@ -349,28 +349,11 @@ def test_form():
...
@@ -349,28 +349,11 @@ def test_form():
@
wtforms2_and_up
@
wtforms2_and_up
def
test_csrf
():
def
test_csrf
():
from
datetime
import
timedelta
from
wtforms.csrf.session
import
SessionCSRF
from
wtforms.meta
import
DefaultMeta
# BaseForm w/ CSRF
class
SecureForm
(
form
.
BaseForm
):
class
Meta
(
DefaultMeta
):
csrf
=
True
csrf_class
=
SessionCSRF
csrf_secret
=
b
'EPj00jpfj8Gx1SjnyLxwBBSQfnQ9DJYe0Ym'
csrf_time_limit
=
timedelta
(
minutes
=
20
)
@
property
def
csrf_context
(
self
):
return
session
class
SecureModelView
(
MockModelView
):
class
SecureModelView
(
MockModelView
):
form_base_class
=
SecureForm
form_base_class
=
form
.
SecureForm
def
scaffold_form
(
self
):
def
scaffold_form
(
self
):
return
SecureForm
return
form
.
SecureForm
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
]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment