mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 14:03:30 +00:00
actions: Modify check_message for handling wildcard_mention_policy setting.
This commit adds enforcement for sending messages containing wildcard mentions according to wildcard_mention_policy.
This commit is contained in:
@@ -105,6 +105,12 @@
|
||||
{{> dropdown_options_widget option_values=invite_to_stream_policy_values}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label for="realm_wildcard_mention_policy" class="dropdown-title">{{t "Who can use @all/@everyone mentions in large streams" }}</label>
|
||||
<select name="realm_wildcard_mention_policy" id="id_realm_wildcard_mention_policy" class="prop-element" data-setting-widget-type="number">
|
||||
{{> dropdown_options_widget option_values=wildcard_mention_policy_values}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@ from zerver.lib.message import (
|
||||
truncate_body,
|
||||
truncate_topic,
|
||||
update_first_visible_message_id,
|
||||
wildcard_mention_allowed,
|
||||
)
|
||||
from zerver.lib.pysa import mark_sanitized
|
||||
from zerver.lib.queue import queue_json_publish
|
||||
@@ -2416,7 +2417,12 @@ def check_message(sender: UserProfile, client: Client, addressee: Addressee,
|
||||
message_dict = {'message': message, 'stream': stream, 'local_id': local_id,
|
||||
'sender_queue_id': sender_queue_id, 'realm': realm,
|
||||
'widget_content': widget_content}
|
||||
return build_message_send_dict(message_dict, email_gateway)
|
||||
message_send_dict = build_message_send_dict(message_dict, email_gateway)
|
||||
|
||||
if stream is not None and message_send_dict['message'].mentions_wildcard:
|
||||
if not wildcard_mention_allowed(sender, stream):
|
||||
raise JsonableError(_("You do not have permission to use wildcard mentions in this stream."))
|
||||
return message_send_dict
|
||||
|
||||
def _internal_prep_message(realm: Realm,
|
||||
sender: UserProfile,
|
||||
|
||||
@@ -28,7 +28,10 @@ from zerver.lib.display_recipient import (
|
||||
from zerver.lib.markdown import MentionData, markdown_convert, topic_links
|
||||
from zerver.lib.markdown import version as markdown_version
|
||||
from zerver.lib.request import JsonableError
|
||||
from zerver.lib.stream_subscription import get_stream_subscriptions_for_user
|
||||
from zerver.lib.stream_subscription import (
|
||||
get_stream_subscriptions_for_user,
|
||||
num_subscribers_for_stream_id,
|
||||
)
|
||||
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_mutes import build_topic_mute_checker, topic_is_muted
|
||||
@@ -1234,3 +1237,34 @@ def get_recent_private_conversations(user_profile: UserProfile) -> Dict[int, Dic
|
||||
rec['user_ids'].sort()
|
||||
|
||||
return recipient_map
|
||||
|
||||
def wildcard_mention_allowed(sender: UserProfile, stream: Stream) -> bool:
|
||||
realm = sender.realm
|
||||
|
||||
# If there are fewer than Realm.WILDCARD_MENTION_THRESHOLD, we
|
||||
# allow sending. In the future, we may want to make this behavior
|
||||
# a default, and also just allow explicitly setting whether this
|
||||
# applies to a stream as an override.
|
||||
if num_subscribers_for_stream_id(stream.id) <= Realm.WILDCARD_MENTION_THRESHOLD:
|
||||
return True
|
||||
|
||||
if realm.wildcard_mention_policy == Realm.WILDCARD_MENTION_POLICY_NOBODY:
|
||||
return False
|
||||
|
||||
if realm.wildcard_mention_policy == Realm.WILDCARD_MENTION_POLICY_EVERYONE:
|
||||
return True
|
||||
|
||||
if realm.wildcard_mention_policy == Realm.WILDCARD_MENTION_POLICY_ADMINS:
|
||||
return sender.is_realm_admin
|
||||
|
||||
if realm.wildcard_mention_policy == Realm.WILDCARD_MENTION_POLICY_STREAM_ADMINS:
|
||||
# TODO: Change this when we implement stream administrators
|
||||
return sender.is_realm_admin
|
||||
|
||||
if realm.wildcard_mention_policy == Realm.WILDCARD_MENTION_POLICY_FULL_MEMBERS:
|
||||
return sender.is_realm_admin or (not sender.is_new_member and not sender.is_guest)
|
||||
|
||||
if realm.wildcard_mention_policy == Realm.WILDCARD_MENTION_POLICY_MEMBERS:
|
||||
return not sender.is_guest
|
||||
|
||||
raise AssertionError("Invalid wildcard mention policy")
|
||||
|
||||
@@ -178,6 +178,7 @@ class Realm(models.Model):
|
||||
AUTHENTICATION_FLAGS = ['Google', 'Email', 'GitHub', 'LDAP', 'Dev',
|
||||
'RemoteUser', 'AzureAD', 'SAML', 'GitLab', 'Apple']
|
||||
SUBDOMAIN_FOR_ROOT_DOMAIN = ''
|
||||
WILDCARD_MENTION_THRESHOLD = 15
|
||||
|
||||
id: int = models.AutoField(auto_created=True, primary_key=True, verbose_name='ID')
|
||||
|
||||
|
||||
@@ -1325,6 +1325,108 @@ class StreamMessagesTest(ZulipTestCase):
|
||||
self.assertEqual(user_message.message.content, content)
|
||||
self.assertTrue(user_message.flags.mentioned)
|
||||
|
||||
def send_and_verify_wildcard_mention_message(self,
|
||||
sender_name: str,
|
||||
test_fails: bool=False,
|
||||
sub_count: int=16) -> None:
|
||||
sender = self.example_user(sender_name)
|
||||
content = "@**all** test wildcard mention"
|
||||
with mock.patch(
|
||||
"zerver.lib.message.num_subscribers_for_stream_id", return_value=sub_count
|
||||
):
|
||||
if not test_fails:
|
||||
msg_id = self.send_stream_message(sender, "test_stream", content)
|
||||
result = self.api_get(sender, '/json/messages/' + str(msg_id))
|
||||
self.assert_json_success(result)
|
||||
|
||||
else:
|
||||
with self.assertRaisesRegex(JsonableError,
|
||||
"You do not have permission to use wildcard mentions in this stream."):
|
||||
self.send_stream_message(sender, "test_stream", content)
|
||||
|
||||
def test_wildcard_mention_restrictions(self) -> None:
|
||||
cordelia = self.example_user("cordelia")
|
||||
iago = self.example_user("iago")
|
||||
polonius = self.example_user("polonius")
|
||||
realm = cordelia.realm
|
||||
|
||||
stream_name = "test_stream"
|
||||
self.subscribe(cordelia, stream_name)
|
||||
self.subscribe(iago, stream_name)
|
||||
self.subscribe(polonius, stream_name)
|
||||
|
||||
do_set_realm_property(
|
||||
realm, "wildcard_mention_policy", Realm.WILDCARD_MENTION_POLICY_EVERYONE
|
||||
)
|
||||
self.send_and_verify_wildcard_mention_message("polonius")
|
||||
|
||||
do_set_realm_property(
|
||||
realm, "wildcard_mention_policy", Realm.WILDCARD_MENTION_POLICY_MEMBERS
|
||||
)
|
||||
self.send_and_verify_wildcard_mention_message("polonius", test_fails=True)
|
||||
# There is no restriction on small streams.
|
||||
self.send_and_verify_wildcard_mention_message("polonius", sub_count=10)
|
||||
self.send_and_verify_wildcard_mention_message("cordelia")
|
||||
|
||||
do_set_realm_property(
|
||||
realm,
|
||||
"wildcard_mention_policy",
|
||||
Realm.WILDCARD_MENTION_POLICY_FULL_MEMBERS
|
||||
)
|
||||
do_set_realm_property(realm, "waiting_period_threshold", 10)
|
||||
iago.date_joined = timezone_now()
|
||||
iago.save()
|
||||
cordelia.date_joined = timezone_now()
|
||||
cordelia.save()
|
||||
self.send_and_verify_wildcard_mention_message("cordelia", test_fails=True)
|
||||
self.send_and_verify_wildcard_mention_message("cordelia", sub_count=10)
|
||||
# Administrators can use wildcard mentions even if they are new.
|
||||
self.send_and_verify_wildcard_mention_message("iago")
|
||||
|
||||
cordelia.date_joined = timezone_now() - datetime.timedelta(days=11)
|
||||
cordelia.save()
|
||||
self.send_and_verify_wildcard_mention_message("cordelia")
|
||||
|
||||
do_set_realm_property(
|
||||
realm,
|
||||
"wildcard_mention_policy",
|
||||
Realm.WILDCARD_MENTION_POLICY_STREAM_ADMINS
|
||||
)
|
||||
# TODO: Change this when we implement stream administrators
|
||||
self.send_and_verify_wildcard_mention_message("cordelia", test_fails=True)
|
||||
# There is no restriction on small streams.
|
||||
self.send_and_verify_wildcard_mention_message("cordelia", sub_count=10)
|
||||
self.send_and_verify_wildcard_mention_message("iago")
|
||||
|
||||
cordelia.date_joined = timezone_now()
|
||||
cordelia.save()
|
||||
do_set_realm_property(
|
||||
realm, "wildcard_mention_policy", Realm.WILDCARD_MENTION_POLICY_ADMINS
|
||||
)
|
||||
self.send_and_verify_wildcard_mention_message("cordelia", test_fails=True)
|
||||
# There is no restriction on small streams.
|
||||
self.send_and_verify_wildcard_mention_message("cordelia", sub_count=10)
|
||||
self.send_and_verify_wildcard_mention_message("iago")
|
||||
|
||||
do_set_realm_property(
|
||||
realm, "wildcard_mention_policy", Realm.WILDCARD_MENTION_POLICY_NOBODY
|
||||
)
|
||||
self.send_and_verify_wildcard_mention_message("iago", test_fails=True)
|
||||
self.send_and_verify_wildcard_mention_message("iago", sub_count=10)
|
||||
|
||||
def test_invalid_wildcard_mention_policy(self) -> None:
|
||||
cordelia = self.example_user("cordelia")
|
||||
self.login_user(cordelia)
|
||||
|
||||
self.subscribe(cordelia, "test_stream")
|
||||
do_set_realm_property(cordelia.realm, "wildcard_mention_policy", 10)
|
||||
content = "@**all** test wildcard mention"
|
||||
with mock.patch(
|
||||
"zerver.lib.message.num_subscribers_for_stream_id", return_value=16
|
||||
):
|
||||
with self.assertRaisesRegex(AssertionError, "Invalid wildcard mention policy"):
|
||||
self.send_stream_message(cordelia, "test_stream", content)
|
||||
|
||||
def test_stream_message_mirroring(self) -> None:
|
||||
user = self.mit_user('starnine')
|
||||
self.subscribe(user, 'Verona')
|
||||
|
||||
Reference in New Issue
Block a user