Skip to content

Commit

Permalink
Merge pull request #92 from BesartSulejmani/master
Browse files Browse the repository at this point in the history
add create django superuser if django superuser username is set
  • Loading branch information
annashamray authored May 10, 2024
2 parents cdebdf6 + 2ef2c3f commit 38e11f9
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 0 deletions.
12 changes: 12 additions & 0 deletions bin/docker_start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ if [ -d $fixtures_dir ]; then
done
fi

# Create superuser
# specify password by setting OBJECTTYPE_SUPERUSER_PASSWORD in the env
# specify username by setting OBJECTTYPE_SUPERUSER_USERNAME in the env
# specify email by setting OBJECTTYPE_SUPERUSER_EMAIL in the env
if [ -n "${OBJECTTYPE_SUPERUSER_USERNAME}" ]; then
python src/manage.py createinitialsuperuser \
--no-input \
--username "${OBJECTTYPE_SUPERUSER_USERNAME}" \
--email "${OBJECTTYPE_SUPERUSER_EMAIL:-admin@admin.org}"
unset OBJECTTYPE_SUPERUSER_USERNAME OBJECTTYPE_SUPERUSER_EMAIL OBJECTTYPE_SUPERUSER_PASSWORD
fi

# Start server
>&2 echo "Starting server"
uwsgi \
Expand Down
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import os

from django.conf import settings
from django.contrib.auth.management.commands.createsuperuser import (
Command as BaseCommand,
)
from django.core.mail import send_mail
from django.urls import reverse


class Command(BaseCommand):
def add_arguments(self, parser):
super().add_arguments(parser)

parser.add_argument(
"--password",
help="Set the password when the superuser is initially created.",
)
parser.add_argument(
"--generate-password",
action="store_true",
help=(
"Generate and e-mail the password. The --password option and "
"environment variable overrule this flag."
),
)

def handle(self, **options):
username = options[self.UserModel.USERNAME_FIELD]
database = options["database"]
qs = self.UserModel._default_manager.db_manager(database).filter(
**{self.UserModel.USERNAME_FIELD: username}
)
if qs.exists():
self.stdout.write(
self.style.WARNING("Superuser account already exists, exiting")
)
return

password = options.get("password") or os.environ.get(
"OBJECTTYPE_SUPERUSER_PASSWORD"
)

if password or options["generate_password"]:
options["interactive"] = False

# perform user creation from core Django
super().handle(**options)

user = qs.get()

if not password and options["generate_password"]:
password = self.UserModel.objects.make_random_password(length=20)

if password:
self.stdout.write("Setting user password...")
user.set_password(password)
user.save()

if options["generate_password"]:
try:
link = f'{settings.ALLOWED_HOSTS[0]}{reverse("admin:index")}'
except IndexError:
link = "unknown url"

send_mail(
f"Credentials for {settings.PROJECT_NAME} ({link})",
f"Credentials for project: {settings.PROJECT_NAME}\n\nUsername: {username}\nPassword: {password}",
settings.DEFAULT_FROM_EMAIL,
[user.email],
fail_silently=False,
)
146 changes: 146 additions & 0 deletions src/objecttypes/accounts/tests/test_createinitialsuperuser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import io
import os

from django.conf import settings
from django.core import mail
from django.core.management import call_command
from django.test import TestCase, override_settings
from django.urls import exceptions, reverse

from ..models import User


class CreateInitialSuperuserTests(TestCase):
def test_create_initial_superuser_command(self):
call_command(
"createinitialsuperuser",
username="maykin",
email="[email protected]",
generate_password=True,
stdout=io.StringIO(),
stderr=io.StringIO(),
)
user = User.objects.get()

self.assertTrue(user.has_usable_password())
self.assertTrue(user.is_active)
self.assertTrue(user.is_staff)
self.assertTrue(user.is_superuser)

self.assertEqual(len(mail.outbox), 1)

sent_mail = mail.outbox[0]
try:
link = f'{settings.ALLOWED_HOSTS[0]}{reverse("admin:index")}'
except exceptions.NoReverseMatch:
link = settings.ALLOWED_HOSTS[0]
self.assertEqual(
sent_mail.subject, f"Credentials for {settings.PROJECT_NAME} ({link})"
)
self.assertListEqual(sent_mail.recipients(), ["[email protected]"])

@override_settings(ALLOWED_HOSTS=[])
def test_create_initial_superuser_command_allowed_hosts_empty(self):
call_command(
"createinitialsuperuser",
username="maykin",
email="[email protected]",
generate_password=True,
stdout=io.StringIO(),
stderr=io.StringIO(),
)
user = User.objects.get()

self.assertTrue(user.has_usable_password())
self.assertTrue(user.is_active)
self.assertTrue(user.is_staff)
self.assertTrue(user.is_superuser)

self.assertEqual(len(mail.outbox), 1)

sent_mail = mail.outbox[0]
link = "unknown url"
self.assertEqual(
sent_mail.subject, f"Credentials for {settings.PROJECT_NAME} ({link})"
)
self.assertListEqual(sent_mail.recipients(), ["[email protected]"])

def test_create_from_cli(self):
call_command(
"createinitialsuperuser",
"--username=admin",
"--password=admin",
"[email protected]",
"--no-input",
stdout=io.StringIO(),
)

user = User.objects.get()
self.assertTrue(user.is_staff)
self.assertTrue(user.is_superuser)

self.assertEqual(user.username, "admin")
self.assertEqual(user.email, "[email protected]")
self.assertTrue(user.check_password("admin"))

def test_command_noop_if_user_exists(self):
User.objects.create(username="admin")

call_command(
"createinitialsuperuser",
"--username=admin",
"--password=admin",
"[email protected]",
"--no-input",
stdout=io.StringIO(),
)

self.assertEqual(User.objects.count(), 1)
user = User.objects.get()
self.assertFalse(user.is_staff)
self.assertFalse(user.is_superuser)

self.assertEqual(user.username, "admin")
self.assertEqual(user.email, "")
self.assertFalse(user.check_password("admin"))

def test_password_from_env(self):
os.environ["OBJECTTYPE_SUPERUSER_PASSWORD"] = "admin"

def reset_env():
del os.environ["OBJECTTYPE_SUPERUSER_PASSWORD"]

self.addCleanup(reset_env)

call_command(
"createinitialsuperuser",
"--username=admin",
"[email protected]",
"--no-input",
stdout=io.StringIO(),
)

user = User.objects.get()
self.assertTrue(user.is_staff)
self.assertTrue(user.is_superuser)

self.assertEqual(user.username, "admin")
self.assertEqual(user.email, "[email protected]")
self.assertTrue(user.check_password("admin"))

def test_without_password(self):
call_command(
"createinitialsuperuser",
"--username=admin",
"[email protected]",
"--no-input",
stdout=io.StringIO(),
)

user = User.objects.get()
self.assertTrue(user.is_staff)
self.assertTrue(user.is_superuser)

self.assertEqual(user.username, "admin")
self.assertEqual(user.email, "[email protected]")
self.assertFalse(user.check_password("admin"))

0 comments on commit 38e11f9

Please sign in to comment.