mirror of
https://github.com/wassname/flask-security.git
synced 2026-07-05 17:30:14 +08:00
Configurable forms, issue:49
This commit is contained in:
+32
-1
@@ -59,6 +59,37 @@ The following is a list of all the available context processor decorators:
|
||||
* ``send_login_context_processor``: Send login view
|
||||
|
||||
|
||||
Forms
|
||||
-----
|
||||
|
||||
All forms can be overridden in much the same way as context
|
||||
processors. For each form used, you can specify a function that
|
||||
returns the form class. This allows you to override/extend forms. For
|
||||
example, to add extra fields to the register form::
|
||||
|
||||
security = Security(app, user_datastore)
|
||||
|
||||
from flask_security.forms import RegisterForm
|
||||
|
||||
class ExtendedRegisterForm(RegisterForm):
|
||||
first_name = TextField('First Name', [Required()])
|
||||
last_name = TextField('Last Name', [Required()])
|
||||
|
||||
@security.register_form
|
||||
def security_register_form():
|
||||
return ExtendedRegisterForm
|
||||
|
||||
The following is a list of all the available form override decorators:
|
||||
|
||||
* ``login_form``: Login form
|
||||
* ``confirm_register_form``: Confirmable register form
|
||||
* ``register_form``: Register form
|
||||
* ``forgot_password_form``: Forgot password form
|
||||
* ``reset_password_form``: Reset password form
|
||||
* ``send_confirmation_form``: Send confirmation form
|
||||
* ``passwordless_login_form``: Passwordless login form
|
||||
|
||||
|
||||
Emails
|
||||
------
|
||||
|
||||
@@ -93,4 +124,4 @@ templates you can specify an email context processor with the
|
||||
# This processor is added to all emails
|
||||
@security.email_context_processor
|
||||
def security_mail_processor():
|
||||
return dict(hello="world")
|
||||
return dict(hello="world")
|
||||
|
||||
@@ -167,6 +167,7 @@ def _get_state(app, datastore, **kwargs):
|
||||
reset_serializer=_get_serializer(app, 'reset'),
|
||||
confirm_serializer=_get_serializer(app, 'confirm'),
|
||||
_context_processors={},
|
||||
_form_fns={},
|
||||
_send_mail_task=None
|
||||
))
|
||||
|
||||
@@ -236,6 +237,9 @@ class _SecurityState(object):
|
||||
rv.update(fn())
|
||||
return rv
|
||||
|
||||
def _get_form_cls(self, endpoint):
|
||||
return self._form_fns.get(endpoint, lambda: None)()
|
||||
|
||||
def context_processor(self, fn):
|
||||
self._add_ctx_processor(None, fn)
|
||||
|
||||
@@ -263,6 +267,27 @@ class _SecurityState(object):
|
||||
def send_mail_task(self, fn):
|
||||
self._send_mail_task = fn
|
||||
|
||||
def login_form(self, fn):
|
||||
self._form_fns['login_form'] = fn
|
||||
|
||||
def confirm_register_form(self, fn):
|
||||
self._form_fns['confirm_register_form'] = fn
|
||||
|
||||
def register_form(self, fn):
|
||||
self._form_fns['register_form'] = fn
|
||||
|
||||
def forgot_password_form(self, fn):
|
||||
self._form_fns['forgot_password_form'] = fn
|
||||
|
||||
def reset_password_form(self, fn):
|
||||
self._form_fns['reset_password_form'] = fn
|
||||
|
||||
def send_confirmation_form(self, fn):
|
||||
self._form_fns['send_confirmation_form'] = fn
|
||||
|
||||
def passwordless_login_form(self, fn):
|
||||
self._form_fns['passwordless_login_form'] = fn
|
||||
|
||||
|
||||
class Security(object):
|
||||
"""The :class:`Security` class initializes the Flask-Security extension.
|
||||
|
||||
+34
-11
@@ -35,6 +35,17 @@ _security = LocalProxy(lambda: current_app.extensions['security'])
|
||||
_datastore = LocalProxy(lambda: _security.datastore)
|
||||
|
||||
|
||||
_default_forms = {
|
||||
'login_form': LoginForm,
|
||||
'confirm_register_form': ConfirmRegisterForm,
|
||||
'register_form': RegisterForm,
|
||||
'forgot_password_form': ForgotPasswordForm,
|
||||
'reset_password_form': ResetPasswordForm,
|
||||
'send_confirmation_form': SendConfirmationForm,
|
||||
'passwordless_login_form': PasswordlessLoginForm,
|
||||
}
|
||||
|
||||
|
||||
def _render_json(form, include_auth_token=False):
|
||||
has_errors = len(form.errors) > 0
|
||||
|
||||
@@ -60,14 +71,20 @@ def _ctx(endpoint):
|
||||
return _security._run_ctx_processor(endpoint)
|
||||
|
||||
|
||||
def _form_cls(endpoint):
|
||||
return _security._get_form_cls(endpoint) or _default_forms[endpoint]
|
||||
|
||||
|
||||
@anonymous_user_required
|
||||
def login():
|
||||
"""View function for login view"""
|
||||
|
||||
form_class = _form_cls('login_form')
|
||||
|
||||
if request.json:
|
||||
form = LoginForm(MultiDict(request.json))
|
||||
form = form_class(MultiDict(request.json))
|
||||
else:
|
||||
form = LoginForm()
|
||||
form = form_class()
|
||||
|
||||
if form.validate_on_submit():
|
||||
login_user(form.user, remember=form.remember.data)
|
||||
@@ -101,9 +118,9 @@ def register():
|
||||
"""View function which handles a registration request."""
|
||||
|
||||
if _security.confirmable or request.json:
|
||||
form_class = ConfirmRegisterForm
|
||||
form_class = _form_cls('confirm_register_form')
|
||||
else:
|
||||
form_class = RegisterForm
|
||||
form_class = _form_cls('register_form')
|
||||
|
||||
if request.json:
|
||||
form_data = MultiDict(request.json)
|
||||
@@ -136,10 +153,12 @@ def register():
|
||||
def send_login():
|
||||
"""View function that sends login instructions for passwordless login"""
|
||||
|
||||
form_class = _form_cls('passwordless_login_form')
|
||||
|
||||
if request.json:
|
||||
form = PasswordlessLoginForm(MultiDict(request.json))
|
||||
form = form_class(MultiDict(request.json))
|
||||
else:
|
||||
form = PasswordlessLoginForm()
|
||||
form = form_class()
|
||||
|
||||
if form.validate_on_submit():
|
||||
send_login_instructions(form.user)
|
||||
@@ -179,10 +198,12 @@ def token_login(token):
|
||||
def send_confirmation():
|
||||
"""View function which sends confirmation instructions."""
|
||||
|
||||
form_class = _form_cls('send_confirmation_form')
|
||||
|
||||
if request.json:
|
||||
form = SendConfirmationForm(MultiDict(request.json))
|
||||
form = form_class(MultiDict(request.json))
|
||||
else:
|
||||
form = SendConfirmationForm()
|
||||
form = form_class()
|
||||
|
||||
if form.validate_on_submit():
|
||||
send_confirmation_instructions(form.user)
|
||||
@@ -225,10 +246,12 @@ def confirm_email(token):
|
||||
def forgot_password():
|
||||
"""View function that handles a forgotten password request."""
|
||||
|
||||
form_class = _form_cls('forgot_password_form')
|
||||
|
||||
if request.json:
|
||||
form = ForgotPasswordForm(MultiDict(request.json))
|
||||
form = form_class(MultiDict(request.json))
|
||||
else:
|
||||
form = ForgotPasswordForm()
|
||||
form = form_class()
|
||||
|
||||
if form.validate_on_submit():
|
||||
send_reset_password_instructions(form.user)
|
||||
@@ -257,7 +280,7 @@ def reset_password(token):
|
||||
if invalid or expired:
|
||||
return redirect(url_for('forgot_password'))
|
||||
|
||||
form = ResetPasswordForm()
|
||||
form = _form_cls('reset_password_form')()
|
||||
|
||||
if form.validate_on_submit():
|
||||
after_this_request(_commit)
|
||||
|
||||
Reference in New Issue
Block a user