diff options
| author | Alex Becker <acbecker@uchicago.edu> | 2015-07-09 01:15:05 -0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-08-01 20:18:26 -0400 |
| commit | 53d28f83390aed98fab4eed187eaf1edaa92c6d0 (patch) | |
| tree | 6d1d99e4d0baa3da84c04512d7837c2867d65a11 /django | |
| parent | 264eeaf14adf979a81439c6d1f6a8a53b088885e (diff) | |
Fixed #25089 -- Added password validation to createsuperuser/changepassword.
Diffstat (limited to 'django')
| -rw-r--r-- | django/contrib/auth/management/commands/changepassword.py | 16 | ||||
| -rw-r--r-- | django/contrib/auth/management/commands/createsuperuser.py | 20 |
2 files changed, 33 insertions, 3 deletions
diff --git a/django/contrib/auth/management/commands/changepassword.py b/django/contrib/auth/management/commands/changepassword.py index 647b7b1728..600911f759 100644 --- a/django/contrib/auth/management/commands/changepassword.py +++ b/django/contrib/auth/management/commands/changepassword.py @@ -3,6 +3,8 @@ from __future__ import unicode_literals import getpass from django.contrib.auth import get_user_model +from django.contrib.auth.password_validation import validate_password +from django.core.exceptions import ValidationError from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS from django.utils.encoding import force_str @@ -46,12 +48,22 @@ class Command(BaseCommand): MAX_TRIES = 3 count = 0 p1, p2 = 1, 2 # To make them initially mismatch. - while p1 != p2 and count < MAX_TRIES: + password_validated = False + while (p1 != p2 or not password_validated) and count < MAX_TRIES: p1 = self._get_pass() p2 = self._get_pass("Password (again): ") if p1 != p2: self.stdout.write("Passwords do not match. Please try again.\n") - count = count + 1 + count += 1 + # Don't validate passwords that don't match. + continue + try: + validate_password(p2, u) + except ValidationError as err: + self.stdout.write(', '.join(err.messages)) + count += 1 + else: + password_validated = True if count == MAX_TRIES: raise CommandError("Aborting password change for user '%s' after %s attempts" % (u, count)) diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py index ae6ea0e48a..558ee64d9f 100644 --- a/django/contrib/auth/management/commands/createsuperuser.py +++ b/django/contrib/auth/management/commands/createsuperuser.py @@ -8,6 +8,7 @@ import sys from django.contrib.auth import get_user_model from django.contrib.auth.management import get_default_username +from django.contrib.auth.password_validation import validate_password from django.core import exceptions from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS @@ -56,6 +57,9 @@ class Command(BaseCommand): # If not provided, create the user with an unusable password password = None user_data = {} + # Same as user_data but with foreign keys as fake model instances + # instead of raw IDs. + fake_user_data = {} # Do quick and dirty validation if --noinput if not options['interactive']: @@ -121,7 +125,13 @@ class Command(BaseCommand): field.remote_field.field_name, ) if field.remote_field else '', )) - user_data[field_name] = self.get_input_data(field, message) + input_value = self.get_input_data(field, message) + user_data[field_name] = input_value + fake_user_data[field_name] = input_value + + # Wrap any foreign keys in fake model instances + if field.remote_field: + fake_user_data[field_name] = field.remote_field.model(input_value) # Get a password while password is None: @@ -130,13 +140,21 @@ class Command(BaseCommand): if password != password2: self.stderr.write("Error: Your passwords didn't match.") password = None + # Don't validate passwords that don't match. continue if password.strip() == '': self.stderr.write("Error: Blank passwords aren't allowed.") password = None + # Don't validate blank passwords. continue + try: + validate_password(password2, self.UserModel(**fake_user_data)) + except exceptions.ValidationError as err: + self.stderr.write(', '.join(err.messages)) + password = None + except KeyboardInterrupt: self.stderr.write("\nOperation cancelled.") sys.exit(1) |
