You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
2.0 KiB
55 lines
2.0 KiB
import secrets
|
|
from django.core.management.base import BaseCommand
|
|
from django.db.models import Q
|
|
from apps.account.models import User
|
|
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Sets a new plain/hashed password and encrypts it for active users who lack an encrypted password.'
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument(
|
|
'--password',
|
|
type=str,
|
|
help='Specific password to set for all matched users. If not provided, a random 8-character password will be generated for each user.'
|
|
)
|
|
parser.add_argument(
|
|
'--dry-run',
|
|
action='store_true',
|
|
help='Run the command without saving changes to the database.'
|
|
)
|
|
|
|
def handle(self, *args, **options):
|
|
password_input = options['password']
|
|
dry_run = options['dry_run']
|
|
|
|
# Find active users without an encrypted password
|
|
users = User.objects.filter(
|
|
Q(password_enc='') | Q(password_enc__isnull=True),
|
|
is_active=True
|
|
)
|
|
|
|
if not users.exists():
|
|
self.stdout.write(self.style.SUCCESS("No active users found without an encrypted password."))
|
|
return
|
|
|
|
self.stdout.write(f"Found {users.count()} active users without an encrypted password.")
|
|
|
|
updated_count = 0
|
|
for user in users:
|
|
# Generate or use the provided password
|
|
new_password = password_input if password_input else secrets.token_urlsafe(6)[:8]
|
|
|
|
self.stdout.write(f"User: {user.email or user.fullname} (ID: {user.id}) -> Password: {new_password}")
|
|
|
|
if not dry_run:
|
|
user.set_password(new_password)
|
|
user.set_plain_password(new_password)
|
|
user.save()
|
|
|
|
updated_count += 1
|
|
|
|
if dry_run:
|
|
self.stdout.write(self.style.WARNING(f"[DRY-RUN] Would have updated {updated_count} users."))
|
|
else:
|
|
self.stdout.write(self.style.SUCCESS(f"Successfully updated {updated_count} users."))
|