Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add create django superuser if django superuser username is set #92

Merged
merged 3 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions bin/docker_start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,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:[email protected]}"
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"))