Sebastien Bruggeman
Sebastien Bruggeman

Reputation: 33

Flask-Security Custom email validator

I've set up Flask-Security and I'm trying to an e-mail to be validated against lists in a database. I want to keep the current email validators and add a new one.

Below is the code that I'm adding to extend the registration form. But I'm not getting it to work at all the validator is just ignored. I've tried

class ExtendedRegisterForm(RegisterForm):
    email = StringField('Email', validators=[DataRequired()])

    def validate_email(form, field):
        domain = field.data.split('@')[1]
        regdomains = db.session.query(Company.id, Company.domain).filter(Company.domain != None).all()
        for row in regdomains:
            valid = (row.domain).find(domain)
            if valid != -1:
                validated = True
            else:
                continue
        if validated is not True:
            raise ValidationError('Email address must be from an authorised domain')
security = Security(app, user_datastore, register_form=ExtendedRegisterForm)

Upvotes: 2

Views: 1977

Answers (3)

jwag
jwag

Reputation: 807

By any chance do you have SECURITY_CONFIRMABLE enabled? If so, then the register endpoint uses the ConfirmRegisterForm..

Upvotes: 0

pjcunningham
pjcunningham

Reputation: 8046

Override the RegisterForm validate(self) method. You can see an example of this technique in the source code for LoginForm.

Example:

class ExtendedRegisterForm(RegisterForm):

    def validate(self):

        # Perform the default validation
        if not super(ExtendedRegisterForm, self).validate():
            return False

        # check against database if any "company" is registered with the given "domain" else raise an Exception

        # extract the domain from email
        domain = self.email.data.split('@')[1]

        registered_company = Company.query.filter_by(domain=domain).first()
        if registered_company is None:
            # the "company" is not registered thus not authorized 
            # then the given "email" is not validated
            # append error message to the email field
            self.email.errors.append("Company is not registered")
            return False

        #  all good
        return True

Upvotes: 0

cizario
cizario

Reputation: 4254

i assume you already installed email_validator (link on pypi)

i think you need to change your code a little bit like so

from flask_wtf import FlaskForm

from flask_security.forms import RegisterForm
[..]

from wtforms.fields.html5 import EmailField
from wtforms.validators import DataRequired, Email, ..


# @see https://pythonhosted.org/Flask-Security/customizing.html#forms
class ExtendedRegisterForm(RegisterForm):

    # email = StringField('Email', validators=[DataRequired()])
    email = EmailField('Email', validators=[DataRequired(), Email()])

    # def validate_email(form, field):
    def validate_email(self, field):

        # extract the domain from email
        domain = field.data.split('@')[1]


        # regdomains = db.session.query(Company.id, Company.domain).filter(Company.domain != None).all()
        # for row in regdomains:
            # valid = (row.domain).find(domain)
            # if valid != -1:
                # validated = True
            # else:
                # continue
        # if validated is not True:
            # raise ValidationError('Email address must be from an authorized domain')


        # check against database if any "company" is registered with the given "domain" else raise an Exception
        registred_company = Company.query.filter_by(domain=domain).first()
        if registred_company is None:
            # the "company" is not registered thus not authorized 
            # then the given "email" is not validated
            raise ValidationError('Email address must be from an authorised domain')

flask-security has flask-wtf (which depends on wtforms) as dependency so it releys on wtforms via inheritance mechanism regarding fields and validate_{field}(self, field) function to validate form fields.

see: https://github.com/mattupstate/flask-security/blob/develop/flask_security/forms.py

Upvotes: 0

Related Questions