diff --git a/zerver/decorator.py b/zerver/decorator.py index 3097d93bb0..1d6bb47e58 100644 --- a/zerver/decorator.py +++ b/zerver/decorator.py @@ -158,6 +158,24 @@ def require_realm_admin( return wrapper +def check_if_user_can_manage_default_streams( + func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse], +) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]: + @wraps(func) + def wrapper( + request: HttpRequest, + user_profile: UserProfile, + /, + *args: ParamT.args, + **kwargs: ParamT.kwargs, + ) -> HttpResponse: + if not user_profile.can_manage_default_streams(): + raise OrganizationAdministratorRequiredError + return func(request, user_profile, *args, **kwargs) + + return wrapper + + def require_organization_member( func: Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse], ) -> Callable[Concatenate[HttpRequest, UserProfile, ParamT], HttpResponse]: diff --git a/zerver/tests/test_subs.py b/zerver/tests/test_subs.py index 7c4c77f88f..5abae1110b 100644 --- a/zerver/tests/test_subs.py +++ b/zerver/tests/test_subs.py @@ -3491,7 +3491,6 @@ class DefaultStreamTest(ZulipTestCase): def test_api_calls(self) -> None: user_profile = self.example_user("hamlet") - do_change_user_role(user_profile, UserProfile.ROLE_REALM_ADMINISTRATOR, acting_user=None) self.login_user(user_profile) DefaultStream.objects.filter(realm=user_profile.realm).delete() @@ -3499,6 +3498,11 @@ class DefaultStreamTest(ZulipTestCase): stream_name = "stream ADDED via api" stream = ensure_stream(user_profile.realm, stream_name, acting_user=None) result = self.client_post("/json/default_streams", dict(stream_id=stream.id)) + self.assert_json_error(result, "Must be an organization administrator") + self.assertFalse(stream_name in self.get_default_stream_names(user_profile.realm)) + + do_change_user_role(user_profile, UserProfile.ROLE_REALM_ADMINISTRATOR, acting_user=None) + result = self.client_post("/json/default_streams", dict(stream_id=stream.id)) self.assert_json_success(result) self.assertTrue(stream_name in self.get_default_stream_names(user_profile.realm)) diff --git a/zerver/views/streams.py b/zerver/views/streams.py index 9ad7cb15bd..fb71402a98 100644 --- a/zerver/views/streams.py +++ b/zerver/views/streams.py @@ -42,7 +42,11 @@ from zerver.actions.streams import ( get_subscriber_ids, ) from zerver.context_processors import get_valid_realm_from_request -from zerver.decorator import require_non_guest_user, require_realm_admin +from zerver.decorator import ( + check_if_user_can_manage_default_streams, + require_non_guest_user, + require_realm_admin, +) from zerver.lib.default_streams import get_default_stream_ids_for_realm from zerver.lib.email_mirror_helpers import encode_email_address from zerver.lib.exceptions import ( @@ -141,7 +145,7 @@ def deactivate_stream_backend( return json_success(request) -@require_realm_admin +@check_if_user_can_manage_default_streams @typed_endpoint def add_default_stream( request: HttpRequest, user_profile: UserProfile, *, stream_id: Json[int] @@ -153,7 +157,7 @@ def add_default_stream( return json_success(request) -@require_realm_admin +@check_if_user_can_manage_default_streams @typed_endpoint def create_default_stream_group( request: HttpRequest, @@ -171,7 +175,7 @@ def create_default_stream_group( return json_success(request) -@require_realm_admin +@check_if_user_can_manage_default_streams @typed_endpoint def update_default_stream_group_info( request: HttpRequest, @@ -192,7 +196,7 @@ def update_default_stream_group_info( return json_success(request) -@require_realm_admin +@check_if_user_can_manage_default_streams @typed_endpoint def update_default_stream_group_streams( request: HttpRequest, @@ -217,7 +221,7 @@ def update_default_stream_group_streams( return json_success(request) -@require_realm_admin +@check_if_user_can_manage_default_streams @typed_endpoint def remove_default_stream_group( request: HttpRequest, user_profile: UserProfile, *, group_id: PathOnly[int] @@ -227,7 +231,7 @@ def remove_default_stream_group( return json_success(request) -@require_realm_admin +@check_if_user_can_manage_default_streams @typed_endpoint def remove_default_stream( request: HttpRequest, user_profile: UserProfile, *, stream_id: Json[int]