Files
upstream-zulip/zerver/management/commands/delete_user.py
upstream-mirror 64898b2c79
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
2026-09-15 15:05:30 +05:00

69 lines
2.6 KiB
Python

from argparse import ArgumentParser
from typing import Any
from django.core.management.base import CommandError
from typing_extensions import override
from zerver.actions.users import do_delete_user
from zerver.lib.management import ZulipBaseCommand
from zerver.lib.users import get_active_bots_owned_by_user
class Command(ZulipBaseCommand):
help = """
Delete a user or users, including all messages sent by them and
personal messages received by them, and audit records, like what
streams they had been subscribed to. Deactivating users is generally
recommended over this tool, but deletion can be useful if you
specifically to completely delete an account created for testing.
This will:
* Delete the user's account, including metadata like name, email
address, custom profile fields, historical subscriptions, etc.
* Delete any messages they've sent and any non-group direct messages
they've received.
* Group direct messages in which the user participated won't be
deleted (with the exceptions of those message the deleted user
sent). An inactive, inaccessible dummy user account named "Deleted
User <id>" is created to replace the deleted user as a recipient in
group direct message conversations, in order to somewhat preserve
their integrity.
* Delete other records of the user's activity, such as emoji reactions.
* Deactivate all bots owned by the user, without deleting them or
their data. If you want to delete the bots and the message
sent/received by them, you can use the command on them individually.
"""
@override
def add_arguments(self, parser: ArgumentParser) -> None:
parser.add_argument(
"-f",
"--for-real",
action="store_true",
help="Actually delete the user(s). Default is a dry run.",
)
self.add_realm_args(parser)
self.add_user_list_args(parser)
@override
def handle(self, *args: Any, **options: Any) -> None:
realm = self.get_realm(options)
user_profiles = self.get_users(options, realm)
for user_profile in user_profiles:
print(
f"{user_profile.delivery_email} has {get_active_bots_owned_by_user(user_profile).count()} active bots that will be deactivated as a result of the user's deletion."
)
if not options["for_real"]:
raise CommandError("This was a dry run. Pass -f to actually delete.")
for user_profile in user_profiles:
do_delete_user(user_profile, acting_user=None)
print(f"Successfully deleted user {user_profile.delivery_email}.")