2017-07-21 10:57:55 +02:00
|
|
|
import sys
|
2017-11-16 00:43:27 +01:00
|
|
|
from argparse import ArgumentParser
|
2024-07-12 02:30:17 +02:00
|
|
|
from typing import Any
|
2017-11-16 00:43:27 +01:00
|
|
|
|
|
|
|
from django.conf import settings
|
2019-03-14 05:34:20 +01:00
|
|
|
from django.core.management.base import CommandError
|
2023-10-12 19:43:45 +02:00
|
|
|
from typing_extensions import override
|
2017-07-21 10:57:55 +02:00
|
|
|
|
2024-04-23 21:30:37 +02:00
|
|
|
from zerver.lib.management import ZulipBaseCommand, abort_unless_locked
|
2020-06-11 00:54:34 +02:00
|
|
|
from zerver.lib.soft_deactivation import (
|
|
|
|
do_auto_soft_deactivate_users,
|
|
|
|
do_soft_activate_users,
|
|
|
|
do_soft_deactivate_users,
|
|
|
|
logger,
|
|
|
|
)
|
2017-11-16 00:43:27 +01:00
|
|
|
from zerver.models import Realm, UserProfile
|
2017-07-21 10:57:55 +02:00
|
|
|
|
2020-01-14 21:59:46 +01:00
|
|
|
|
2024-07-12 02:30:17 +02:00
|
|
|
def get_users_from_emails(emails: list[str], filter_kwargs: dict[str, Realm]) -> list[UserProfile]:
|
2019-11-16 01:42:36 +01:00
|
|
|
# Bug: Ideally, this would be case-insensitive like our other email queries.
|
2023-07-11 22:45:27 +02:00
|
|
|
users = list(UserProfile.objects.filter(delivery_email__in=emails, **filter_kwargs))
|
2019-03-14 05:34:20 +01:00
|
|
|
|
|
|
|
if len(users) != len(emails):
|
2019-11-16 01:42:36 +01:00
|
|
|
user_emails_found = {user.delivery_email for user in users}
|
2021-02-12 08:20:45 +01:00
|
|
|
user_emails_not_found = "\n".join(set(emails) - user_emails_found)
|
2020-06-14 02:57:50 +02:00
|
|
|
raise CommandError(
|
2021-02-12 08:20:45 +01:00
|
|
|
"Users with the following emails were not found:\n\n"
|
|
|
|
f"{user_emails_not_found}\n\n"
|
|
|
|
"Check if they are correct.",
|
2020-06-14 02:57:50 +02:00
|
|
|
)
|
2019-03-14 05:34:20 +01:00
|
|
|
return users
|
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2017-07-21 10:57:55 +02:00
|
|
|
class Command(ZulipBaseCommand):
|
2019-03-14 05:34:20 +01:00
|
|
|
help = """Soft activate/deactivate users. Users are recognised by their emails here."""
|
2017-07-21 10:57:55 +02:00
|
|
|
|
2023-10-12 19:43:45 +02:00
|
|
|
@override
|
2017-10-26 11:35:57 +02:00
|
|
|
def add_arguments(self, parser: ArgumentParser) -> None:
|
2017-08-22 02:43:03 +02:00
|
|
|
self.add_realm_args(parser)
|
2021-02-12 08:19:30 +01:00
|
|
|
parser.add_argument(
|
2021-02-12 08:20:45 +01:00
|
|
|
"-d", "--deactivate", action="store_true", help="Used to deactivate user/users."
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
|
|
|
parser.add_argument(
|
2021-02-12 08:20:45 +01:00
|
|
|
"-a", "--activate", action="store_true", help="Used to activate user/users."
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
|
|
|
parser.add_argument(
|
2021-02-12 08:20:45 +01:00
|
|
|
"--inactive-for",
|
2021-02-12 08:19:30 +01:00
|
|
|
type=int,
|
|
|
|
default=28,
|
2021-02-12 08:20:45 +01:00
|
|
|
help="Number of days of inactivity before soft-deactivation",
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
|
|
|
parser.add_argument(
|
2021-02-12 08:20:45 +01:00
|
|
|
"users",
|
|
|
|
metavar="<users>",
|
|
|
|
nargs="*",
|
2021-02-12 08:19:30 +01:00
|
|
|
help="A list of user emails to soft activate/deactivate.",
|
|
|
|
)
|
2017-07-21 10:57:55 +02:00
|
|
|
|
2023-10-12 19:43:45 +02:00
|
|
|
@override
|
2024-04-23 21:30:37 +02:00
|
|
|
@abort_unless_locked
|
2019-08-10 00:30:34 +02:00
|
|
|
def handle(self, *args: Any, **options: Any) -> None:
|
2017-08-22 02:46:19 +02:00
|
|
|
if settings.STAGING:
|
2021-02-12 08:20:45 +01:00
|
|
|
print("This is a Staging server. Suppressing management command.")
|
2017-08-22 02:46:19 +02:00
|
|
|
sys.exit(0)
|
|
|
|
|
2017-09-26 22:23:11 +02:00
|
|
|
realm = self.get_realm(options)
|
2021-02-12 08:20:45 +01:00
|
|
|
user_emails = options["users"]
|
|
|
|
activate = options["activate"]
|
|
|
|
deactivate = options["deactivate"]
|
2017-09-26 01:23:44 +02:00
|
|
|
|
2024-07-12 02:30:17 +02:00
|
|
|
filter_kwargs: dict[str, Realm] = {}
|
2017-09-26 01:23:44 +02:00
|
|
|
if realm is not None:
|
2017-08-22 02:43:03 +02:00
|
|
|
filter_kwargs = dict(realm=realm)
|
|
|
|
|
2017-07-21 10:57:55 +02:00
|
|
|
if activate:
|
|
|
|
if not user_emails:
|
2021-02-12 08:20:45 +01:00
|
|
|
print("You need to specify at least one user to use the activate option.")
|
2017-10-06 17:48:43 +02:00
|
|
|
self.print_help("./manage.py", "soft_deactivate_users")
|
2019-05-03 23:20:39 +02:00
|
|
|
raise CommandError
|
2017-08-22 02:43:03 +02:00
|
|
|
|
2019-03-14 05:34:20 +01:00
|
|
|
users_to_activate = get_users_from_emails(user_emails, filter_kwargs)
|
2017-08-16 06:15:56 +02:00
|
|
|
users_activated = do_soft_activate_users(users_to_activate)
|
2021-05-10 07:02:14 +02:00
|
|
|
logger.info("Soft reactivated %d user(s)", len(users_activated))
|
2019-03-14 05:34:20 +01:00
|
|
|
|
2017-07-21 10:57:55 +02:00
|
|
|
elif deactivate:
|
|
|
|
if user_emails:
|
2019-03-14 05:34:20 +01:00
|
|
|
users_to_deactivate = get_users_from_emails(user_emails, filter_kwargs)
|
2021-02-12 08:20:45 +01:00
|
|
|
print("Soft deactivating forcefully...")
|
2019-03-12 04:28:40 +01:00
|
|
|
users_deactivated = do_soft_deactivate_users(users_to_deactivate)
|
2017-07-21 10:57:55 +02:00
|
|
|
else:
|
2021-02-12 08:19:30 +01:00
|
|
|
users_deactivated = do_auto_soft_deactivate_users(
|
2021-02-12 08:20:45 +01:00
|
|
|
int(options["inactive_for"]), realm
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
2021-02-12 08:20:45 +01:00
|
|
|
logger.info("Soft deactivated %d user(s)", len(users_deactivated))
|
2017-07-21 10:57:55 +02:00
|
|
|
|
|
|
|
else:
|
2017-10-06 17:48:43 +02:00
|
|
|
self.print_help("./manage.py", "soft_deactivate_users")
|
2019-05-03 23:20:39 +02:00
|
|
|
raise CommandError
|