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 django-users+unsubscr...@googlegroups.com <mailto:django-users+unsubscr...@googlegroups.com>. To post to this group, send email to django-users@googlegroups.com <mailto:django-users@googlegroups.com>.
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 django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
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