13

As the question above mentioned, I will trying to use a certain extra rule to validate a password during the registration process. The extra rule should be that a password is validate if it has at least one digit, one letter and one special character.

My approach to solute this problem I've created a file named validators.py.

from django.core.exceptions import ValidationError

class CustomPasswortValidator:

    def validate(value):

      # check for digit
      if not any(char.isdigit() for char in value):
          raise ValidationError(_('Password must contain at least 1 digit.'))

      # check for letter
      if not any(char.isalpha() for char in value):
          raise ValidationError(_('Password must contain at least 1 letter.'))

      # check for special character
      special_characters = "[~\!@#\$%\^&\*\(\)_\+{}\":;'\[\]]"
      if not any(char in special_characters for char in value):
        raise ValidationError(_('Password must contain at least 1 letter.'))

My custom registration form looks like this:

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User


class RegistrationForm(UserCreationForm):
    first_name = forms.CharField(max_length=30, required=False,                                         
                                 help_text='Optional.')
    last_name = forms.CharField(max_length=30, required=False, 
                                 help_text='Optional.')
    email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.')

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2', )

I don't get it how I tell django, that my custom password validator should be use beside the django AUTH_PASSWORD_VALIDATORS.

Texas
  • 559
  • 2
  • 6
  • 18
  • Your question is not clear. You want to use a custom password validator but you do not want to change `AUTH_PASSWORD_VALIDATORS` in settings.py? is that it? – e4c5 May 11 '17 at 13:09
  • Right, I don't want to change AUTH_PASSWORD_VALIDATORS. I want to create my own and just add it beside the others. – Texas May 11 '17 at 13:15
  • that statement doesn't clear things p – e4c5 May 11 '17 at 13:16
  • 1
    "and just add it beside the others. " if you look at the AUTH_PASSWORD_VALIDATORS it's a list. You are free to add your own validator there – e4c5 May 11 '17 at 13:16
  • What? xD Okay, may I don't get it. There are certain validators, referenced in settings.py. How can I add a extra rule to validate a password? Okay, and is the common way how I did it in the above file? – Texas May 11 '17 at 13:18
  • just google for `AUTH_PASSWORD_VALIDATORS` and you will see the documentaiton – e4c5 May 11 '17 at 13:27

1 Answers1

25

So, as e4c5 mentioned, it is really simple and straightforward.

My CustomPasswordValidator looks like this:

from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _

class CustomPasswordValidator():

    def __init__(self, min_length=1):
        self.min_length = min_length

    def validate(self, password, user=None):
        special_characters = "[~\!@#\$%\^&\*\(\)_\+{}\":;'\[\]]"
        if not any(char.isdigit() for char in password):
            raise ValidationError(_('Password must contain at least %(min_length)d digit.') % {'min_length': self.min_length})
        if not any(char.isalpha() for char in password):
            raise ValidationError(_('Password must contain at least %(min_length)d letter.') % {'min_length': self.min_length})
        if not any(char in special_characters for char in password):
            raise ValidationError(_('Password must contain at least %(min_length)d special character.') % {'min_length': self.min_length})

    def get_help_text(self):
        return ""

Just add it to the list of AUTH_PASSWORD_VALIDATORS in settings.py and that's it!

AUTH_PASSWORD_VALIDATORS = [
{
    'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
    'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
    'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
    'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
{   'NAME': 'registration.validators.CustomPasswordValidator',

},]
John R Perry
  • 3,916
  • 2
  • 38
  • 62
Texas
  • 559
  • 2
  • 6
  • 18