diff --git a/templates/zerver/api/changelog.md b/templates/zerver/api/changelog.md index fd7b75a830..d8eff38c30 100644 --- a/templates/zerver/api/changelog.md +++ b/templates/zerver/api/changelog.md @@ -10,6 +10,11 @@ below features are supported. ## Changes in Zulip 4.0 +**Feature level 34** + +* [`POST /register`](/api/register-queue): Added a new `wildcard_mention_policy` + setting for controlling who can use wildcard mentions in large streams. + **Feature level 33** * Markdown code blocks now have a `data-code-language` attribute diff --git a/version.py b/version.py index 1d7abac1c3..09e2e54c68 100644 --- a/version.py +++ b/version.py @@ -29,7 +29,7 @@ DESKTOP_WARNING_VERSION = "5.2.0" # # Changes should be accompanied by documentation explaining what the # new level means in templates/zerver/api/changelog.md. -API_FEATURE_LEVEL = 33 +API_FEATURE_LEVEL = 34 # Bump the minor PROVISION_VERSION to indicate that folks should provision # only when going from an old version of the code to a newer version. Bump diff --git a/zerver/migrations/0303_realm_wildcard_mention_policy.py b/zerver/migrations/0303_realm_wildcard_mention_policy.py new file mode 100644 index 0000000000..c00531828b --- /dev/null +++ b/zerver/migrations/0303_realm_wildcard_mention_policy.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.14 on 2020-09-04 16:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('zerver', '0302_case_insensitive_stream_name_index'), + ] + + operations = [ + migrations.AddField( + model_name='realm', + name='wildcard_mention_policy', + field=models.PositiveSmallIntegerField(default=4), + ), + ] diff --git a/zerver/models.py b/zerver/models.py index da11d024ab..836838bfe5 100644 --- a/zerver/models.py +++ b/zerver/models.py @@ -256,6 +256,27 @@ class Realm(models.Model): PRIVATE_MESSAGE_POLICY_DISABLED, ] + # Global policy for who is allowed to use wildcard mentions in + # streams with a large number of subscribers. Anyone can use + # wildcard mentions in small streams regardless of this setting. + WILDCARD_MENTION_POLICY_EVERYONE = 1 + WILDCARD_MENTION_POLICY_MEMBERS = 2 + WILDCARD_MENTION_POLICY_FULL_MEMBERS = 3 + WILDCARD_MENTION_POLICY_STREAM_ADMINS = 4 + WILDCARD_MENTION_POLICY_ADMINS = 5 + WILDCARD_MENTION_POLICY_NOBODY = 6 + wildcard_mention_policy: int = models.PositiveSmallIntegerField( + default=WILDCARD_MENTION_POLICY_STREAM_ADMINS, + ) + WILDCARD_MENTION_POLICY_TYPES = [ + WILDCARD_MENTION_POLICY_EVERYONE, + WILDCARD_MENTION_POLICY_MEMBERS, + WILDCARD_MENTION_POLICY_FULL_MEMBERS, + WILDCARD_MENTION_POLICY_STREAM_ADMINS, + WILDCARD_MENTION_POLICY_ADMINS, + WILDCARD_MENTION_POLICY_NOBODY, + ] + # Who in the organization has access to users' actual email # addresses. Controls whether the UserProfile.email field is the # same as UserProfile.delivery_email, or is instead garbage. @@ -419,6 +440,7 @@ class Realm(models.Model): user_group_edit_policy=int, default_code_block_language=(str, type(None)), message_content_delete_limit_seconds=int, + wildcard_mention_policy=int, ) DIGEST_WEEKDAY_VALUES = [0, 1, 2, 3, 4, 5, 6] diff --git a/zerver/openapi/zulip.yaml b/zerver/openapi/zulip.yaml index f734a116fa..fe17b7bfe1 100644 --- a/zerver/openapi/zulip.yaml +++ b/zerver/openapi/zulip.yaml @@ -6792,6 +6792,24 @@ paths: The policy for which users can add other users to streams in this organization. + realm_wildcard_mention_policy: + type: integer + description: | + Present if `realm` is present in `fetch_event_types`. + + The policy for who can use wildcard mentions in large streams. + + * 1 => Any user can use wildcard mentions in large streams. + * 2 => Only members can use wildcard mentions in large streams. + * 3 => Only full members can use wildcard mentions in large streams. + * 4 => Only stream and organization administrators can use wildcard mentions in large streams. + * 5 => Only organization administrators can use wildcard mentions in large streams. + * 6 => Nobody can use wildcard mentions in large streams. + + All users will receive a warning/reminder when using + mentions in large streams, even when permitted to do so. + + **Changes**: New in Zulip 4.0 (feature level 33). realm_default_language: type: string description: | diff --git a/zerver/tests/test_events.py b/zerver/tests/test_events.py index dddef954cc..c84e6a6951 100644 --- a/zerver/tests/test_events.py +++ b/zerver/tests/test_events.py @@ -1729,6 +1729,7 @@ class RealmPropertyActionTest(BaseAction): invite_to_stream_policy=[3, 2, 1], private_message_policy=[2, 1], user_group_edit_policy=[1, 2], + wildcard_mention_policy=[3, 2, 1], email_address_visibility=[Realm.EMAIL_ADDRESS_VISIBILITY_ADMINS], bot_creation_policy=[Realm.BOT_CREATION_EVERYONE], video_chat_provider=[ diff --git a/zerver/tests/test_home.py b/zerver/tests/test_home.py index b876a50b16..9dfbc0d088 100644 --- a/zerver/tests/test_home.py +++ b/zerver/tests/test_home.py @@ -196,6 +196,7 @@ class HomeTest(ZulipTestCase): "realm_users", "realm_video_chat_provider", "realm_waiting_period_threshold", + "realm_wildcard_mention_policy", "recent_private_conversations", "root_domain_uri", "save_stacktraces", diff --git a/zerver/tests/test_realm.py b/zerver/tests/test_realm.py index 5c6bd24cf1..de00aa1d93 100644 --- a/zerver/tests/test_realm.py +++ b/zerver/tests/test_realm.py @@ -502,6 +502,18 @@ class RealmTest(ZulipTestCase): result = self.client_patch('/json/realm', req) self.assert_json_error(result, 'Invalid private_message_policy') + def test_change_wildcard_mention_policy(self) -> None: + # We need an admin user. + self.login('iago') + req = dict(wildcard_mention_policy = orjson.dumps(Realm.WILDCARD_MENTION_POLICY_EVERYONE).decode()) + result = self.client_patch('/json/realm', req) + self.assert_json_success(result) + + invalid_value = 10 + req = dict(wildcard_mention_policy = orjson.dumps(invalid_value).decode()) + result = self.client_patch('/json/realm', req) + self.assert_json_error(result, 'Invalid wildcard_mention_policy') + def test_invalid_integer_attribute_values(self) -> None: integer_values = [key for key, value in Realm.property_types.items() if value is int] @@ -518,6 +530,7 @@ class RealmTest(ZulipTestCase): user_group_edit_policy=10, private_message_policy=10, message_content_delete_limit_seconds=-10, + wildcard_mention_policy=10, ) # We need an admin user. @@ -719,6 +732,9 @@ class RealmAPITest(ZulipTestCase): invite_to_stream_policy=[Realm.POLICY_ADMINS_ONLY, Realm.POLICY_MEMBERS_ONLY, Realm.POLICY_FULL_MEMBERS_ONLY], + wildcard_mention_policy=[Realm.WILDCARD_MENTION_POLICY_EVERYONE, + Realm.WILDCARD_MENTION_POLICY_FULL_MEMBERS, + Realm.WILDCARD_MENTION_POLICY_ADMINS], bot_creation_policy=[1, 2], email_address_visibility=[Realm.EMAIL_ADDRESS_VISIBILITY_EVERYONE, Realm.EMAIL_ADDRESS_VISIBILITY_ADMINS, diff --git a/zerver/views/realm.py b/zerver/views/realm.py index 17dfcbc658..bd5340e7aa 100644 --- a/zerver/views/realm.py +++ b/zerver/views/realm.py @@ -80,6 +80,8 @@ def update_realm( Realm.USER_GROUP_EDIT_POLICY_TYPES), default=None), private_message_policy: Optional[int]=REQ(validator=check_int_in( Realm.PRIVATE_MESSAGE_POLICY_TYPES), default=None), + wildcard_mention_policy: Optional[int]=REQ(validator=check_int_in( + Realm.WILDCARD_MENTION_POLICY_TYPES), default=None), email_address_visibility: Optional[int]=REQ(validator=check_int_in( Realm.EMAIL_ADDRESS_VISIBILITY_TYPES), default=None), default_twenty_four_hour_time: Optional[bool]=REQ(validator=check_bool, default=None),