From b5a5c92c72cc179b5a9a888039cdd2f0680bff36 Mon Sep 17 00:00:00 2001
From: daniel a rios <misterrios@gmail.com>
Date: Fri, 14 Jun 2019 11:12:08 +0200
Subject: [PATCH] Fixed #30066 -- Enabled super user creation without email and
 password

---
 django/contrib/auth/models.py    |  2 +-
 docs/ref/contrib/auth.txt        |  6 +++++-
 docs/topics/auth/customizing.txt |  9 +++------
 tests/auth_tests/test_basic.py   | 16 ++++++++++++++++
 4 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
index 78fd7fbb5c..971621d9c7 100644
--- a/django/contrib/auth/models.py
+++ b/django/contrib/auth/models.py
@@ -146,7 +146,7 @@ class UserManager(BaseUserManager):
         extra_fields.setdefault('is_superuser', False)
         return self._create_user(username, email, password, **extra_fields)
 
-    def create_superuser(self, username, email, password, **extra_fields):
+    def create_superuser(self, username, email=None, password=None, **extra_fields):
         extra_fields.setdefault('is_staff', True)
         extra_fields.setdefault('is_superuser', True)
 
diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt
index e3dda3045f..666208b28c 100644
--- a/docs/ref/contrib/auth.txt
+++ b/docs/ref/contrib/auth.txt
@@ -282,11 +282,15 @@ Manager methods
 
         See :ref:`Creating users <topics-auth-creating-users>` for example usage.
 
-    .. method:: create_superuser(username, email, password, **extra_fields)
+    .. method:: create_superuser(username, email=None, password=None, **extra_fields)
 
         Same as :meth:`create_user`, but sets :attr:`~models.User.is_staff` and
         :attr:`~models.User.is_superuser` to ``True``.
 
+        .. versionchanged:: 3.0
+
+            The ``email`` and ``password`` parameters were made optional.
+
 ``AnonymousUser`` object
 ========================
 
diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt
index afc9bb3e62..53dc14ebd8 100644
--- a/docs/topics/auth/customizing.txt
+++ b/docs/topics/auth/customizing.txt
@@ -746,20 +746,17 @@ providing two additional methods:
                 # create user here
                 ...
 
-    .. method:: models.CustomUserManager.create_superuser(*username_field*, password, **other_fields)
+    .. method:: models.CustomUserManager.create_superuser(*username_field*, password=None, **other_fields)
 
         The prototype of ``create_superuser()`` should accept the username
         field, plus all required fields as arguments. For example, if your user
         model uses ``email`` as the username field, and has ``date_of_birth``
         as a required field, then ``create_superuser`` should be defined as::
 
-            def create_superuser(self, email, date_of_birth, password):
+            def create_superuser(self, email, date_of_birth, password=None):
                 # create superuser here
                 ...
 
-        Unlike ``create_user()``, ``create_superuser()`` *must* require the
-        caller to provide a password.
-
 For a :class:`~.ForeignKey` in :attr:`.USERNAME_FIELD` or
 :attr:`.REQUIRED_FIELDS`, these methods receive the value of the
 :attr:`~.ForeignKey.to_field` (the :attr:`~django.db.models.Field.primary_key`
@@ -1044,7 +1041,7 @@ authentication app::
             user.save(using=self._db)
             return user
 
-        def create_superuser(self, email, date_of_birth, password):
+        def create_superuser(self, email, date_of_birth, password=None):
             """
             Creates and saves a superuser with the given email, date of
             birth and password.
diff --git a/tests/auth_tests/test_basic.py b/tests/auth_tests/test_basic.py
index c1b7e60455..9e0d8e863e 100644
--- a/tests/auth_tests/test_basic.py
+++ b/tests/auth_tests/test_basic.py
@@ -73,6 +73,22 @@ class BasicTestCase(TestCase):
         self.assertTrue(super.is_active)
         self.assertTrue(super.is_staff)
 
+    def test_superuser_no_email_or_password(self):
+        cases = [
+            {},
+            {'email': ''},
+            {'email': None},
+            {'password': None},
+        ]
+        for i, kwargs in enumerate(cases):
+            with self.subTest(**kwargs):
+                superuser = User.objects.create_superuser(
+                    'super{}'.format(i),
+                    **kwargs
+                )
+                self.assertEqual(superuser.email, '')
+                self.assertFalse(superuser.has_usable_password())
+
     def test_get_user_model(self):
         "The current user model can be retrieved"
         self.assertEqual(get_user_model(), User)