bots: Re-parent bot while reactivating if original owner is deactivated.

Since the original owner is deactivated, we change the owner to the
admin who is reactivating the bot.
This commit is contained in:
Sahil Batra 2022-04-21 19:34:52 +05:30 committed by Tim Abbott
parent 133bd1e4cb
commit ba00907946
4 changed files with 66 additions and 0 deletions

View File

@ -255,6 +255,10 @@ python_rules = RuleList(
"zerver/actions/bots.py",
"user_profile.save() # Can't use update_fields because of how the foreign key works.",
),
(
"zerver/actions/create_user.py",
"user_profile.save() # Can't use update_fields because of how the foreign key works.",
),
},
"exclude": {"zerver/tests", "zerver/lib/create_user.py"},
"good_lines": ['user_profile.save(update_fields=["pointer"])'],

View File

@ -606,6 +606,26 @@ def do_reactivate_user(user_profile: UserProfile, *, acting_user: Optional[UserP
}
).decode(),
)
bot_owner_changed = False
if (
user_profile.is_bot
and user_profile.bot_owner is not None
and not user_profile.bot_owner.is_active
and acting_user is not None
):
previous_owner = user_profile.bot_owner
user_profile.bot_owner = acting_user
user_profile.save() # Can't use update_fields because of how the foreign key works.
RealmAuditLog.objects.create(
realm=user_profile.realm,
acting_user=acting_user,
modified_user=user_profile,
event_type=RealmAuditLog.USER_BOT_OWNER_CHANGED,
event_time=event_time,
)
bot_owner_changed = True
do_increment_logging_stat(
user_profile.realm,
COUNT_STATS["active_users_log:is_bot:day"],
@ -620,6 +640,12 @@ def do_reactivate_user(user_profile: UserProfile, *, acting_user: Optional[UserP
if user_profile.is_bot:
notify_created_bot(user_profile)
if bot_owner_changed:
from zerver.actions.bots import send_bot_owner_update_events
assert acting_user is not None
send_bot_owner_update_events(user_profile, acting_user, previous_owner)
subscribed_recipient_ids = Subscription.objects.filter(
user_profile_id=user_profile.id, active=True, recipient__type=Recipient.STREAM
).values_list("recipient__type_id", flat=True)

View File

@ -849,6 +849,29 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
profile = get_user(bot_email, bot_realm)
self.assertEqual(profile.bot_type, UserProfile.DEFAULT_BOT)
def test_reactivating_bot_with_deactivated_owner(self) -> None:
self.login("hamlet")
bot_info = {
"full_name": "Test bot",
"short_name": "testbot",
"bot_type": "1",
}
result = self.client_post("/json/bots", bot_info)
bot_id = result.json()["user_id"]
test_bot = UserProfile.objects.get(id=bot_id, is_bot=True)
do_deactivate_user(test_bot, acting_user=None)
# Deactivate the bot owner
do_deactivate_user(self.example_user("hamlet"), acting_user=None)
self.login("iago")
result = self.client_post(f"/json/users/{bot_id}/reactivate")
self.assert_json_success(result)
test_bot = UserProfile.objects.get(id=bot_id, is_bot=True)
assert test_bot.bot_owner is not None
self.assertEqual(test_bot.bot_owner.id, self.example_user("iago").id)
def test_patch_bot_full_name(self) -> None:
self.login("hamlet")
bot_info = {

View File

@ -2445,6 +2445,19 @@ class NormalActionsTest(BaseAction):
check_subscription_peer_add("events[2]", events[2])
check_subscription_peer_add("events[3]", events[3])
do_deactivate_user(bot, acting_user=None)
do_deactivate_user(self.example_user("hamlet"), acting_user=None)
reset_email_visibility_to_everyone_in_zulip_realm()
bot.refresh_from_db()
self.user_profile = self.example_user("iago")
action = lambda: do_reactivate_user(bot, acting_user=self.example_user("iago"))
events = self.verify_action(action, num_events=6)
check_realm_bot_add("events[1]", events[1])
check_realm_bot_update("events[2]", events[2], "owner_id")
check_realm_user_update("events[3]", events[3], "bot_owner_id")
def test_do_deactivate_realm(self) -> None:
realm = self.user_profile.realm
action = lambda: do_deactivate_realm(realm, acting_user=None)