mirror of https://github.com/zulip/zulip.git
update_stream_backend: Add ability to make streams web public.
We allow clients to make existing streams web public via the API. This feature is still disabled via settings in production environments, because we may have additional policy rules or UI warnings we wish to add to this sort of conversion.
This commit is contained in:
parent
6a78112940
commit
5138652810
|
@ -15,6 +15,8 @@ below features are supported.
|
|||
|
||||
* [`POST /subscribe`](/api/subscribe): Added `is_web_public` parameter
|
||||
for requesting the creation of a web-public stream.
|
||||
* [`PATCH /streams/{stream_id}`](/api/update-stream): Added
|
||||
`is_web_public` parameter for converting a stream into a web-public stream.
|
||||
|
||||
**Feature level 97**
|
||||
|
||||
|
|
|
@ -4823,6 +4823,20 @@ def do_make_stream_web_public(stream: Stream) -> None:
|
|||
stream.save(update_fields=["invite_only", "history_public_to_subscribers", "is_web_public"])
|
||||
|
||||
|
||||
def do_change_stream_permission(
|
||||
stream: Stream,
|
||||
invite_only: Optional[bool] = None,
|
||||
history_public_to_subscribers: Optional[bool] = None,
|
||||
is_web_public: Optional[bool] = None,
|
||||
) -> None:
|
||||
# TODO: Ideally this would be just merged with do_change_stream_invite_only.
|
||||
if is_web_public:
|
||||
do_make_stream_web_public(stream)
|
||||
else:
|
||||
assert invite_only is not None
|
||||
do_change_stream_invite_only(stream, invite_only, history_public_to_subscribers)
|
||||
|
||||
|
||||
def do_change_stream_post_policy(stream: Stream, stream_post_policy: int) -> None:
|
||||
stream.stream_post_policy = stream_post_policy
|
||||
stream.save(update_fields=["stream_post_policy"])
|
||||
|
|
|
@ -12638,6 +12638,22 @@ paths:
|
|||
type: boolean
|
||||
example: true
|
||||
required: false
|
||||
- name: is_web_public
|
||||
in: query
|
||||
description: |
|
||||
Change whether the stream is a web-public stream.
|
||||
|
||||
Note that creating web public streams requires the
|
||||
`WEB_PUBLIC_STREAMS_ENABLED` [server setting][server-settings]
|
||||
to be enabled on the Zulip server in question.
|
||||
|
||||
[server-settings]: https://zulip.readthedocs.io/en/stable/production/settings.html
|
||||
|
||||
**Changes**: New in Zulip 5.0 (feature level 98).
|
||||
schema:
|
||||
type: boolean
|
||||
example: true
|
||||
required: false
|
||||
- $ref: "#/components/parameters/StreamPostPolicy"
|
||||
- $ref: "#/components/parameters/HistoryPublicToSubscribers"
|
||||
- $ref: "#/components/parameters/MessageRetentionDays"
|
||||
|
|
|
@ -544,6 +544,59 @@ class StreamAdminTest(ZulipTestCase):
|
|||
self.assertTrue(stream.invite_only)
|
||||
self.assertTrue(stream.history_public_to_subscribers)
|
||||
|
||||
def test_make_stream_web_public(self) -> None:
|
||||
user_profile = self.example_user("hamlet")
|
||||
self.login_user(user_profile)
|
||||
realm = user_profile.realm
|
||||
self.make_stream("test_stream", realm=realm)
|
||||
stream_id = get_stream("test_stream", realm).id
|
||||
|
||||
params = {
|
||||
"stream_name": orjson.dumps("test_stream").decode(),
|
||||
"is_web_public": orjson.dumps(True).decode(),
|
||||
"history_public_to_subscribers": orjson.dumps(True).decode(),
|
||||
}
|
||||
result = self.client_patch(f"/json/streams/{stream_id}", params)
|
||||
self.assert_json_error(result, "Must be an organization or stream administrator")
|
||||
|
||||
do_change_user_role(user_profile, UserProfile.ROLE_REALM_ADMINISTRATOR, acting_user=None)
|
||||
result = self.client_patch(f"/json/streams/{stream_id}", params)
|
||||
self.assert_json_error(result, "Must be an organization owner")
|
||||
|
||||
do_change_user_role(user_profile, UserProfile.ROLE_REALM_OWNER, acting_user=None)
|
||||
with self.settings(WEB_PUBLIC_STREAMS_ENABLED=False):
|
||||
result = self.client_patch(f"/json/streams/{stream_id}", params)
|
||||
self.assert_json_error(result, "Web public streams are not enabled.")
|
||||
|
||||
bad_params = {
|
||||
"stream_name": orjson.dumps("test_stream").decode(),
|
||||
"is_web_public": orjson.dumps(True).decode(),
|
||||
"is_private": orjson.dumps(True).decode(),
|
||||
"history_public_to_subscribers": orjson.dumps(True).decode(),
|
||||
}
|
||||
result = self.client_patch(f"/json/streams/{stream_id}", bad_params)
|
||||
self.assert_json_error(result, "Invalid parameters")
|
||||
|
||||
bad_params = {
|
||||
"stream_name": orjson.dumps("test_stream").decode(),
|
||||
"is_web_public": orjson.dumps(True).decode(),
|
||||
"is_private": orjson.dumps(False).decode(),
|
||||
"history_public_to_subscribers": orjson.dumps(False).decode(),
|
||||
}
|
||||
result = self.client_patch(f"/json/streams/{stream_id}", bad_params)
|
||||
self.assert_json_error(result, "Invalid parameters")
|
||||
|
||||
stream = get_stream("test_stream", realm)
|
||||
self.assertFalse(stream.is_web_public)
|
||||
|
||||
result = self.client_patch(f"/json/streams/{stream_id}", params)
|
||||
self.assert_json_success(result)
|
||||
|
||||
stream = get_stream("test_stream", realm)
|
||||
self.assertTrue(stream.is_web_public)
|
||||
self.assertFalse(stream.invite_only)
|
||||
self.assertTrue(stream.history_public_to_subscribers)
|
||||
|
||||
def test_try_make_stream_public_with_private_history(self) -> None:
|
||||
user_profile = self.example_user("hamlet")
|
||||
self.login_user(user_profile)
|
||||
|
|
|
@ -25,8 +25,8 @@ from zerver.lib.actions import (
|
|||
do_change_default_stream_group_description,
|
||||
do_change_default_stream_group_name,
|
||||
do_change_stream_description,
|
||||
do_change_stream_invite_only,
|
||||
do_change_stream_message_retention_days,
|
||||
do_change_stream_permission,
|
||||
do_change_stream_post_policy,
|
||||
do_change_subscription_property,
|
||||
do_create_default_stream_group,
|
||||
|
@ -258,6 +258,7 @@ def update_stream_backend(
|
|||
json_validator=check_int_in(Stream.STREAM_POST_POLICY_TYPES), default=None
|
||||
),
|
||||
history_public_to_subscribers: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
is_web_public: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
new_name: Optional[str] = REQ(default=None),
|
||||
message_retention_days: Optional[Union[int, str]] = REQ(
|
||||
json_validator=check_string_or_int, default=None
|
||||
|
@ -308,7 +309,21 @@ def update_stream_backend(
|
|||
(stream, sub) = access_stream_by_id(user_profile, stream_id)
|
||||
if is_private and stream.id in default_stream_ids:
|
||||
raise JsonableError(_("Default streams cannot be made private."))
|
||||
do_change_stream_invite_only(stream, is_private, history_public_to_subscribers)
|
||||
|
||||
if is_web_public:
|
||||
# Enforce restrictions on creating web-public streams.
|
||||
if not user_profile.realm.web_public_streams_enabled():
|
||||
raise JsonableError(_("Web public streams are not enabled."))
|
||||
if not user_profile.is_realm_owner:
|
||||
raise OrganizationOwnerRequired()
|
||||
# Forbid parameter combinations that are inconsistent
|
||||
if is_private or history_public_to_subscribers is False:
|
||||
raise JsonableError(_("Invalid parameters"))
|
||||
|
||||
if is_private is not None or is_web_public is not None:
|
||||
do_change_stream_permission(
|
||||
stream, is_private, history_public_to_subscribers, is_web_public
|
||||
)
|
||||
return json_success()
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue