summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorAlex Becker <acbecker@uchicago.edu>2015-07-09 01:15:05 -0500
committerTim Graham <timograham@gmail.com>2015-08-01 20:18:26 -0400
commit53d28f83390aed98fab4eed187eaf1edaa92c6d0 (patch)
tree6d1d99e4d0baa3da84c04512d7837c2867d65a11 /django
parent264eeaf14adf979a81439c6d1f6a8a53b088885e (diff)
Fixed #25089 -- Added password validation to createsuperuser/changepassword.
Diffstat (limited to 'django')
-rw-r--r--django/contrib/auth/management/commands/changepassword.py16
-rw-r--r--django/contrib/auth/management/commands/createsuperuser.py20
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)