streams: Prevent creation of multi-line stream descriptions.

We do not anticipate our UI for showing stream descriptions looking
reasonable for multi-line descriptions, so we should just ban creating
them.

Given the frontend changes, multi-line descriptions are only likely to
show up from importing content from other tools, in which case
replacing newlines with spaces is cleaner than the alternative.
This commit is contained in:
Tim Abbott
2019-02-20 12:09:21 -08:00
parent 3134453220
commit cbc62b8e07
3 changed files with 27 additions and 2 deletions

View File

@@ -327,7 +327,7 @@ def build_stream(date_created: Any, realm_id: int, name: str,
stream = Stream(
name=name,
deactivated=deactivated,
description=description,
description=description.replace("\n", " "),
# We don't set rendered_description here; it'll be added on import
date_created=date_created,
invite_only=invite_only,

View File

@@ -174,6 +174,19 @@ class TestCreateStreams(ZulipTestCase):
for stream in existing_streams:
self.assertTrue(stream.invite_only)
def test_create_api_multiline_description(self) -> None:
user = self.example_user("hamlet")
realm = user.realm
self.login(user.email)
post_data = {'subscriptions': ujson.dumps([{"name": 'new_stream',
"description": "multi\nline\ndescription"}]),
'invite_only': ujson.dumps(False)}
result = self.api_post(user.email, "/api/v1/users/me/subscriptions", post_data,
subdomain="zulip")
self.assert_json_success(result)
stream = get_stream("new_stream", realm)
self.assertEqual(stream.description, 'multi line description')
def test_history_public_to_subscribers_on_stream_creation(self) -> None:
realm = get_realm('zulip')
stream_dicts = [
@@ -689,6 +702,12 @@ class StreamAdminTest(ZulipTestCase):
self.assert_json_error(result, "description is too long (limit: %s characters)"
% (Stream.MAX_DESCRIPTION_LENGTH))
result = self.client_patch('/json/streams/%d' % (stream_id,),
{'description': ujson.dumps('a\nmulti\nline\ndescription')})
self.assert_json_success(result)
stream = get_stream('stream_name1', realm)
self.assertEqual(stream.description, 'a multi line description')
def test_change_stream_description_requires_realm_admin(self) -> None:
user_profile = self.example_user('hamlet')
email = user_profile.email

View File

@@ -158,6 +158,9 @@ def update_stream_backend(
# description even for private streams.
stream = access_stream_for_delete_or_update(user_profile, stream_id)
if description is not None:
if '\n' in description:
# We don't allow newline characters in stream descriptions.
description = description.replace("\n", " ")
do_change_stream_description(stream, description)
if new_name is not None:
new_name = new_name.strip()
@@ -278,7 +281,7 @@ def you_were_just_subscribed_message(acting_user: UserProfile,
@has_request_variables
def add_subscriptions_backend(
request: HttpRequest, user_profile: UserProfile,
streams_raw: Iterable[Mapping[str, str]]=REQ(
streams_raw: Iterable[Dict[str, str]]=REQ(
"subscriptions", validator=check_list(check_dict_only(
[('name', check_string)], optional_keys=[
('color', check_color),
@@ -299,6 +302,9 @@ def add_subscriptions_backend(
# check for its presence in the streams_raw first
if 'color' in stream_dict:
color_map[stream_dict['name']] = stream_dict['color']
if 'description' in stream_dict:
# We don't allow newline characters in stream descriptions.
stream_dict['description'] = stream_dict['description'].replace("\n", " ")
stream_dict_copy = {} # type: Dict[str, Any]
for field in stream_dict: