Coverage for app/venv/lib/python3.14/site-packages/weblate/auth/management/commands/createadmin.py: 58%
53 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
1# Copyright © Michal Čihař <michal@weblate.org>
2#
3# SPDX-License-Identifier: GPL-3.0-or-later
4from __future__ import annotations
6from typing import TYPE_CHECKING
8from django.core.management.base import CommandError
9from django.db.models import Q
11from weblate.auth.models import User
12from weblate.utils.backup import make_password
13from weblate.utils.management.base import BaseCommand
15if TYPE_CHECKING: 15 ↛ 16line 15 didn't jump to line 16 because the condition on line 15 was never true
16 from django.core.management.base import CommandParser
19class Command(BaseCommand):
20 help = "setups admin user with random password"
22 def add_arguments(self, parser: CommandParser) -> None:
23 parser.add_argument(
24 "--password",
25 default=None,
26 help="Password to set, random is generated if not specified",
27 )
28 parser.add_argument(
29 "--no-password",
30 action="store_true",
31 default=False,
32 help="Do not set password at all (useful with --update)",
33 )
34 parser.add_argument(
35 "--username", default="admin", help='Admin username, defaults to "admin"'
36 )
37 parser.add_argument(
38 "--email",
39 default="admin@example.com",
40 help='Admin email, defaults to "admin@example.com"',
41 )
42 parser.add_argument(
43 "--name",
44 default="Weblate Admin",
45 help='Admin name, defaults to "Weblate Admin"',
46 )
47 parser.add_argument(
48 "--update",
49 action="store_true",
50 default=False,
51 help="Change password for this account if exists",
52 )
54 def handle(self, *args, **options) -> None:
55 """
56 Create admin account with admin password.
58 This is useful mostly for setup inside appliances, when user wants to be able to
59 login remotely and change password then.
60 """
61 email = options["email"]
62 username = options["username"]
63 if not email: 63 ↛ 64line 63 didn't jump to line 64 because the condition on line 63 was never true
64 email = "admin@example.com"
65 self.stdout.write(f"Blank e-mail for admin, using {email} instead!")
66 matching_users = User.objects.filter(Q(username=username) | Q(email=email))
68 if len(matching_users) == 0: 68 ↛ 70line 68 didn't jump to line 70 because the condition on line 68 was always true
69 user = None
70 elif len(matching_users) == 1:
71 user = matching_users[0]
72 else:
73 for user in matching_users:
74 self.stderr.write(
75 f"Found matching user: username={user.username} email={user.email}"
76 )
77 msg = "Multiple users matched given parameters!"
78 raise CommandError(msg)
80 if user and not options["update"]: 80 ↛ 81line 80 didn't jump to line 81 because the condition on line 80 was never true
81 msg = f"User {username} already exists, specify --update to update existing"
82 raise CommandError(msg)
84 if options["no_password"]: 84 ↛ 85line 84 didn't jump to line 85 because the condition on line 84 was never true
85 password = None
86 elif options["password"]: 86 ↛ 89line 86 didn't jump to line 89 because the condition on line 86 was always true
87 password = options["password"]
88 else:
89 password = make_password(13)
90 self.stdout.write(f"Using generated password: {password}")
92 if user and options["update"]: 92 ↛ 93line 92 didn't jump to line 93 because the condition on line 92 was never true
93 self.stdout.write(f"Updating user {user.username}")
94 user.email = email
95 if password is not None and not user.check_password(password):
96 user.set_password(password)
97 else:
98 self.stdout.write(f"Creating user {username}")
99 user = User.objects.create_user(username, email, password)
100 user.full_name = options["name"]
101 user.is_superuser = True
102 user.is_active = True
103 user.save()