message: Restrict sending DMs to inaccessible users.

This commit adds code to not allow guest users to send DMs
to users they cannot access.
This commit is contained in:
Sahil Batra 2023-10-25 12:45:41 +05:30 committed by Tim Abbott
parent 39a31170ee
commit e4a97dd3ac
2 changed files with 87 additions and 0 deletions

View File

@ -75,6 +75,7 @@ from zerver.lib.timestamp import timestamp_to_datetime
from zerver.lib.topic import participants_for_topic
from zerver.lib.url_preview.types import UrlEmbedData
from zerver.lib.user_message import UserMessageLite, bulk_insert_ums
from zerver.lib.users import check_user_can_access_all_users, get_accessible_user_ids
from zerver.lib.validator import check_widget_content
from zerver.lib.widget import do_widget_post_save_actions
from zerver.models import (
@ -1460,6 +1461,21 @@ def check_private_message_policy(
raise JsonableError(_("Direct messages are disabled in this organization."))
def check_sender_can_access_recipients(
realm: Realm, sender: UserProfile, user_profiles: Sequence[UserProfile]
) -> None:
if check_user_can_access_all_users(sender):
return
users_accessible_to_sender = set(get_accessible_user_ids(realm, sender))
# Guest users can access all the bots (including cross-realm bots).
non_bot_recipient_user_ids = {user.id for user in user_profiles if not user.is_bot}
inaccessible_recipients = non_bot_recipient_user_ids - users_accessible_to_sender
if inaccessible_recipients:
raise JsonableError(_("You do not have permission to access some of the recipients."))
# check_message:
# Returns message ready for sending with do_send_message on success or the error message (string) on error.
def check_message(
@ -1545,6 +1561,8 @@ def check_message(
"JabberMirror",
]
check_sender_can_access_recipients(realm, sender, user_profiles)
check_private_message_policy(realm, sender, user_profiles)
# API super-users who set the `forged` flag are allowed to

View File

@ -777,6 +777,75 @@ class MessagePOSTTest(ZulipTestCase):
)
self.assert_json_error(result, f"'{othello.email}' is no longer using Zulip.")
def test_personal_message_to_inaccessible_users(self) -> None:
othello = self.example_user("othello")
cordelia = self.example_user("cordelia")
hamlet = self.example_user("hamlet")
iago = self.example_user("iago")
self.set_up_db_for_testing_user_access()
self.login("polonius")
result = self.client_post(
"/json/messages",
{
"type": "direct",
"content": "Test direct message",
"to": orjson.dumps([othello.id]).decode(),
},
)
self.assert_json_error(
result, "You do not have permission to access some of the recipients."
)
result = self.client_post(
"/json/messages",
{
"type": "direct",
"content": "Test direct message",
"to": orjson.dumps([hamlet.id]).decode(),
},
)
self.assert_json_success(result)
msg = self.get_last_message()
self.assertEqual(msg.content, "Test direct message")
result = self.client_post(
"/json/messages",
{
"type": "direct",
"content": "Test group direct message",
"to": orjson.dumps([othello.id, cordelia.id]).decode(),
},
)
self.assert_json_error(
result, "You do not have permission to access some of the recipients."
)
result = self.client_post(
"/json/messages",
{
"type": "direct",
"content": "Test group direct message",
"to": orjson.dumps([hamlet.id, cordelia.id]).decode(),
},
)
self.assert_json_error(
result, "You do not have permission to access some of the recipients."
)
result = self.client_post(
"/json/messages",
{
"type": "direct",
"content": "Test group direct message",
"to": orjson.dumps([hamlet.id, iago.id]).decode(),
},
)
self.assert_json_success(result)
msg = self.get_last_message()
self.assertEqual(msg.content, "Test group direct message")
def test_invalid_type(self) -> None:
"""
Sending a message of unknown type returns error JSON.