From 565b14533cf628d6631ff44d2bf41b73634eebe7 Mon Sep 17 00:00:00 2001 From: Richard Date: Sat, 1 Aug 2026 12:42:29 +0200 Subject: [PATCH] fix: Skip default admin@local.host creation during container startup if an admin user already exists --- .../__pycache__/create_admin.cpython-314.pyc | Bin 4786 -> 5712 bytes .../users/management/commands/create_admin.py | 66 ++++++++++-------- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/backend/apps/users/management/commands/__pycache__/create_admin.cpython-314.pyc b/backend/apps/users/management/commands/__pycache__/create_admin.cpython-314.pyc index aa75b579adc861afdcf071988caacb0e8ebe1c8b..b77c8af08319675f7f9310c7c4c84bc4974f52d4 100644 GIT binary patch literal 5712 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 delta 2025 zcmcIkOKclO7@qa|?X|u3+K%mb<45eYcA}=Fp`k?t+PZ1eCSh5U6^JO28*f|(zqISn zrV>g{$c3s828nRup-Qa~5(2JB^q8s$ZJJbGSsZ#mD#uiXB5`8Ij_pK>cnL2p?-%R~YaFuNl-}O#n(H z5|TTGT3*)@YLQUi6w=7jz#Cga9ehl5Epw)Zqn%%YPw=Lp?JyS*l`?{1-?m!% zJpckg&~uiZb`31(28jj=0^Tg>3#f+1s&j^2+>mh>+e)UcTE7h}uXC+XD69`2)cNOw zKmeS->7Y$HwvC$zX?8Vnn{wecZX(_ykQCr4L5sdtK?jeTIt{jx5rw7TimB5yv|T%m zxG<^bocI)eXVN3=LD21IpjnvO2SE zRlmlW|LGd-^=qVIz~X!Tzi*PG?%fHmT71jQsN=M=WI}bAxYn>W+X=v4BhI^cH}By) zcyGUk_ch1-A9?U251q(EVEJFWV3CV1kDZb-GKyU) zXNv_{!Wm2W36byx*0l8~hDIjonqlsIs*n-WQV0tPQO192PofVx9Es)o=$%{vD&t>0 z`he-FG7}0j@kQjz_~&tDFnK4lk(j6$Rk~x<@PH0gX-=WJo5ydBel~hLue|W`MwF}Q z+O~qi2yNTqMnb3p0sIfSv5tR)i@dUEHHhOvV z%31h>!#A%SI=$vyGb{X*BD|qYO)JwEw*a_A9M>SSM4Z56AgOr*K=7pIDFD_H%|lOT z<&?^FRGBE+3KPAZto99~t@I7wNmoY%v=y{x&Q)h}Xe%>0c-0wtCLFu2{lKRByRI94 zvOBIVy}P9N;#GU%zCEGRt|}c~r^BD@-=ur%Dv#_Q_^mTKHm9U>%3L0$Q6Q2yo5Lq@ zHr*qdUjcBO(mbSHA6jl$w#}or5}zijk-_!IpfWVEc5!V%c`c_ro8O2OHt8ZXxbAxI zdXL4=lHeX`8KcR2wxKZ#`MpIqM#G<7Bg8Q5cNYvtbmPPpI0A3FU$Ml{5J>p#kzRV= Z<0Z~OpC`&3BZzUL^5#=e2NHe+{{U-?fRO+I diff --git a/backend/apps/users/management/commands/create_admin.py b/backend/apps/users/management/commands/create_admin.py index 77c729a..c55d924 100644 --- a/backend/apps/users/management/commands/create_admin.py +++ b/backend/apps/users/management/commands/create_admin.py @@ -13,45 +13,51 @@ class Command(BaseCommand): parser.add_argument('--password', type=str, default=os.getenv('ADMIN_PASSWORD', 'adminpassword'), help='Passwort für den Admin') def handle(self, *args, **options): - username = options['username'] or os.getenv('ADMIN_USERNAME', 'admin') - email = options['email'] or os.getenv('ADMIN_EMAIL', 'admin@local.host') - password = options['password'] or os.getenv('ADMIN_PASSWORD', 'adminpassword') + has_existing_admin = User.objects.filter(is_superuser=True).exists() or User.objects.filter(is_admin_user=True).exists() + explicit_env_set = bool(os.getenv('ADMIN_USERNAME') or os.getenv('ADMIN_EMAIL')) - # 1. Admin User - user, created = User.objects.get_or_create( - username=username, - defaults={'email': email} - ) - - if created: - user.set_password(password) - user.is_superuser = True - user.is_staff = True - user.is_admin_user = True - user.is_approved = True - user.is_email_verified = True - user.is_active = True - user.save() - self.stdout.write(self.style.SUCCESS(f"✅ Initialer Admin '{username}' ({email}) wurde erstellt! Passwort: {password}")) + if has_existing_admin and not explicit_env_set and not os.getenv('FORCE_CREATE_ADMIN'): + self.stdout.write(self.style.SUCCESS("ℹ️ Mindestens ein Admin-Benutzer existiert bereits. Es wurde kein neuer Standard-Admin ('admin@local.host') erstellt.")) else: - changed = False - if not user.is_superuser or not user.is_admin_user or not user.is_approved or not user.is_active: + username = options['username'] or os.getenv('ADMIN_USERNAME', 'admin') + email = options['email'] or os.getenv('ADMIN_EMAIL', 'admin@local.host') + password = options['password'] or os.getenv('ADMIN_PASSWORD', 'adminpassword') + + # 1. Admin User + user, created = User.objects.get_or_create( + username=username, + defaults={'email': email} + ) + + if created: + user.set_password(password) user.is_superuser = True user.is_staff = True user.is_admin_user = True user.is_approved = True + user.is_email_verified = True user.is_active = True - changed = True - - if os.getenv('ADMIN_PASSWORD'): - user.set_password(password) - changed = True - - if changed: user.save() - self.stdout.write(self.style.SUCCESS(f"✅ Admin-Rechte für bestehenden Benutzer '{username}' wurden aktualisiert.")) + self.stdout.write(self.style.SUCCESS(f"✅ Initialer Admin '{username}' ({email}) wurde erstellt! Passwort: {password}")) else: - self.stdout.write(self.style.SUCCESS(f"ℹ️ Admin-Benutzer '{username}' existiert bereits.")) + changed = False + if not user.is_superuser or not user.is_admin_user or not user.is_approved or not user.is_active: + user.is_superuser = True + user.is_staff = True + user.is_admin_user = True + user.is_approved = True + user.is_active = True + changed = True + + if os.getenv('ADMIN_PASSWORD'): + user.set_password(password) + changed = True + + if changed: + user.save() + self.stdout.write(self.style.SUCCESS(f"✅ Admin-Rechte für bestehenden Benutzer '{username}' wurden aktualisiert.")) + else: + self.stdout.write(self.style.SUCCESS(f"ℹ️ Admin-Benutzer '{username}' existiert bereits.")) # 2. Initial Base Skills try: