From 99c5563bc6d8c9561506bf869117f7ae2ae4a099 Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Sat, 21 Jan 2017 20:23:36 -0800 Subject: [PATCH] internal_send_message: Make realm argument mandatory. A lot of care has been taken to ensure we're using the realm that the message is being sent into, not the realm of the sender, to correctly handle the logic for cross-realm bot users such as the notifications bot. --- zerver/lib/actions.py | 19 +++++++++++++------ zerver/lib/bugdown/__init__.py | 4 +++- zerver/lib/email_mirror.py | 8 ++++---- zerver/lib/html_diff.py | 4 +++- zerver/views/invite.py | 4 ++-- zerver/views/tutorial.py | 4 ++-- zerver/worker/queue_processors.py | 4 +++- zilencer/error_notify.py | 7 +++++-- zilencer/views.py | 3 ++- 9 files changed, 37 insertions(+), 20 deletions(-) diff --git a/zerver/lib/actions.py b/zerver/lib/actions.py index a8884b700d..01dd25f5c9 100644 --- a/zerver/lib/actions.py +++ b/zerver/lib/actions.py @@ -228,14 +228,18 @@ def send_signup_message(sender, signups_stream, user_profile, # Don't send notification for the first user in a realm if user_profile.realm.notifications_stream is not None and user_count > 1: internal_send_message( + user_profile.realm, sender, "stream", user_profile.realm.notifications_stream.name, "New users", "%s just signed up for Zulip. Say hello!" % ( - user_profile.full_name,), - realm=user_profile.realm) + user_profile.full_name,) + ) + # We also send a notification to the Zulip administrative realm + admin_realm = get_user_profile_by_email(sender).realm internal_send_message( + admin_realm, sender, "stream", signups_stream, @@ -309,6 +313,7 @@ def process_new_human_user(user_profile, prereg_user=None, newsletter_data=None) and settings.NOTIFICATION_BOT is not None: # This is a cross-realm private message. internal_send_message( + user_profile.realm, settings.NOTIFICATION_BOT, "private", prereg_user.referred_by.email, @@ -1378,9 +1383,9 @@ def internal_prep_message(realm, sender_email, recipient_type_name, recipients, return None -def internal_send_message(sender_email, recipient_type_name, recipients, - subject, content, realm=None): - # type: (Text, str, Text, Text, Text, Optional[Realm]) -> None +def internal_send_message(realm, sender_email, recipient_type_name, recipients, + subject, content): + # type: (Realm, Text, str, Text, Text, Text) -> None msg = internal_prep_message(realm, sender_email, recipient_type_name, recipients, subject, content) @@ -2179,9 +2184,11 @@ system-generated notifications.""" % (product_name, notifications_stream.name,) "invite_required": invite_required, "org_type": org_type}) + # Send a notification to the admin realm (if configured) if settings.NEW_USER_BOT is not None: signup_message = "Signups enabled" - internal_send_message(settings.NEW_USER_BOT, "stream", + admin_realm = get_user_profile_by_email(settings.NEW_USER_BOT).realm + internal_send_message(admin_realm, settings.NEW_USER_BOT, "stream", "signups", string_id, signup_message) return (realm, created) diff --git a/zerver/lib/bugdown/__init__.py b/zerver/lib/bugdown/__init__.py index f8b7cafe09..8c1f328e64 100644 --- a/zerver/lib/bugdown/__init__.py +++ b/zerver/lib/bugdown/__init__.py @@ -1333,6 +1333,7 @@ def do_convert(content, realm_filters_key=None, message=None, possible_words=Non return timeout(5, _md_engine.convert, content) except: from zerver.lib.actions import internal_send_message + from zerver.models import get_user_profile_by_email cleaned = _sanitize_for_log(content) @@ -1341,7 +1342,8 @@ def do_convert(content, realm_filters_key=None, message=None, possible_words=Non % (traceback.format_exc(), cleaned)) subject = "Markdown parser failure on %s" % (platform.node(),) if settings.ERROR_BOT is not None: - internal_send_message(settings.ERROR_BOT, "stream", + error_bot_realm = get_user_profile_by_email(settings.ERROR_BOT).realm + internal_send_message(error_bot_realm, settings.ERROR_BOT, "stream", "errors", subject, "Markdown parser failed, email sent with details.") mail.mail_admins(subject, "Failed message: %s\n\n%s\n\n" % ( cleaned, traceback.format_exc()), diff --git a/zerver/lib/email_mirror.py b/zerver/lib/email_mirror.py index 2bdbdc3429..5ffadf47ff 100644 --- a/zerver/lib/email_mirror.py +++ b/zerver/lib/email_mirror.py @@ -176,8 +176,8 @@ def send_to_missed_message_address(address, message): else: recipient_type_name = 'private' - internal_send_message(user_profile.email, recipient_type_name, - recipient_str, subject, body) + internal_send_message(user_profile.realm, user_profile.email, + recipient_type_name, recipient_str, subject, body) logging.info("Successfully processed email from %s to %s" % ( user_profile.email, recipient_str)) @@ -189,12 +189,12 @@ class ZulipEmailForwardError(Exception): def send_zulip(sender, stream, topic, content): # type: (Text, Stream, Text, Text) -> None internal_send_message( + stream.realm, sender, "stream", stream.name, topic[:60], - content[:2000], - stream.realm) + content[:2000]) def valid_stream(stream_name, token): # type: (Text, Text) -> bool diff --git a/zerver/lib/html_diff.py b/zerver/lib/html_diff.py index 900ac147d7..335f07138d 100644 --- a/zerver/lib/html_diff.py +++ b/zerver/lib/html_diff.py @@ -116,12 +116,14 @@ def highlight_html_differences(s1, s2): if not verify_html(retval): from zerver.lib.actions import internal_send_message + from zerver.models import get_user_profile_by_email # We probably want more information here logging.getLogger('').error('HTML diff produced mal-formed HTML') if settings.ERROR_BOT is not None: subject = "HTML diff failure on %s" % (platform.node(),) - internal_send_message(settings.ERROR_BOT, "stream", + realm = get_user_profile_by_email(settings.ERROR_BOT).realm + internal_send_message(realm, settings.ERROR_BOT, "stream", "errors", subject, "HTML diff produced malformed HTML") return s2 diff --git a/zerver/views/invite.py b/zerver/views/invite.py index b39c30fda0..a43cf3351b 100644 --- a/zerver/views/invite.py +++ b/zerver/views/invite.py @@ -79,8 +79,8 @@ def json_bulk_invite_users(request, user_profile, invited = PreregistrationUser.objects.filter(referred_by=user_profile) internal_message = "%s <`%s`> invited %d people to Zulip." % ( user_profile.full_name, user_profile.email, invited.count()) - internal_send_message(settings.NEW_USER_BOT, "stream", "signups", - user_profile.realm.domain, internal_message) + internal_send_message(user_profile.realm, settings.NEW_USER_BOT, "stream", + "signups", user_profile.realm.domain, internal_message) return json_success() @authenticated_json_post_view diff --git a/zerver/views/tutorial.py b/zerver/views/tutorial.py index 0468aa05c0..f04bba43cc 100644 --- a/zerver/views/tutorial.py +++ b/zerver/views/tutorial.py @@ -23,8 +23,8 @@ def json_tutorial_send_message(request, user_profile, type=REQ(validator=check_s """ sender_name = "welcome-bot@zulip.com" if type == 'stream': - internal_send_message(sender_name, "stream", recipient, topic, content, - realm=user_profile.realm) + internal_send_message(user_profile.realm, sender_name, + "stream", recipient, topic, content) return json_success() # For now, there are no PM cases. return json_error(_('Bad data passed in to tutorial_send_message')) diff --git a/zerver/worker/queue_processors.py b/zerver/worker/queue_processors.py index 0fd112c3af..5b722d1c24 100644 --- a/zerver/worker/queue_processors.py +++ b/zerver/worker/queue_processors.py @@ -301,7 +301,9 @@ class SlowQueryWorker(QueueProcessingWorker): for query in slow_queries: content += " %s\n" % (query,) - internal_send_message(settings.ERROR_BOT, "stream", "logs", topic, content) + error_bot_realm = get_user_profile_by_email(settings.ERROR_BOT).realm + internal_send_message(error_bot_realm, settings.ERROR_BOT, + "stream", "logs", topic, content) reset_queries() diff --git a/zilencer/error_notify.py b/zilencer/error_notify.py index 2822e898bd..c6f8d9e5bd 100644 --- a/zilencer/error_notify.py +++ b/zilencer/error_notify.py @@ -6,6 +6,7 @@ import logging from django.conf import settings from django.core.mail import mail_admins +from zerver.models import get_user_profile_by_email from zerver.lib.actions import internal_send_message from typing import Dict import six @@ -66,7 +67,8 @@ def zulip_browser_error(report): body += ("Message: %(message)s\n" % (report)) - internal_send_message(settings.ERROR_BOT, + realm = get_user_profile_by_email(settings.ERROR_BOT).realm + internal_send_message(realm, settings.ERROR_BOT, "stream", "errors", format_subject(subject), body) def notify_server_error(report): @@ -92,7 +94,8 @@ def zulip_server_error(report): request_repr += "- %s: \"%s\"\n" % (field, report.get(field.lower())) request_repr += "~~~~" - internal_send_message(settings.ERROR_BOT, + realm = get_user_profile_by_email(settings.ERROR_BOT).realm + internal_send_message(realm, settings.ERROR_BOT, "stream", "errors", format_subject(subject), "Error generated by %s\n\n~~~~ pytb\n%s\n\n~~~~\n%s" % ( user_info, stack_trace, request_repr)) diff --git a/zilencer/views.py b/zilencer/views.py index d03ca246eb..4e64be531f 100644 --- a/zilencer/views.py +++ b/zilencer/views.py @@ -77,7 +77,8 @@ def submit_feedback(request, deployment, message=REQ(validator=check_dict([]))): content += message['content'] - internal_send_message("feedback@zulip.com", "stream", "support", subject, content) + internal_send_message(realm_for_email("feedback@zulip.com"), "feedback@zulip.com", + "stream", "support", subject, content) return HttpResponse(message['sender_email'])