diff --git a/zerver/actions/create_realm.py b/zerver/actions/create_realm.py index b362ab23a7..e7c5bb37f8 100644 --- a/zerver/actions/create_realm.py +++ b/zerver/actions/create_realm.py @@ -166,6 +166,10 @@ def do_create_realm( if org_type is not None: kwargs["org_type"] = org_type if enable_spectator_access is not None: + if enable_spectator_access: + # Realms with LIMITED plan cannot have spectators enabled. + assert plan_type != Realm.PLAN_TYPE_LIMITED + assert plan_type is not None or not settings.BILLING_ENABLED kwargs["enable_spectator_access"] = enable_spectator_access if date_created is not None: diff --git a/zerver/actions/realm_settings.py b/zerver/actions/realm_settings.py index 1114f06a83..f035de6ca2 100644 --- a/zerver/actions/realm_settings.py +++ b/zerver/actions/realm_settings.py @@ -416,6 +416,11 @@ def do_change_realm_plan_type( realm: Realm, plan_type: int, *, acting_user: Optional[UserProfile] ) -> None: old_value = realm.plan_type + + if plan_type == Realm.PLAN_TYPE_LIMITED: + # We do not allow public access on limited plans. + do_set_realm_property(realm, "enable_spectator_access", False, acting_user=acting_user) + realm.plan_type = plan_type realm.save(update_fields=["plan_type"]) RealmAuditLog.objects.create( @@ -451,7 +456,14 @@ def do_change_realm_plan_type( update_first_visible_message_id(realm) - realm.save(update_fields=["_max_invites", "message_visibility_limit", "upload_quota_gb"]) + realm.save( + update_fields=[ + "_max_invites", + "enable_spectator_access", + "message_visibility_limit", + "upload_quota_gb", + ] + ) event = { "type": "realm", diff --git a/zerver/tests/test_events.py b/zerver/tests/test_events.py index 9ae0cfcdf4..8817d1e227 100644 --- a/zerver/tests/test_events.py +++ b/zerver/tests/test_events.py @@ -1766,9 +1766,11 @@ class NormalActionsTest(BaseAction): events = self.verify_action( lambda: do_change_realm_plan_type( realm, Realm.PLAN_TYPE_LIMITED, acting_user=self.user_profile - ) + ), + num_events=2, ) - check_realm_update("events[0]", events[0], "plan_type") + check_realm_update("events[0]", events[0], "enable_spectator_access") + check_realm_update("events[1]", events[1], "plan_type") state_data = fetch_initial_state_data(self.user_profile) self.assertEqual(state_data["realm_plan_type"], Realm.PLAN_TYPE_LIMITED) diff --git a/zerver/tests/test_message_edit.py b/zerver/tests/test_message_edit.py index 259aa5fbdc..f625cce72d 100644 --- a/zerver/tests/test_message_edit.py +++ b/zerver/tests/test_message_edit.py @@ -427,6 +427,12 @@ class EditMessageTest(EditMessageTestCase): result, "Not logged in: API authentication or user session required", 401 ) + do_set_realm_property(user_profile.realm, "enable_spectator_access", True, acting_user=None) + result = self.client_get("/json/messages/" + str(web_public_stream_msg_id)) + self.assert_json_error( + result, "Not logged in: API authentication or user session required", 401 + ) + # Verify works with STANDARD_FREE plan type too. do_change_realm_plan_type( user_profile.realm, Realm.PLAN_TYPE_STANDARD_FREE, acting_user=None diff --git a/zerver/tests/test_realm.py b/zerver/tests/test_realm.py index c1b1a4981d..4fa2990a54 100644 --- a/zerver/tests/test_realm.py +++ b/zerver/tests/test_realm.py @@ -97,12 +97,28 @@ class RealmTest(ZulipTestCase): self.assertEqual(realm.invite_to_stream_policy, Realm.POLICY_MODERATORS_ONLY) def test_realm_enable_spectator_access(self) -> None: - realm = do_create_realm("test_web_public_true", "Foo", enable_spectator_access=True) + realm = do_create_realm( + "test_web_public_true", + "Foo", + plan_type=Realm.PLAN_TYPE_STANDARD, + enable_spectator_access=True, + ) self.assertEqual(realm.enable_spectator_access, True) realm = do_create_realm("test_web_public_false", "Boo", enable_spectator_access=False) self.assertEqual(realm.enable_spectator_access, False) + with self.assertRaises(AssertionError): + realm = do_create_realm("test_web_public_false_1", "Foo", enable_spectator_access=True) + + with self.assertRaises(AssertionError): + realm = do_create_realm( + "test_web_public_false_2", + "Foo", + plan_type=Realm.PLAN_TYPE_LIMITED, + enable_spectator_access=True, + ) + def test_do_set_realm_name_caching(self) -> None: """The main complicated thing about setting realm names is fighting the cache, and we start by populating the cache for Hamlet, and we end @@ -733,12 +749,14 @@ class RealmTest(ZulipTestCase): self.assertEqual(realm.message_visibility_limit, None) self.assertEqual(realm.upload_quota_gb, Realm.UPLOAD_QUOTA_STANDARD) + do_set_realm_property(realm, "enable_spectator_access", True, acting_user=None) do_change_realm_plan_type(realm, Realm.PLAN_TYPE_LIMITED, acting_user=iago) realm = get_realm("zulip") self.assertEqual(realm.plan_type, Realm.PLAN_TYPE_LIMITED) self.assertEqual(realm.max_invites, settings.INVITES_DEFAULT_REALM_DAILY_MAX) self.assertEqual(realm.message_visibility_limit, Realm.MESSAGE_VISIBILITY_LIMITED) self.assertEqual(realm.upload_quota_gb, Realm.UPLOAD_QUOTA_LIMITED) + self.assertFalse(realm.enable_spectator_access) do_change_realm_plan_type(realm, Realm.PLAN_TYPE_STANDARD_FREE, acting_user=iago) realm = get_realm("zulip")