streams: Send stream creation event when changing stream to public.

This commit adds code to send stream creation and peer add events
when stream is changed from private to public. These events are
only sent to users who are not susbcribed to the stream and are
not realm admins as subscribers and realm admins already have
the stream data. This will update the stream data with clients
and will remove the need to reload to view the modified stream.

Fixes #22194.
This commit is contained in:
Sahil Batra 2022-06-07 19:52:28 +05:30 committed by Tim Abbott
parent 319ff6eba2
commit f4fcedd072
2 changed files with 75 additions and 1 deletions

View File

@ -944,6 +944,43 @@ def do_change_stream_permission(
).decode(),
)
notify_stream_creation_ids = set()
if old_invite_only_value and not stream.invite_only:
# We need to send stream creation event to users who can access the
# stream now but were not able to do so previously. So, we can exclude
# subscribers, users who were previously subscribed to the stream and
# realm admins from the non-guest user list.
previously_subscribed_user_ids = Subscription.objects.filter(
recipient_id=stream.recipient_id, active=False, is_user_active=True
).values_list("user_profile_id", flat=True)
stream_subscriber_user_ids = get_active_subscriptions_for_stream_id(
stream.id, include_deactivated_users=False
).values_list("user_profile_id", flat=True)
old_can_access_stream_user_ids = (
set(stream_subscriber_user_ids)
| set(previously_subscribed_user_ids)
| {user.id for user in stream.realm.get_admin_users_and_bots()}
)
non_guest_user_ids = set(active_non_guest_user_ids(stream.realm_id))
notify_stream_creation_ids = non_guest_user_ids - old_can_access_stream_user_ids
send_stream_creation_event(stream, list(notify_stream_creation_ids))
# Add subscribers info to the stream object. We need to send peer_add
# events to users who were previously subscribed to the streams as
# they did not had subscribers data.
old_subscribers_access_user_ids = set(stream_subscriber_user_ids) | {
user.id for user in stream.realm.get_admin_users_and_bots()
}
peer_notify_user_ids = non_guest_user_ids - old_subscribers_access_user_ids
peer_add_event = dict(
type="subscription",
op="peer_add",
stream_ids=[stream.id],
user_ids=sorted(stream_subscriber_user_ids),
)
send_event(stream.realm, peer_add_event, peer_notify_user_ids)
event = dict(
op="update",
type="stream",
@ -954,7 +991,10 @@ def do_change_stream_permission(
stream_id=stream.id,
name=stream.name,
)
send_event(stream.realm, event, can_access_stream_user_ids(stream))
# we do not need to send update events to the users who received creation event
# since they already have the updated stream info.
notify_stream_update_ids = can_access_stream_user_ids(stream) - notify_stream_creation_ids
send_event(stream.realm, event, notify_stream_update_ids)
old_policy_name = get_stream_permission_policy_name(
invite_only=old_invite_only_value,

View File

@ -2744,6 +2744,40 @@ class SubscribeActionTest(BaseAction):
check_stream_update("events[0]", events[0])
check_message("events[1]", events[1])
# Update stream privacy - make stream public
self.user_profile = self.example_user("cordelia")
action = lambda: do_change_stream_permission(
stream,
invite_only=False,
history_public_to_subscribers=True,
is_web_public=False,
acting_user=self.example_user("hamlet"),
)
events = self.verify_action(action, include_subscribers=include_subscribers, num_events=2)
check_stream_create("events[0]", events[0])
check_subscription_peer_add("events[1]", events[1])
do_change_stream_permission(
stream,
invite_only=True,
history_public_to_subscribers=True,
is_web_public=False,
acting_user=self.example_user("hamlet"),
)
self.subscribe(self.example_user("cordelia"), stream.name)
self.unsubscribe(self.example_user("cordelia"), stream.name)
action = lambda: do_change_stream_permission(
stream,
invite_only=False,
history_public_to_subscribers=True,
is_web_public=False,
acting_user=self.example_user("hamlet"),
)
events = self.verify_action(
action, include_subscribers=include_subscribers, num_events=2, include_streams=False
)
self.user_profile = self.example_user("hamlet")
# Update stream stream_post_policy property
action = lambda: do_change_stream_post_policy(
stream, Stream.STREAM_POST_POLICY_ADMINS, acting_user=self.example_user("hamlet")