mirror of
https://github.com/wassname/flask-security.git
synced 2026-06-27 16:10:11 +08:00
b15736accd
It adds a to_dict function that uses inspect to add all wtf Field to the returned dict. This allows extensions to the register form to easily add fields that will be passed to the datastore's create_user function.
191 lines
5.5 KiB
Python
191 lines
5.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
flask.ext.security.forms
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Flask-Security forms module
|
|
|
|
:copyright: (c) 2012 by Matt Wright.
|
|
:license: MIT, see LICENSE for more details.
|
|
"""
|
|
|
|
import inspect
|
|
|
|
from flask import request, current_app
|
|
from flask.ext.wtf import Form as BaseForm, TextField, PasswordField, \
|
|
SubmitField, HiddenField, Required, BooleanField, EqualTo, Email, \
|
|
ValidationError, Length, Field
|
|
from werkzeug.local import LocalProxy
|
|
|
|
from .confirmable import requires_confirmation
|
|
from .utils import verify_password, get_message
|
|
|
|
# Convenient reference
|
|
_datastore = LocalProxy(lambda: current_app.extensions['security'].datastore)
|
|
|
|
email_required = Required(message='Email not provided')
|
|
|
|
email_validator = Email(message='Invalid email address')
|
|
|
|
password_required = Required(message="Password not provided")
|
|
|
|
|
|
def unique_user_email(form, field):
|
|
if _datastore.find_user(email=field.data) is not None:
|
|
raise ValidationError(field.data +
|
|
' is already associated with an account')
|
|
|
|
|
|
def valid_user_email(form, field):
|
|
form.user = _datastore.find_user(email=field.data)
|
|
if form.user is None:
|
|
raise ValidationError('Specified user does not exist')
|
|
|
|
|
|
class Form(BaseForm):
|
|
def __init__(self, *args, **kwargs):
|
|
kwargs.setdefault('csrf_enabled', not current_app.testing)
|
|
super(Form, self).__init__(*args, **kwargs)
|
|
|
|
|
|
class EmailFormMixin():
|
|
email = TextField("Email Address",
|
|
validators=[email_required,
|
|
email_validator])
|
|
|
|
|
|
class UserEmailFormMixin():
|
|
user = None
|
|
email = TextField("Email Address",
|
|
validators=[email_required,
|
|
email_validator,
|
|
valid_user_email])
|
|
|
|
|
|
class UniqueEmailFormMixin():
|
|
email = TextField("Email Address",
|
|
validators=[email_required,
|
|
email_validator,
|
|
unique_user_email])
|
|
|
|
|
|
class PasswordFormMixin():
|
|
password = PasswordField("Password",
|
|
validators=[password_required])
|
|
|
|
|
|
class NewPasswordFormMixin():
|
|
password = PasswordField("Password",
|
|
validators=[password_required,
|
|
Length(min=6, max=128)])
|
|
|
|
class PasswordConfirmFormMixin():
|
|
password_confirm = PasswordField("Retype Password",
|
|
validators=[EqualTo('password', message="Passwords do not match")])
|
|
|
|
|
|
class NextFormMixin():
|
|
next = HiddenField()
|
|
|
|
|
|
class RegisterFormMixin():
|
|
submit = SubmitField("Register")
|
|
|
|
def to_dict(form):
|
|
fields = inspect.getmembers(form, lambda member: isinstance(member, Field))
|
|
return dict((key, value.data) for key, value in fields)
|
|
|
|
|
|
class SendConfirmationForm(Form, UserEmailFormMixin):
|
|
"""The default forgot password form"""
|
|
|
|
submit = SubmitField("Resend Confirmation Instructions")
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(SendConfirmationForm, self).__init__(*args, **kwargs)
|
|
if request.method == 'GET':
|
|
self.email.data = request.args.get('email', None)
|
|
|
|
def validate(self):
|
|
if not super(SendConfirmationForm, self).validate():
|
|
return False
|
|
if self.user.confirmed_at is not None:
|
|
self.email.errors.append(get_message('ALREADY_CONFIRMED')[0])
|
|
return False
|
|
return True
|
|
|
|
|
|
class ForgotPasswordForm(Form, UserEmailFormMixin):
|
|
"""The default forgot password form"""
|
|
|
|
submit = SubmitField("Recover Password")
|
|
|
|
|
|
class PasswordlessLoginForm(Form, UserEmailFormMixin):
|
|
"""The passwordless login form"""
|
|
|
|
submit = SubmitField("Send Login Link")
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(PasswordlessLoginForm, self).__init__(*args, **kwargs)
|
|
|
|
def validate(self):
|
|
if not super(PasswordlessLoginForm, self).validate():
|
|
return False
|
|
if not self.user.is_active():
|
|
self.email.errors.append(get_message('DISABLED_ACCOUNT')[0])
|
|
return False
|
|
return True
|
|
|
|
|
|
class LoginForm(Form, NextFormMixin):
|
|
"""The default login form"""
|
|
email = TextField('Email Address')
|
|
password = PasswordField('Password')
|
|
remember = BooleanField("Remember Me")
|
|
submit = SubmitField("Login")
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(LoginForm, self).__init__(*args, **kwargs)
|
|
|
|
def validate(self):
|
|
super(LoginForm, self).validate()
|
|
|
|
if self.email.data.strip() == '':
|
|
self.email.errors.append('Email not provided')
|
|
return False
|
|
|
|
if self.password.data.strip() == '':
|
|
self.password.errors.append('Password not provided')
|
|
return False
|
|
|
|
self.user = _datastore.find_user(email=self.email.data)
|
|
|
|
if self.user is None:
|
|
self.email.errors.append('Specified user does not exist')
|
|
return False
|
|
if not verify_password(self.password.data, self.user.password):
|
|
self.password.errors.append('Invalid password')
|
|
return False
|
|
if requires_confirmation(self.user):
|
|
self.email.errors.append(get_message('CONFIRMATION_REQUIRED')[0])
|
|
return False
|
|
if not self.user.is_active():
|
|
self.email.errors.append(get_message('DISABLED_ACCOUNT')[0])
|
|
return False
|
|
return True
|
|
|
|
|
|
class ConfirmRegisterForm(Form, RegisterFormMixin,
|
|
UniqueEmailFormMixin, NewPasswordFormMixin):
|
|
pass
|
|
|
|
class RegisterForm(ConfirmRegisterForm, PasswordConfirmFormMixin):
|
|
pass
|
|
|
|
|
|
class ResetPasswordForm(Form, NewPasswordFormMixin, PasswordConfirmFormMixin):
|
|
"""The default reset password form"""
|
|
|
|
submit = SubmitField("Reset Password")
|