From 499a70b01e594157b0a9426cb7793db60d279e4d Mon Sep 17 00:00:00 2001 From: Shubham Dhama Date: Thu, 26 Jul 2018 23:49:45 +0530 Subject: [PATCH] notifications: Fix leaking of private stream msgs sent before subscribing. Fixes: #9834. --- zerver/lib/notifications.py | 8 ++++-- zerver/tests/test_notifications.py | 39 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/zerver/lib/notifications.py b/zerver/lib/notifications.py index 69c1e4c5ed..4748ae6687 100644 --- a/zerver/lib/notifications.py +++ b/zerver/lib/notifications.py @@ -6,9 +6,11 @@ from django.conf import settings from django.template import loader from django.utils.timezone import now as timezone_now from django.utils.translation import ugettext as _ + from zerver.decorator import statsd_increment -from zerver.lib.send_email import send_future_email, FromAddress +from zerver.lib.message import bulk_access_messages from zerver.lib.queue import queue_json_publish +from zerver.lib.send_email import send_future_email, FromAddress from zerver.lib.url_encoding import pm_narrow_url, stream_narrow_url, topic_narrow_url from zerver.models import ( Recipient, @@ -422,7 +424,9 @@ def handle_missedmessage_emails(user_profile_id: int, for msg_list in messages_by_recipient_subject.values(): msg = min(msg_list, key=lambda msg: msg.pub_date) if msg.is_stream_message(): - msg_list.extend(get_context_for_message(msg)) + context_messages = get_context_for_message(msg) + filtered_context_messages = bulk_access_messages(user_profile, context_messages) + msg_list.extend(filtered_context_messages) # Sort emails by least recently-active discussion. recipient_subjects = [] # type: List[Tuple[Tuple[int, str], int]] diff --git a/zerver/tests/test_notifications.py b/zerver/tests/test_notifications.py index 8d4cf53b95..df86a5e6e7 100644 --- a/zerver/tests/test_notifications.py +++ b/zerver/tests/test_notifications.py @@ -550,6 +550,45 @@ class TestMissedMessages(ZulipTestCase): subject = 'Othello, the Moor of Venice mentioned you' self.assertEqual(mail.outbox[0].subject, subject) + @patch('zerver.lib.email_mirror.generate_random_token') + def test_message_access_in_emails(self, mock_random_token: MagicMock) -> None: + # Messages sent to a protected history-private stream shouldn't be + # accessible/available in emails before subscribing + tokens = self._get_tokens() + mock_random_token.side_effect = tokens + + stream_name = "private_stream" + self.make_stream(stream_name, invite_only=True, + history_public_to_subscribers=False) + user = self.example_user('iago') + self.subscribe(user, stream_name) + late_subscribed_user = self.example_user('hamlet') + + self.send_stream_message(user.email, + stream_name, + 'Before subscribing') + + self.subscribe(late_subscribed_user, stream_name) + + self.send_stream_message(user.email, + stream_name, + "After subscribing") + + mention_msg_id = self.send_stream_message(user.email, + stream_name, + '@**King Hamlet**') + + handle_missedmessage_emails(late_subscribed_user.id, [ + {'message_id': mention_msg_id, "trigger": "mentioned"}, + ]) + + self.assertEqual(len(mail.outbox), 1) + self.assertEqual(mail.outbox[0].subject, 'Iago mentioned you') + email_text = mail.outbox[0].message().as_string() + self.assertNotIn('Before subscribing', email_text) + self.assertIn('After subscribing', email_text) + self.assertIn('@**King Hamlet**', email_text) + @patch('zerver.lib.email_mirror.generate_random_token') def test_stream_mentions_multiple_people(self, mock_random_token: MagicMock) -> None: """A mention should take precedence over regular stream messages for email subjects.