From b81905bfd4a745a407d246e899a7c0db1c7555be Mon Sep 17 00:00:00 2001
From: Tom <tom@tomforb.es>
Date: Sat, 9 Sep 2017 18:06:20 +0100
Subject: [PATCH] Fixed #28571 -- Added a prompt to bypass password validation
 in createsuperuser.

---
 .../management/commands/createsuperuser.py    |  4 ++-
 docs/releases/2.1.txt                         |  3 +-
 tests/auth_tests/test_management.py           | 30 +++++++++++++++++++
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py
index 7e19ef9955..3a16c58b3d 100644
--- a/django/contrib/auth/management/commands/createsuperuser.py
+++ b/django/contrib/auth/management/commands/createsuperuser.py
@@ -163,7 +163,9 @@ class Command(BaseCommand):
                         validate_password(password2, self.UserModel(**fake_user_data))
                     except exceptions.ValidationError as err:
                         self.stderr.write('\n'.join(err.messages))
-                        password = None
+                        response = input('Bypass password validation and create user anyway? [y/N]: ')
+                        if response.lower() != 'y':
+                            password = None
 
             except KeyboardInterrupt:
                 self.stderr.write("\nOperation cancelled.")
diff --git a/docs/releases/2.1.txt b/docs/releases/2.1.txt
index 22768e2f1b..2135e1a958 100644
--- a/docs/releases/2.1.txt
+++ b/docs/releases/2.1.txt
@@ -42,7 +42,8 @@ Minor features
 :mod:`django.contrib.auth`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-* ...
+* :djadmin:`createsuperuser` now gives a prompt to allow bypassing the
+  :setting:`AUTH_PASSWORD_VALIDATORS` checks.
 
 :mod:`django.contrib.contenttypes`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py
index 539ac84424..4e60333c9d 100644
--- a/tests/auth_tests/test_management.py
+++ b/tests/auth_tests/test_management.py
@@ -27,6 +27,7 @@ from .models import (
 
 MOCK_INPUT_KEY_TO_PROMPTS = {
     # @mock_inputs dict key: [expected prompt messages],
+    'bypass': ['Bypass password validation and create user anyway? [y/N]: '],
     'email': ['Email address: '],
     'username': ['Username: ', lambda: "Username (leave blank to use '%s'): " % get_default_username()],
 }
@@ -531,6 +532,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase):
             'password': bad_then_good_password,
             'username': 'joe1234567890',
             'email': '',
+            'bypass': 'n',
         })
         def test(self):
             call_command(
@@ -564,6 +566,34 @@ class CreatesuperuserManagementCommandTestCase(TestCase):
 
         test(self)
 
+    def test_password_validation_bypass(self):
+        """
+        Password validation can be bypassed by entering 'y' at the prompt.
+        """
+        new_io = StringIO()
+
+        @mock_inputs({
+            'password': '1234567890',
+            'username': 'joe1234567890',
+            'email': '',
+            'bypass': 'y',
+        })
+        def test(self):
+            call_command(
+                'createsuperuser',
+                interactive=True,
+                stdin=MockTTY(),
+                stdout=new_io,
+                stderr=new_io,
+            )
+            self.assertEqual(
+                new_io.getvalue().strip(),
+                'This password is entirely numeric.\n'
+                'Superuser created successfully.'
+            )
+
+        test(self)
+
     def test_invalid_username(self):
         """Creation fails if the username fails validation."""
         user_field = User._meta.get_field(User.USERNAME_FIELD)