From c8646909cd6bcabf0073fda0c9c3ff704a148fe4 Mon Sep 17 00:00:00 2001 From: Piotr Banaszkiewicz Date: Tue, 7 Feb 2023 17:21:56 +0100 Subject: [PATCH 1/2] [#2310] Repurpose `create_superuser` to also generate random password --- .../management/commands/create_superuser.py | 28 ++++++++++++++++--- start.sh | 2 ++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/amy/workshops/management/commands/create_superuser.py b/amy/workshops/management/commands/create_superuser.py index eb14c7388..008e73eb8 100644 --- a/amy/workshops/management/commands/create_superuser.py +++ b/amy/workshops/management/commands/create_superuser.py @@ -1,4 +1,5 @@ from django.core.management.base import BaseCommand, CommandError +from django.utils.crypto import get_random_string from communityroles.models import CommunityRole, CommunityRoleConfig from workshops.models import Person @@ -8,16 +9,35 @@ class Command(BaseCommand): args = "no arguments" help = 'Create a superuser called "admin" with password "admin".' + def add_arguments(self, parser): + parser.add_argument( + "--random-password", + action="store_true", + help="Use randomly generated password for the superuser", + ) + + def _random_password(self) -> str: + return get_random_string(length=40) + def handle(self, *args, **options): + username = "admin" + password = (options["random_password"] and self._random_password()) or "admin" + email = "admin@example.org" + + if Person.objects.filter(username=username).exists(): + print("Admin user exists, quitting.") + return + try: + print("Attempting to create admin user") admin = Person.objects.create_superuser( - username="admin", + username=username, personal="admin", family="admin", - email="admin@example.org", - password="admin", + email=email, + password=password, ) - print("Created admin user") + print(f"Created admin user with password {password}") role_config = CommunityRoleConfig.objects.get(name="instructor") CommunityRole.objects.create( diff --git a/start.sh b/start.sh index 7a787351a..79c6de027 100644 --- a/start.sh +++ b/start.sh @@ -11,6 +11,8 @@ /venv/amy/bin/python manage.py runscript seed_badges /venv/amy/bin/python manage.py runscript seed_training_requirements +/venv/amy/bin/python manage.py create_superuser --random-password + /venv/amy/bin/gunicorn \ --workers=4 \ --bind=0.0.0.0:80 \ From 337638ddba48ba57bacb2dac2f273c026bc333ab Mon Sep 17 00:00:00 2001 From: Piotr Banaszkiewicz Date: Tue, 7 Feb 2023 21:25:03 +0100 Subject: [PATCH 2/2] [#2310] Change approach in create_superuser Now the user account is created with the default password, if and only if the account doesn't exist yet. --- .../management/commands/create_superuser.py | 20 ++------ amy/workshops/tests/test_commands.py | 48 +++++++++++++++++++ start.sh | 2 +- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/amy/workshops/management/commands/create_superuser.py b/amy/workshops/management/commands/create_superuser.py index 008e73eb8..fddce6e3f 100644 --- a/amy/workshops/management/commands/create_superuser.py +++ b/amy/workshops/management/commands/create_superuser.py @@ -1,5 +1,4 @@ from django.core.management.base import BaseCommand, CommandError -from django.utils.crypto import get_random_string from communityroles.models import CommunityRole, CommunityRoleConfig from workshops.models import Person @@ -9,35 +8,22 @@ class Command(BaseCommand): args = "no arguments" help = 'Create a superuser called "admin" with password "admin".' - def add_arguments(self, parser): - parser.add_argument( - "--random-password", - action="store_true", - help="Use randomly generated password for the superuser", - ) - - def _random_password(self) -> str: - return get_random_string(length=40) - def handle(self, *args, **options): username = "admin" - password = (options["random_password"] and self._random_password()) or "admin" - email = "admin@example.org" if Person.objects.filter(username=username).exists(): print("Admin user exists, quitting.") return try: - print("Attempting to create admin user") admin = Person.objects.create_superuser( username=username, personal="admin", family="admin", - email=email, - password=password, + email="admin@example.org", + password="admin", ) - print(f"Created admin user with password {password}") + print("Created admin user") role_config = CommunityRoleConfig.objects.get(name="instructor") CommunityRole.objects.create( diff --git a/amy/workshops/tests/test_commands.py b/amy/workshops/tests/test_commands.py index 743cd88af..e584c57a2 100644 --- a/amy/workshops/tests/test_commands.py +++ b/amy/workshops/tests/test_commands.py @@ -4,6 +4,7 @@ from datetime import date +from django.core.management.base import BaseCommand from django.test import TestCase from communityroles.models import CommunityRole, CommunityRoleConfig @@ -13,6 +14,7 @@ from workshops.management.commands.assign_trainer_community_role import ( Command as AssignTrainerCommunityRole, ) +from workshops.management.commands.create_superuser import Command as CreateSuperuser from workshops.management.commands.migrate_inactive_trainers_to_trainer_badges import ( Command as MigrateInactiveTrainersToTrainerBadges, ) @@ -596,3 +598,49 @@ def test_handle(self) -> None: self.assertEqual(award2.badge, self.trainer_badge) # Changed self.assertEqual(award2.awarded, date(2021, 1, 1)) self.assertEqual(award1.badge, self.trainer_badge) # Not changed + + +class TestCreateSuperuserCommand(TestCase): + command: BaseCommand + + def setUp(self) -> None: + self.command = CreateSuperuser() + instructor_badge = Badge.objects.create(name="instructor", title="Instructor") + CommunityRoleConfig.objects.create( + name="instructor", + link_to_award=True, + award_badge_limit=instructor_badge, + link_to_membership=False, + additional_url=False, + ) + + def test_admin_created(self) -> None: + """When `admin` account doesn't exist, it gets created.""" + # Act + self.command.handle() + + # Assert + Person.objects.get(username="admin") + + def test_admin_not_created(self) -> None: + """When `admin` account exists, the command doesn't change it or create other + superuser accounts.""" + # Arrange + superuser = Person.objects.create_superuser( + username="admin", + personal="admin", + family="admin", + email="admin@example.org", + password="admin", + ) + superuser.is_active = False + superuser.save() + + # Act + self.command.handle() + + # Assert + Person.objects.get(username="admin") + self.assertEqual(Person.objects.filter(is_superuser=True).count(), 1) + superuser.refresh_from_db() + self.assertFalse(superuser.is_active) diff --git a/start.sh b/start.sh index 79c6de027..88e9a8439 100644 --- a/start.sh +++ b/start.sh @@ -11,7 +11,7 @@ /venv/amy/bin/python manage.py runscript seed_badges /venv/amy/bin/python manage.py runscript seed_training_requirements -/venv/amy/bin/python manage.py create_superuser --random-password +/venv/amy/bin/python manage.py create_superuser /venv/amy/bin/gunicorn \ --workers=4 \