diff --git a/templates/zerver/api/changelog.md b/templates/zerver/api/changelog.md index 2a003c7bed..76bb546d9e 100644 --- a/templates/zerver/api/changelog.md +++ b/templates/zerver/api/changelog.md @@ -10,6 +10,13 @@ below features are supported. ## Changes in Zulip 4.0 +**Feature level 60** + +* [`PATCH /users/{user_id}`](/api/update-user): Added support for + changing a user's organization-level role to moderator. +* API endpoints that return `role` values can now return `300`, the + encoding of the moderator role. + **Feature level 59** * [`GET /users`](/api/get-users), [`GET /users/{user_id}`](/api/get-user), diff --git a/zerver/models.py b/zerver/models.py index bee3e5fde6..a5c11fd331 100644 --- a/zerver/models.py +++ b/zerver/models.py @@ -1186,6 +1186,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin): ROLE_TYPES = [ ROLE_REALM_OWNER, ROLE_REALM_ADMINISTRATOR, + ROLE_MODERATOR, ROLE_MEMBER, ROLE_GUEST, ] diff --git a/zerver/openapi/zulip.yaml b/zerver/openapi/zulip.yaml index c95b6d6dfc..f9d622029a 100644 --- a/zerver/openapi/zulip.yaml +++ b/zerver/openapi/zulip.yaml @@ -390,6 +390,7 @@ paths: enum: - 100 - 200 + - 300 - 400 - 600 - type: object @@ -6750,6 +6751,7 @@ paths: * Organization owner: 100 * Organization administrator: 200 + * Organization moderator: 300 * Member: 400 * Guest: 600 @@ -6758,7 +6760,8 @@ paths: The owner role cannot be removed from the only organization owner. **Changes**: New in Zulip 3.0 (feature level 8), replacing the previous - pair of `is_admin` and `is_guest` boolean parameters. + pair of `is_admin` and `is_guest` boolean parameters. Organization moderator + role added in Zulip 4.0 (feature level 60). schema: type: integer example: 400 diff --git a/zerver/tests/test_users.py b/zerver/tests/test_users.py index ee50398062..d9f21f46af 100644 --- a/zerver/tests/test_users.py +++ b/zerver/tests/test_users.py @@ -447,17 +447,27 @@ class PermissionTest(ZulipTestCase): user_profile.is_realm_admin and not user_profile.is_guest and not user_profile.is_realm_owner + and not user_profile.is_moderator ) elif role == UserProfile.ROLE_REALM_OWNER: return ( user_profile.is_realm_owner and user_profile.is_realm_admin + and not user_profile.is_moderator + and not user_profile.is_guest + ) + elif role == UserProfile.ROLE_MODERATOR: + return ( + user_profile.is_moderator + and not user_profile.is_realm_owner + and not user_profile.is_realm_admin and not user_profile.is_guest ) if role == UserProfile.ROLE_MEMBER: return ( not user_profile.is_guest + and not user_profile.is_moderator and not user_profile.is_realm_admin and not user_profile.is_realm_owner ) @@ -465,6 +475,7 @@ class PermissionTest(ZulipTestCase): assert role == UserProfile.ROLE_GUEST return ( user_profile.is_guest + and not user_profile.is_moderator and not user_profile.is_realm_admin and not user_profile.is_realm_owner ) @@ -524,6 +535,26 @@ class PermissionTest(ZulipTestCase): do_change_user_role(iago, UserProfile.ROLE_REALM_OWNER, acting_user=None) self.check_user_role_change("iago", UserProfile.ROLE_REALM_ADMINISTRATOR) + def test_change_owner_to_moderator(self) -> None: + iago = self.example_user("iago") + do_change_user_role(iago, UserProfile.ROLE_REALM_OWNER, acting_user=None) + self.check_user_role_change("iago", UserProfile.ROLE_MODERATOR) + + def test_change_moderator_to_owner(self) -> None: + self.check_user_role_change("shiva", UserProfile.ROLE_REALM_OWNER) + + def test_change_admin_to_moderator(self) -> None: + self.check_user_role_change("iago", UserProfile.ROLE_MODERATOR) + + def test_change_moderator_to_admin(self) -> None: + self.check_user_role_change("shiva", UserProfile.ROLE_REALM_ADMINISTRATOR) + + def test_change_guest_to_moderator(self) -> None: + self.check_user_role_change("polonius", UserProfile.ROLE_MODERATOR) + + def test_change_moderator_to_guest(self) -> None: + self.check_user_role_change("shiva", UserProfile.ROLE_GUEST) + def test_admin_user_can_change_profile_data(self) -> None: realm = get_realm("zulip") self.login("iago")