Custom password validation

287 views
Skip to first unread message

Larry Martell

unread,
Apr 10, 2015, 3:15:17 PM4/10/15
to django...@googlegroups.com
I am trying to add custom password validation to the create user and
change password admin forms. I did not see anything in the django docs
about how to do this. From what I read on stackoverflow and other
sites it seems I have to write a validator and then someone hook it
into the add and change forms.

Here's what I have now in my apps admin.py:

def validate_password_strength(value):
"""Validates that a password is as least 10 characters long and has at least
2 digits and 1 Upper case letter.
"""
min_length = 10

if len(value) < min_length:
raise ValidationError(_('Password must be at least {0} characters '
'long.').format(min_length))

# check for 2 digits
if sum(c.isdigit() for c in value) < 2:
raise ValidationError(_('Password must container at least 2 digits.'))

# check for uppercase letter
if not any(c.isupper() for c in value):
raise ValidationError(_('Password must container at least 1
uppercase letter.'))

class MySetPasswordForm(SetPasswordForm):
def __init__(self, *args, **kwargs):
super(MySetPasswordForm, self).__init__(*args, **kwargs)
self.fields['password1'].validators.append(validate_password_strength)

But what I can't figure out is how do I get MySetPasswordForm to be
used. Can anyone help me with this. If i am way off base, can someone
point me in the right direction. Thanks!

Larry Martell

unread,
Apr 10, 2015, 6:40:26 PM4/10/15
to django...@googlegroups.com
I've tried a few different things. First I did this:

class UserAdmin(UserAdmin):
form = MySetPasswordForm

# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)

And I got this error:

<class 'elex_apis.energy.webservice.admin.UserAdmin'>: (admin.E016)
The value of 'form' must inherit from 'BaseModelForm'.

So then I changed MySetPasswordForm to inherit from BaseModelForm and
then I got this error:

__init__() missing 1 required positional argument: 'user'

So then I added the user param so now MySetPasswordForm looked like this:

class MySetPasswordForm(BaseModelForm):
def __init__(self, user, *args, **kwargs):
super(MySetPasswordForm, self).__init__(user, *args, **kwargs)
self.fields['password1'].validators.append(validate_password_strength)

But I still got the same error as before.

I can't believe it's this hard to add a password validator. It must be
a very common need, so clearly I must be missing something simple. Can
anyone please provide some assistance here.

Helton Alves

unread,
Apr 10, 2015, 11:16:41 PM4/10/15
to django...@googlegroups.com
hey man, how are you ?

I don't know if I understand very well, but you can try make a custom user and in forms file you can do the validation that you need. :D

if that's right, you can follow this example:

--
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...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CACwCsY7e%3DkTtvs71PdDG66h1X%3DisWGCgjs7LdpXFtG-n3hRjDQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Larry Martell

unread,
Apr 11, 2015, 7:57:17 AM4/11/15
to django...@googlegroups.com


On Friday, April 10, 2015, Helton Alves <homemcoi...@gmail.com> wrote:
hey man, how are you ?

I don't know if I understand very well, but you can try make a custom user and in forms file you can do the validation that you need. :D

if that's right, you can follow this example:

I appreciate the reply but no this doesn't really help. I do not want to nor should I need to replace the entire user model just to add password validation. This violates the DRY principle and I just can't believe there is not an easier way to do this. But thanks for replying.


To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CABcoSmCTX8oOKJ5wsJXaS3b%3DfgfTPwKo6n1e68cVFfdiL-Zi6A%40mail.gmail.com.

Frank Bieniek

unread,
Apr 14, 2015, 4:18:13 AM4/14/15
to django...@googlegroups.com
Hi Larry,

You could configure the routes in the urls.py, take the create user route and plug in your CustomPasswordForm...
...
customization example of the userena urls for the normal frontend

... url(r'^(?P<username>[\.\w]+)/password/$',
        userena_views.password_change, {"pass_form": PasswordChangeForm},
        name = 'userena_password_change'),
...

cheers
Frank

Larry Martell

unread,
Apr 14, 2015, 8:05:04 AM4/14/15
to django...@googlegroups.com
On Tue, Apr 14, 2015 at 4:18 AM, Frank Bieniek
<frank....@googlemail.com> wrote:
> Hi Larry,
>
> You could configure the routes in the urls.py, take the create user route
> and plug in your CustomPasswordForm...
> ...
> customization example of the userena urls for the normal frontend
>
> ... url(r'^(?P<username>[\.\w]+)/password/$',
> userena_views.password_change, {"pass_form": PasswordChangeForm},
> name = 'userena_password_change'),

With some help I was able to get this working. As I suspected, it was
very simple:

class AdminPasswordChangeForm(auth_forms.AdminPasswordChangeForm):
def clean_password1(self):
return validate_password_strength(self.cleaned_data['password1'])

class UserCreationForm(auth_forms.UserCreationForm):
def clean_password1(self):
return validate_password_strength(self.cleaned_data['password1'])

class UserAdmin(auth_admin.UserAdmin):
change_password_form = AdminPasswordChangeForm
add_form = UserCreationForm

# Re-register UserAdmin
admin.site.unregister(auth_models.User)
admin.site.register(auth_models.User, UserAdmin)
Reply all
Reply to author
Forward
0 new messages