settings: Make `MAX_MESSAGE_LENGTH` a server-level setting.

This will offer users who are self-hosting to adjust
this value. Moreover, this will help to reduce the
overall time taken to test `test_markdown.py` (since
this can be now overridden with `override_settings`
Django decorator).

This is done as a prep commit for #18641.
This commit is contained in:
akshatdalton 2021-06-03 13:04:22 +00:00 committed by Tim Abbott
parent 9b9d30152a
commit 7df62ebbaf
8 changed files with 14 additions and 11 deletions

View File

@ -187,7 +187,6 @@ from zerver.lib.utils import generate_api_key, log_statsd_event
from zerver.lib.validator import check_widget_content from zerver.lib.validator import check_widget_content
from zerver.lib.widget import do_widget_post_save_actions, is_widget_message from zerver.lib.widget import do_widget_post_save_actions, is_widget_message
from zerver.models import ( from zerver.models import (
MAX_MESSAGE_LENGTH,
Attachment, Attachment,
Client, Client,
CustomProfileField, CustomProfileField,
@ -3197,7 +3196,7 @@ def _internal_prep_message(
Call do_send_messages with a list of the return values of this method. Call do_send_messages with a list of the return values of this method.
""" """
# Remove any null bytes from the content # Remove any null bytes from the content
if len(content) > MAX_MESSAGE_LENGTH: if len(content) > settings.MAX_MESSAGE_LENGTH:
content = content[0:3900] + "\n\n[message was too long and has been truncated]" content = content[0:3900] + "\n\n[message was too long and has been truncated]"
# If we have a stream name, and the stream doesn't exist, we # If we have a stream name, and the stream doesn't exist, we

View File

@ -50,7 +50,6 @@ from zerver.lib.user_mutes import get_user_mutes
from zerver.lib.user_status import get_user_info_dict from zerver.lib.user_status import get_user_info_dict
from zerver.lib.users import get_cross_realm_dicts, get_raw_user_data, is_administrator_role from zerver.lib.users import get_cross_realm_dicts, get_raw_user_data, is_administrator_role
from zerver.models import ( from zerver.models import (
MAX_MESSAGE_LENGTH,
MAX_TOPIC_NAME_LENGTH, MAX_TOPIC_NAME_LENGTH,
Client, Client,
CustomProfileField, CustomProfileField,
@ -300,7 +299,7 @@ def fetch_initial_state_data(
state["max_stream_name_length"] = Stream.MAX_NAME_LENGTH state["max_stream_name_length"] = Stream.MAX_NAME_LENGTH
state["max_stream_description_length"] = Stream.MAX_DESCRIPTION_LENGTH state["max_stream_description_length"] = Stream.MAX_DESCRIPTION_LENGTH
state["max_topic_length"] = MAX_TOPIC_NAME_LENGTH state["max_topic_length"] = MAX_TOPIC_NAME_LENGTH
state["max_message_length"] = MAX_MESSAGE_LENGTH state["max_message_length"] = settings.MAX_MESSAGE_LENGTH
if want("realm_domains"): if want("realm_domains"):
state["realm_domains"] = get_realm_domains(realm) state["realm_domains"] = get_realm_domains(realm)

View File

@ -62,7 +62,6 @@ from zerver.lib.types import LinkifierDict
from zerver.lib.url_encoding import encode_stream, hash_util_encode from zerver.lib.url_encoding import encode_stream, hash_util_encode
from zerver.lib.url_preview import preview as link_preview from zerver.lib.url_preview import preview as link_preview
from zerver.models import ( from zerver.models import (
MAX_MESSAGE_LENGTH,
Message, Message,
Realm, Realm,
UserGroup, UserGroup,
@ -2612,6 +2611,7 @@ def do_convert(
# Throw an exception if the content is huge; this protects the # Throw an exception if the content is huge; this protects the
# rest of the codebase from any bugs where we end up rendering # rest of the codebase from any bugs where we end up rendering
# something huge. # something huge.
MAX_MESSAGE_LENGTH = settings.MAX_MESSAGE_LENGTH
if len(rendered_content) > MAX_MESSAGE_LENGTH * 10: if len(rendered_content) > MAX_MESSAGE_LENGTH * 10:
raise MarkdownRenderingException( raise MarkdownRenderingException(
f"Rendered content exceeds {MAX_MESSAGE_LENGTH * 10} characters (message {logging_message_id})" f"Rendered content exceeds {MAX_MESSAGE_LENGTH * 10} characters (message {logging_message_id})"

View File

@ -6,6 +6,7 @@ from typing import Any, Dict, List, Optional, Sequence, Set, Tuple
import ahocorasick import ahocorasick
import orjson import orjson
from django.conf import settings
from django.db import connection from django.db import connection
from django.db.models import Max, Sum from django.db.models import Max, Sum
from django.utils.timezone import now as timezone_now from django.utils.timezone import now as timezone_now
@ -38,7 +39,6 @@ from zerver.lib.timestamp import datetime_to_timestamp
from zerver.lib.topic import DB_TOPIC_NAME, MESSAGE__TOPIC, TOPIC_LINKS, TOPIC_NAME from zerver.lib.topic import DB_TOPIC_NAME, MESSAGE__TOPIC, TOPIC_LINKS, TOPIC_NAME
from zerver.lib.topic_mutes import build_topic_mute_checker, topic_is_muted from zerver.lib.topic_mutes import build_topic_mute_checker, topic_is_muted
from zerver.models import ( from zerver.models import (
MAX_MESSAGE_LENGTH,
MAX_TOPIC_NAME_LENGTH, MAX_TOPIC_NAME_LENGTH,
Message, Message,
Reaction, Reaction,
@ -129,7 +129,7 @@ def normalize_body(body: str) -> str:
raise JsonableError(_("Message must not be empty")) raise JsonableError(_("Message must not be empty"))
if "\x00" in body: if "\x00" in body:
raise JsonableError(_("Message must not contain null bytes")) raise JsonableError(_("Message must not contain null bytes"))
return truncate_content(body, MAX_MESSAGE_LENGTH, "\n[message truncated]") return truncate_content(body, settings.MAX_MESSAGE_LENGTH, "\n[message truncated]")
def truncate_topic(topic: str) -> str: def truncate_topic(topic: str) -> str:

View File

@ -90,7 +90,6 @@ from zerver.lib.validator import (
) )
MAX_TOPIC_NAME_LENGTH = 60 MAX_TOPIC_NAME_LENGTH = 60
MAX_MESSAGE_LENGTH = 10000
MAX_LANGUAGE_ID_LENGTH: int = 50 MAX_LANGUAGE_ID_LENGTH: int = 50
STREAM_NAMES = TypeVar("STREAM_NAMES", Sequence[str], AbstractSet[str]) STREAM_NAMES = TypeVar("STREAM_NAMES", Sequence[str], AbstractSet[str])

View File

@ -48,7 +48,6 @@ from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.tex import render_tex from zerver.lib.tex import render_tex
from zerver.lib.user_groups import create_user_group from zerver.lib.user_groups import create_user_group
from zerver.models import ( from zerver.models import (
MAX_MESSAGE_LENGTH,
Message, Message,
RealmEmoji, RealmEmoji,
RealmFilter, RealmFilter,
@ -2748,10 +2747,11 @@ class MarkdownErrorTests(ZulipTestCase):
with self.assertRaises(JsonableError): with self.assertRaises(JsonableError):
self.send_stream_message(self.example_user("othello"), "Denmark", message) self.send_stream_message(self.example_user("othello"), "Denmark", message)
@override_settings(MAX_MESSAGE_LENGTH=10)
def test_ultra_long_rendering(self) -> None: def test_ultra_long_rendering(self) -> None:
"""A rendered message with an ultra-long length (> 10 * MAX_MESSAGE_LENGTH) """A rendered message with an ultra-long length (> 10 * MAX_MESSAGE_LENGTH)
throws an exception""" throws an exception"""
msg = "mock rendered message\n" * MAX_MESSAGE_LENGTH msg = "mock rendered message\n" * settings.MAX_MESSAGE_LENGTH
with mock.patch("zerver.lib.markdown.timeout", return_value=msg), mock.patch( with mock.patch("zerver.lib.markdown.timeout", return_value=msg), mock.patch(
"zerver.lib.markdown.markdown_logger" "zerver.lib.markdown.markdown_logger"

View File

@ -48,7 +48,6 @@ from zerver.lib.test_helpers import (
) )
from zerver.lib.timestamp import convert_to_UTC, datetime_to_timestamp from zerver.lib.timestamp import convert_to_UTC, datetime_to_timestamp
from zerver.models import ( from zerver.models import (
MAX_MESSAGE_LENGTH,
MAX_TOPIC_NAME_LENGTH, MAX_TOPIC_NAME_LENGTH,
Message, Message,
Realm, Realm,
@ -900,12 +899,14 @@ class MessagePOSTTest(ZulipTestCase):
sent_message = self.get_last_message() sent_message = self.get_last_message()
self.assertEqual(sent_message.content, " I like whitespace at the end!") self.assertEqual(sent_message.content, " I like whitespace at the end!")
@override_settings(MAX_MESSAGE_LENGTH=25)
def test_long_message(self) -> None: def test_long_message(self) -> None:
""" """
Sending a message longer than the maximum message length succeeds but is Sending a message longer than the maximum message length succeeds but is
truncated. truncated.
""" """
self.login("hamlet") self.login("hamlet")
MAX_MESSAGE_LENGTH = settings.MAX_MESSAGE_LENGTH
long_message = "A" * (MAX_MESSAGE_LENGTH + 1) long_message = "A" * (MAX_MESSAGE_LENGTH + 1)
post_data = { post_data = {
"type": "stream", "type": "stream",

View File

@ -452,3 +452,8 @@ SERVER_UPGRADE_NAG_DEADLINE_DAYS = 30 * 18
# How long servers have to respond to outgoing webhook requests # How long servers have to respond to outgoing webhook requests
OUTGOING_WEBHOOK_TIMEOUT_SECONDS = 10 OUTGOING_WEBHOOK_TIMEOUT_SECONDS = 10
# Maximum length of message content allowed.
# Any message content exceeding this limit will be truncated.
# See: `_internal_prep_message` function in zerver/lib/actions.py.
MAX_MESSAGE_LENGTH = 10000