diff --git a/zerver/lib/actions.py b/zerver/lib/actions.py index b618b73c81..7a118b5324 100644 --- a/zerver/lib/actions.py +++ b/zerver/lib/actions.py @@ -2162,7 +2162,12 @@ def validate_sender_can_write_to_stream(sender: UserProfile, # matches the realm of the sender. if stream.is_announcement_only: - if not (sender.is_realm_admin or is_cross_realm_bot_email(sender.email)): + if sender.is_realm_admin or is_cross_realm_bot_email(sender.email): + pass + elif sender.is_bot and (sender.bot_owner is not None and + sender.bot_owner.is_realm_admin): + pass + else: raise JsonableError(_("Only organization administrators can send to this stream.")) if not (stream.invite_only or sender.is_guest): diff --git a/zerver/tests/test_messages.py b/zerver/tests/test_messages.py index 947d7e5dfa..50c3e10835 100644 --- a/zerver/tests/test_messages.py +++ b/zerver/tests/test_messages.py @@ -1451,6 +1451,18 @@ class MessagePOSTTest(ZulipTestCase): "topic": "Test topic"}) self.assert_json_success(result) + admin_owned_bot = self.create_test_bot( + short_name='whatever', + user_profile=user_profile, + ) + result = self.api_post(admin_owned_bot.email, + "/api/v1/messages", {"type": "stream", + "to": stream_name, + "client": "test suite", + "content": "Test message", + "topic": "Test topic"}) + self.assert_json_success(result) + def test_message_fail_to_announce(self) -> None: """ Sending a message to an announcement_only stream not by a realm @@ -1470,6 +1482,36 @@ class MessagePOSTTest(ZulipTestCase): "topic": "Test topic"}) self.assert_json_error(result, "Only organization administrators can send to this stream.") + # Non admin owned bot fail to send to announcement only stream + non_admin_owned_bot = self.create_test_bot( + short_name='whatever', + user_profile=user_profile, + ) + result = self.api_post(non_admin_owned_bot.email, + "/api/v1/messages", {"type": "stream", + "to": stream_name, + "client": "test suite", + "content": "Test message", + "topic": "Test topic"}) + self.assert_json_error(result, "Only organization administrators can send to this stream.") + + # Bots without owner (except cross realm bot) fail to send to announcement only stream + bot_without_owner = do_create_user( + email='free-bot@zulip.testserver', + password='', + realm=user_profile.realm, + full_name='freebot', + short_name='freebot', + bot_type=UserProfile.DEFAULT_BOT, + ) + result = self.api_post(bot_without_owner.email, + "/api/v1/messages", {"type": "stream", + "to": stream_name, + "client": "test suite", + "content": "Test message", + "topic": "Test topic"}) + self.assert_json_error(result, "Only organization administrators can send to this stream.") + def test_api_message_with_default_to(self) -> None: """ Sending messages without a to field should be sent to the default