diff --git a/analytics/views.py b/analytics/views.py index 5adefa1535..9bf8d75fe6 100644 --- a/analytics/views.py +++ b/analytics/views.py @@ -1077,8 +1077,10 @@ def support(request: HttpRequest) -> HttpResponse: if users: for user in users: user.realm.realm_icon_url = realm_icon_url(user.realm) - user.realm.admin_emails = ", ".join(user.realm.get_admin_users().values_list("email", - flat=True)) + user.realm.admin_emails = ", ".join( + user.realm.get_human_admin_users().values_list( + "email", + flat=True)) user.realm.default_discount = get_discount_for_realm(user.realm) context["users"] = users @@ -1102,7 +1104,7 @@ def support(request: HttpRequest) -> HttpResponse: if realms: for realm in realms: realm.realm_icon_url = realm_icon_url(realm) - realm.admin_emails = ", ".join(realm.get_admin_users().values_list("email", flat=True)) + realm.admin_emails = ", ".join(realm.get_human_admin_users().values_list("email", flat=True)) realm.default_discount = get_discount_for_realm(realm) context["realms"] = realms return render(request, 'analytics/support.html', context=context) @@ -1383,7 +1385,7 @@ def get_realm_activity(request: HttpRequest, realm_str: str) -> HttpResponse: all_user_records = {} # type: Dict[str, Any] try: - admins = Realm.objects.get(string_id=realm_str).get_admin_users() + admins = Realm.objects.get(string_id=realm_str).get_human_admin_users() except Realm.DoesNotExist: return HttpResponseNotFound("Realm %s does not exist" % (realm_str,)) diff --git a/zerver/lib/actions.py b/zerver/lib/actions.py index de82cdf791..7f358a4461 100644 --- a/zerver/lib/actions.py +++ b/zerver/lib/actions.py @@ -225,7 +225,7 @@ def bot_owner_user_ids(user_profile: UserProfile) -> Set[int]: if is_private_bot: return {user_profile.bot_owner_id, } else: - users = {user.id for user in user_profile.realm.get_admin_users()} + users = {user.id for user in user_profile.realm.get_human_admin_users()} users.add(user_profile.bot_owner_id) return users diff --git a/zerver/lib/send_email.py b/zerver/lib/send_email.py index b59953ea9d..b93f37ee75 100644 --- a/zerver/lib/send_email.py +++ b/zerver/lib/send_email.py @@ -160,7 +160,7 @@ def send_future_email(template_prefix: str, realm: Realm, to_user_ids: Optional[ def send_email_to_admins(template_prefix: str, realm: Realm, from_name: Optional[str]=None, from_address: Optional[str]=None, context: Dict[str, Any]={}) -> None: - admins = realm.get_admin_users() + admins = realm.get_human_admin_users() admin_user_ids = [admin.id for admin in admins] send_email(template_prefix, to_user_ids=admin_user_ids, from_name=from_name, from_address=from_address, context=context) diff --git a/zerver/models.py b/zerver/models.py index a7b93df2ca..c81b6ac595 100644 --- a/zerver/models.py +++ b/zerver/models.py @@ -412,6 +412,11 @@ class Realm(models.Model): return UserProfile.objects.filter(realm=self, is_realm_admin=True, is_active=True) + def get_human_admin_users(self) -> Sequence['UserProfile']: + # TODO: Change return type to QuerySet[UserProfile] + return UserProfile.objects.filter(realm=self, is_bot=False, is_realm_admin=True, + is_active=True) + def get_active_users(self) -> Sequence['UserProfile']: # TODO: Change return type to QuerySet[UserProfile] return UserProfile.objects.filter(realm=self, is_active=True).select_related() diff --git a/zerver/tests/test_realm.py b/zerver/tests/test_realm.py index a563137756..49aec48a9a 100644 --- a/zerver/tests/test_realm.py +++ b/zerver/tests/test_realm.py @@ -234,7 +234,7 @@ class RealmTest(ZulipTestCase): self.assertTrue(re.search(self.TOKENIZED_NOREPLY_REGEX, tokenized_no_reply_email)) self.assertIn('Reactivate your Zulip organization', outbox[0].subject) self.assertIn('Dear former administrators', outbox[0].body) - admins = realm.get_admin_users() + admins = realm.get_human_admin_users() confirmation_url = self.get_confirmation_url_from_outbox(admins[0].email) response = self.client_get(confirmation_url) self.assert_in_success_response(['Your organization has been successfully reactivated'], response) diff --git a/zerver/tests/test_users.py b/zerver/tests/test_users.py index 688a361776..3e8f67b9fd 100644 --- a/zerver/tests/test_users.py +++ b/zerver/tests/test_users.py @@ -72,9 +72,14 @@ class PermissionTest(ZulipTestCase): def test_get_admin_users(self) -> None: user_profile = self.example_user('hamlet') do_change_is_admin(user_profile, False) + admin_users = user_profile.realm.get_human_admin_users() + self.assertFalse(user_profile in admin_users) admin_users = user_profile.realm.get_admin_users() self.assertFalse(user_profile in admin_users) + do_change_is_admin(user_profile, True) + admin_users = user_profile.realm.get_human_admin_users() + self.assertTrue(user_profile in admin_users) admin_users = user_profile.realm.get_admin_users() self.assertTrue(user_profile in admin_users) @@ -110,7 +115,7 @@ class PermissionTest(ZulipTestCase): with tornado_redirected_to_list(events): result = self.client_patch('/json/users/{}'.format(self.example_user("othello").id), req) self.assert_json_success(result) - admin_users = realm.get_admin_users() + admin_users = realm.get_human_admin_users() self.assertTrue(user in admin_users) person = events[0]['event']['person'] self.assertEqual(person['email'], self.example_email("othello")) @@ -122,7 +127,7 @@ class PermissionTest(ZulipTestCase): with tornado_redirected_to_list(events): result = self.client_patch('/json/users/{}'.format(self.example_user("othello").id), req) self.assert_json_success(result) - admin_users = realm.get_admin_users() + admin_users = realm.get_human_admin_users() self.assertFalse(user in admin_users) person = events[0]['event']['person'] self.assertEqual(person['email'], self.example_email("othello")) @@ -135,7 +140,7 @@ class PermissionTest(ZulipTestCase): with tornado_redirected_to_list(events): result = self.client_patch('/json/users/{}'.format(self.example_user("hamlet").id), req) self.assert_json_success(result) - admin_users = realm.get_admin_users() + admin_users = realm.get_human_admin_users() self.assertFalse(admin in admin_users) person = events[0]['event']['person'] self.assertEqual(person['email'], self.example_email("hamlet")) diff --git a/zerver/views/users.py b/zerver/views/users.py index b231755ed9..9b3945c83a 100644 --- a/zerver/views/users.py +++ b/zerver/views/users.py @@ -54,8 +54,8 @@ def deactivate_user_own_backend(request: HttpRequest, user_profile: UserProfile) return json_success() def check_last_admin(user_profile: UserProfile) -> bool: - admins = set(user_profile.realm.get_admin_users()) - return user_profile.is_realm_admin and len(admins) == 1 + admins = set(user_profile.realm.get_human_admin_users()) + return user_profile.is_realm_admin and not user_profile.is_bot and len(admins) == 1 def deactivate_bot_backend(request: HttpRequest, user_profile: UserProfile, bot_id: int) -> HttpResponse: