On 6/02/2019 6:32 pm, Mike Dewhirst wrote:
On 6/02/2019 5:15 pm, 'Amitesh Sahay' via Django users wrote:

I have an existing django views.py where I have some password, username, and email validation logic applied. However, going forward I need to apply more advanced password validation. for e.g. password length limitation, uppercase sensitivity etc. I have a code written for advanced validation, but I am not able to apply them to my existing views.py.


You appear to be avoiding Django forms. Conventional wisdom says the best reason for using forms is to employ the built-in validation like this ...

from django.contrib.auth.forms import UserCreationForm

class MyUserCreationForm(UserCreationForm):
    """
https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#
    custom-users-and-the-built-in-auth-forms
    """
    first_name = forms.CharField(
        max_length=30,
        required=True,
        help_text='Required',
    )
    last_name = forms.CharField(
        max_length=30,
        required=True,
        help_text='Required'
    )
    username = forms.CharField(
        max_length=150,
        required=True,
        help_text='Required. Letters, digits and @/./+/-/_ only',
    )
    email = forms.EmailField(
        max_length=254,
        required=True,
        help_text='Required'
    )
    class Meta(UserCreationForm.Meta):
        model = User
        fields = [
            'first_name',
            'last_name',
            'username',
            'password1',
            'password2',
            'email',
        ]

    def __init__(self, *args, **kwargs):
        super(CommonUserCreationForm, self).__init__(*args, **kwargs)
        if 'first_name' in self.fields:
self.fields['first_name'].widget.attrs.update({'autofocus': True})


If you do that you can simplify your register_view() like this ...


from django.contrib.auth import get_user_model
from .forms import MyUserCreationForm    # sorry
# from .forms import CommonUserCreationForm

def register_view(request):
    if request.method == 'POST':
        form = MyUserCreationForm(request.POST)

        # don't like usernames which differ only by character case
        #
        username = form.data.get('username')
        User = get_user_model()
        try:
            user = User.objects.get(username__iexact=username)
            i_username = user.username
            if i_username.lower() == username.lower():
                form.add_error(
                    'username',
                    ValidationError('{0} already exists'.format(i_username))
                )
        except User.DoesNotExist:
            # DoesNotExist is the expected case
            pass
        #

        if form.is_valid():
            form.save()
            user = User.objects.get(username__iexact=username)
            user.username = form.cleaned_data.get('username')
            user.first_name = form.cleaned_data.get('first_name')
            user.last_name = form.cleaned_data.get('last_name')
            user.email = form.cleaned_data.get('email')
            user.save()
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=username, password=raw_password)
            auth_login(request, user)
            return redirect('myapp:index_view')
    else:
        form = MyUserCreationForm()
    return render(request, 'register.html', {'form': form})


And finally to answer your original question if you do something similar to the above you can add password validators *to be used in the form* in your settings module. Like this ...


# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        'OPTIONS': {
            'error_message': 'Password too short',
            'help_message': 'This password needs to be at least 23 characters',
        }
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
    {
        'NAME': 'pwned_passwords_django.validators.PwnedPasswordsValidator',
        'OPTIONS': {
            'error_message': 'Known insecure password',
            'help_message': 'That is a known insecure password and cannot be used here.',
        }
    },
]

Hope that helps

Mike


Below is the code from views.py

|from||||django.shortcuts ||import||||render,||||redirect|
|from||||django.contrib.auth.models ||import||||User|
|from||||django.contrib ||import||||messages|
|from||||.||||import||||validator|
|def||||register(request):|
|if||||request.method ==||||'POST'||:|
|first_name =||||request.POST[||'first_name'||]|
|last_name =||||request.POST[||'last_name'||]|
|email =||||request.POST[||'email'||]|
|username =||||request.POST[||'username'||]|
|password =||||request.POST[||'password'||,||||validator.||MinimumLengthValidator||]|
|password2 =||||request.POST[||'password2'||]|

|# check if the password match|
|if||||password ==||||password2:|

|if||||User||.objects.filter(username=username).exists():|
|messages.error(request,||||'username already exist'||)|
|return||||redirect(||'register'||)|
|else||:|
|if||||User||.objects.filter(email=email).exists():|
|messages.error(request,||||'Registration Failed - Try different email address'||)|
|return||||redirect(||'register'||)|
|else||:|
|user =||||User||.objects.create_user(username=username,||||password=password,||||email=email,|
|first_name=first_name,||||last_name=last_name)|
|user.save()|
|messages.success(request,||||'Registration complete, please proceed to login'||)|
|return||||redirect(||'register'||)|
|else||:|
|messages.error(request,||||'password dose not match'||)|
|return||||redirect(||'register'||)|
|else||:|
|return||||render(request,||||'ACCOUNTS/register.html'||)|

Below is the code for advanced password validation from validate.py

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

|class||||MinimumLengthValidator||:|
|def||||__init__(self,||||min_length=||8||):|
|self.min_length =||||min_length|

|def||||validate(self,||||password,||||user=||None||):|
|if||||len(password)||||<||||self.min_length:|
|raise||||ValidationError||(|
|_(||"This password must contain at least %(min_length)d characters."||),|
|code=||'password_too_short'||,|
|params={||'min_length'||:||||self.min_length},|
|)|

|def||||get_help_text(self):|
|return||||_(|
|"Your password must contain at least %(self.min_length)d characters."|
|%||||{||'min_length'||:||||self.min_length}|
|)|


|class||||NumberValidator||(object):|
|def||||validate(self,||||password,||||user=||None||):|
|if||||not||||re.findall(||'\d'||,||||password):|
|raise||||ValidationError||(|
|_(||"The password must contain at least %(min_digits)d digit(s), 0-9."||),|
|code=||'password_no_number'||,|
|)|

|def||||get_help_text(self):|
|return||||_(|
|"Your password must contain at least 1 digit, 0-9."|
|)|


|class||||UppercaseValidator||(object):|
|def||||validate(self,||||password,||||user=||None||):|
|if||||not||||re.findall(||'[A-Z]'||,||||password):|
|raise||||ValidationError||(|
|_(||"The password must contain at least 1 uppercase letter, A-Z."||),|
|code=||'password_no_upper'||,|
|)|

|def||||get_help_text(self):|
|return||||_(|
|"Your password must contain at least 1 uppercase letter, A-Z."|
|)|

I have tried below steps.

|I imported the validator.py ||in||||the views.py,||and||||tried to call the module.function inside the password field ||as||||below|

|password =||||request.POST[||'password'||,||||validator.||MinimumLengthValidator||]|

But that doesn't work. If I am right, I can write a mixin class and call it in my views.py. But I am using function based views. So, I am not sure if I can use mixin. Please suggest how can we achieve the desired result.

Regards,

Amitesh Sahay
*91-750 797 8619*
--
You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected] <mailto:[email protected]>. To post to this group, send email to [email protected] <mailto:[email protected]>.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/894430447.3071951.1549433756290%40mail.yahoo.com <https://groups.google.com/d/msgid/django-users/894430447.3071951.1549433756290%40mail.yahoo.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to the Google Groups "Django 
users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/ffb9cd61-7596-2118-6665-a0ac93ea5ff8%40dewhirst.com.au.
For more options, visit https://groups.google.com/d/optout.

Reply via email to