mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	users: Add is_owner field to user objects returned by get endpoints.
This commit adds 'is_owner' field to the user object returned by
'/users', 'users/{user_id}', and '/users/me' endpoints.
			
			
This commit is contained in:
		@@ -10,6 +10,11 @@ below features are supported.
 | 
			
		||||
 | 
			
		||||
## Changes in Zulip 2.2
 | 
			
		||||
 | 
			
		||||
**Feature level 8**
 | 
			
		||||
* [`GET /users`](/api/get-all-users), [`GET /users/{user_id}`](/api/get-user)
 | 
			
		||||
  and [`GET /users/me`](/api/get-profile): User objects now contain the
 | 
			
		||||
  `is_owner` field as well.
 | 
			
		||||
 | 
			
		||||
**Feature level 7**
 | 
			
		||||
* [`GET /events`](/api/get-events-from-queue): `realm_user` and
 | 
			
		||||
  `realm_bot` events no longer contain an `email` field to identify
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ DESKTOP_WARNING_VERSION = "5.2.0"
 | 
			
		||||
#
 | 
			
		||||
# Changes should be accompanied by documentation explaining what the
 | 
			
		||||
# new level means in templates/zerver/api/changelog.md.
 | 
			
		||||
API_FEATURE_LEVEL = 7
 | 
			
		||||
API_FEATURE_LEVEL = 8
 | 
			
		||||
 | 
			
		||||
# Bump the minor PROVISION_VERSION to indicate that folks should provision
 | 
			
		||||
# only when going from an old version of the code to a newer version. Bump
 | 
			
		||||
 
 | 
			
		||||
@@ -311,6 +311,7 @@ def format_user_row(realm: Realm, acting_user: UserProfile, row: Dict[str, Any],
 | 
			
		||||
                                  client_gravatar=client_gravatar,)
 | 
			
		||||
 | 
			
		||||
    is_admin = is_administrator_role(row['role'])
 | 
			
		||||
    is_owner = row['role'] == UserProfile.ROLE_REALM_OWNER
 | 
			
		||||
    is_guest = row['role'] == UserProfile.ROLE_GUEST
 | 
			
		||||
    is_bot = row['is_bot']
 | 
			
		||||
    # This format should align with get_cross_realm_dicts() and notify_created_user
 | 
			
		||||
@@ -320,6 +321,7 @@ def format_user_row(realm: Realm, acting_user: UserProfile, row: Dict[str, Any],
 | 
			
		||||
        avatar_url=avatar_url,
 | 
			
		||||
        avatar_version=row['avatar_version'],
 | 
			
		||||
        is_admin=is_admin,
 | 
			
		||||
        is_owner=is_owner,
 | 
			
		||||
        is_guest=is_guest,
 | 
			
		||||
        is_bot=is_bot,
 | 
			
		||||
        full_name=row['full_name'],
 | 
			
		||||
 
 | 
			
		||||
@@ -1353,6 +1353,7 @@ paths:
 | 
			
		||||
                             "is_active": true,
 | 
			
		||||
                             "email": "AARON@zulip.com",
 | 
			
		||||
                             "is_admin": false,
 | 
			
		||||
                             "is_owner": false,
 | 
			
		||||
                             "avatar_url": "https://secure.gravatar.com/avatar/818c212b9f8830dfef491b3f7da99a14?d=identicon&version=1",
 | 
			
		||||
                             "bot_type": null,
 | 
			
		||||
                             "timezone": "",
 | 
			
		||||
@@ -1401,6 +1402,7 @@ paths:
 | 
			
		||||
                             "bot_type": null,
 | 
			
		||||
                             "timezone": "",
 | 
			
		||||
                             "is_admin": false,
 | 
			
		||||
                             "is_owner": false,
 | 
			
		||||
                             "avatar_url": "https://secure.gravatar.com/avatar/6d8cad0fd00256e7b40691d27ddfd466?d=identicon&version=1",
 | 
			
		||||
                             "is_active": true,
 | 
			
		||||
                             "email": "hamlet@zulip.com"
 | 
			
		||||
@@ -1414,6 +1416,7 @@ paths:
 | 
			
		||||
                             "is_active": true,
 | 
			
		||||
                             "avatar_url": "https://secure.gravatar.com/avatar/7328586831cdbb1627649bd857b1ee8c?d=identicon&version=1",
 | 
			
		||||
                             "is_admin": false,
 | 
			
		||||
                             "is_owner": false,
 | 
			
		||||
                             "user_id": 23,
 | 
			
		||||
                             "bot_type": 1,
 | 
			
		||||
                             "timezone": "",
 | 
			
		||||
@@ -1550,6 +1553,7 @@ paths:
 | 
			
		||||
                             "bot_type": null,
 | 
			
		||||
                             "timezone": "",
 | 
			
		||||
                             "is_admin": false,
 | 
			
		||||
                             "is_owner": false,
 | 
			
		||||
                             "avatar_url": "https://secure.gravatar.com/avatar/6d8cad0fd00256e7b40691d27ddfd466?d=identicon&version=1",
 | 
			
		||||
                             "is_active": true,
 | 
			
		||||
                             "email": "hamlet@zulip.com"
 | 
			
		||||
@@ -1830,6 +1834,14 @@ paths:
 | 
			
		||||
                      description: |
 | 
			
		||||
                        A boolean indicating if the requesting user is an admin.
 | 
			
		||||
                      example: true
 | 
			
		||||
                    is_owner:
 | 
			
		||||
                      type: boolean
 | 
			
		||||
                      description: |
 | 
			
		||||
                        A boolean indicating if the requesting user is
 | 
			
		||||
                        an organization owner.
 | 
			
		||||
 | 
			
		||||
                        **Changes**: New in Zulip 2.2 (feature level 8).
 | 
			
		||||
                      example: false
 | 
			
		||||
                    is_bot:
 | 
			
		||||
                      type: boolean
 | 
			
		||||
                      description: |
 | 
			
		||||
@@ -1875,6 +1887,7 @@ paths:
 | 
			
		||||
                        "email": "iago@zulip.com",
 | 
			
		||||
                        "full_name": "Iago",
 | 
			
		||||
                        "is_admin": true,
 | 
			
		||||
                        "is_owner": false,
 | 
			
		||||
                        "is_bot": false,
 | 
			
		||||
                        "max_message_id": 30,
 | 
			
		||||
                        "msg": "",
 | 
			
		||||
@@ -3966,6 +3979,13 @@ components:
 | 
			
		||||
          type: boolean
 | 
			
		||||
          description: |
 | 
			
		||||
            A boolean specifying whether the user is an organization administrator.
 | 
			
		||||
        is_owner:
 | 
			
		||||
          type: boolean
 | 
			
		||||
          description: |
 | 
			
		||||
            A boolean specifying whether the user is an organization owner.
 | 
			
		||||
            If true, is_admin will also be true.
 | 
			
		||||
 | 
			
		||||
            **Changes**: New in Zulip 2.2 (feature level 8).
 | 
			
		||||
        bot_type:
 | 
			
		||||
          type: integer
 | 
			
		||||
          nullable: true
 | 
			
		||||
 
 | 
			
		||||
@@ -672,15 +672,15 @@ class ListCustomProfileFieldTest(CustomProfileFieldTestCase):
 | 
			
		||||
 | 
			
		||||
        expected_keys_for_iago = {
 | 
			
		||||
            "delivery_email",
 | 
			
		||||
            "email", "user_id", "avatar_url", "avatar_version", "is_admin", "is_guest", "is_bot",
 | 
			
		||||
            "email", "user_id", "avatar_url", "avatar_version", "is_admin", "is_guest", "is_bot", "is_owner",
 | 
			
		||||
            "full_name", "timezone", "is_active", "date_joined", "profile_data"}
 | 
			
		||||
        self.assertEqual(set(iago_raw_data.keys()), expected_keys_for_iago)
 | 
			
		||||
        self.assertNotEqual(iago_raw_data["profile_data"], {})
 | 
			
		||||
 | 
			
		||||
        expected_keys_for_test_bot = {
 | 
			
		||||
            "delivery_email",
 | 
			
		||||
            "email", "user_id", "avatar_url", "avatar_version", "is_admin", "is_guest", "is_bot", "full_name",
 | 
			
		||||
            "timezone", "is_active", "date_joined", "bot_type", "bot_owner_id"}
 | 
			
		||||
            "email", "user_id", "avatar_url", "avatar_version", "is_admin", "is_guest", "is_bot", "is_owner",
 | 
			
		||||
            "full_name", "timezone", "is_active", "date_joined", "bot_type", "bot_owner_id"}
 | 
			
		||||
        self.assertEqual(set(test_bot_raw_data.keys()), expected_keys_for_test_bot)
 | 
			
		||||
        self.assertEqual(test_bot_raw_data["bot_type"], 1)
 | 
			
		||||
        self.assertEqual(test_bot_raw_data["bot_owner_id"], iago_raw_data["user_id"])
 | 
			
		||||
@@ -697,8 +697,8 @@ class ListCustomProfileFieldTest(CustomProfileFieldTestCase):
 | 
			
		||||
        self.login('iago')
 | 
			
		||||
        expected_keys = {
 | 
			
		||||
            "result", "msg", "pointer", "client_id", "max_message_id", "user_id",
 | 
			
		||||
            "avatar_url", "full_name", "email", "is_bot", "is_admin", "short_name",
 | 
			
		||||
            "profile_data"}
 | 
			
		||||
            "avatar_url", "full_name", "email", "is_bot", "is_admin", "is_owner",
 | 
			
		||||
            "short_name", "profile_data"}
 | 
			
		||||
 | 
			
		||||
        url = "/json/users/me"
 | 
			
		||||
        response = self.client_get(url)
 | 
			
		||||
 
 | 
			
		||||
@@ -1248,6 +1248,7 @@ class EventsRegisterTest(ZulipTestCase):
 | 
			
		||||
                ('avatar_version', check_int),
 | 
			
		||||
                ('full_name', check_string),
 | 
			
		||||
                ('is_admin', check_bool),
 | 
			
		||||
                ('is_owner', check_bool),
 | 
			
		||||
                ('is_bot', check_bool),
 | 
			
		||||
                ('is_guest', check_bool),
 | 
			
		||||
                ('is_active', check_bool),
 | 
			
		||||
@@ -1276,6 +1277,7 @@ class EventsRegisterTest(ZulipTestCase):
 | 
			
		||||
                ('full_name', check_string),
 | 
			
		||||
                ('is_active', check_bool),
 | 
			
		||||
                ('is_admin', check_bool),
 | 
			
		||||
                ('is_owner', check_bool),
 | 
			
		||||
                ('is_bot', check_bool),
 | 
			
		||||
                ('is_guest', check_bool),
 | 
			
		||||
                ('profile_data', check_dict_only([])),
 | 
			
		||||
 
 | 
			
		||||
@@ -614,6 +614,7 @@ class HomeTest(ZulipTestCase):
 | 
			
		||||
                is_active=True,
 | 
			
		||||
                is_bot=True,
 | 
			
		||||
                is_admin=False,
 | 
			
		||||
                is_owner=False,
 | 
			
		||||
                is_cross_realm_bot=True,
 | 
			
		||||
                is_guest=False
 | 
			
		||||
            ),
 | 
			
		||||
@@ -627,6 +628,7 @@ class HomeTest(ZulipTestCase):
 | 
			
		||||
                is_active=True,
 | 
			
		||||
                is_bot=True,
 | 
			
		||||
                is_admin=False,
 | 
			
		||||
                is_owner=False,
 | 
			
		||||
                is_cross_realm_bot=True,
 | 
			
		||||
                is_guest=False
 | 
			
		||||
            ),
 | 
			
		||||
@@ -640,6 +642,7 @@ class HomeTest(ZulipTestCase):
 | 
			
		||||
                is_active=True,
 | 
			
		||||
                is_bot=True,
 | 
			
		||||
                is_admin=False,
 | 
			
		||||
                is_owner=False,
 | 
			
		||||
                is_cross_realm_bot=True,
 | 
			
		||||
                is_guest=False
 | 
			
		||||
            ),
 | 
			
		||||
 
 | 
			
		||||
@@ -1371,6 +1371,7 @@ class GetProfileTest(ZulipTestCase):
 | 
			
		||||
    def test_get_user_profile(self) -> None:
 | 
			
		||||
        hamlet = self.example_user('hamlet')
 | 
			
		||||
        iago = self.example_user('iago')
 | 
			
		||||
        desdemona = self.example_user('desdemona')
 | 
			
		||||
 | 
			
		||||
        self.login('hamlet')
 | 
			
		||||
        result = ujson.loads(self.client_get('/json/users/me').content)
 | 
			
		||||
@@ -1380,6 +1381,7 @@ class GetProfileTest(ZulipTestCase):
 | 
			
		||||
        self.assertIn("user_id", result)
 | 
			
		||||
        self.assertFalse(result['is_bot'])
 | 
			
		||||
        self.assertFalse(result['is_admin'])
 | 
			
		||||
        self.assertFalse(result['is_owner'])
 | 
			
		||||
        self.assertFalse('delivery_email' in result)
 | 
			
		||||
        self.login('iago')
 | 
			
		||||
        result = ujson.loads(self.client_get('/json/users/me').content)
 | 
			
		||||
@@ -1388,6 +1390,14 @@ class GetProfileTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(result['full_name'], 'Iago')
 | 
			
		||||
        self.assertFalse(result['is_bot'])
 | 
			
		||||
        self.assertTrue(result['is_admin'])
 | 
			
		||||
        self.assertFalse(result['is_owner'])
 | 
			
		||||
        self.login('desdemona')
 | 
			
		||||
        result = ujson.loads(self.client_get('/json/users/me').content)
 | 
			
		||||
        self.assertEqual(result['short_name'], 'desdemona')
 | 
			
		||||
        self.assertEqual(result['email'], desdemona.email)
 | 
			
		||||
        self.assertFalse(result['is_bot'])
 | 
			
		||||
        self.assertTrue(result['is_admin'])
 | 
			
		||||
        self.assertTrue(result['is_owner'])
 | 
			
		||||
 | 
			
		||||
        # Tests the GET ../users/{id} api endpoint.
 | 
			
		||||
        user = self.example_user('hamlet')
 | 
			
		||||
@@ -1398,6 +1408,7 @@ class GetProfileTest(ZulipTestCase):
 | 
			
		||||
        self.assertNotIn("profile_data", result['user'])
 | 
			
		||||
        self.assertFalse(result['user']['is_bot'])
 | 
			
		||||
        self.assertFalse(result['user']['is_admin'])
 | 
			
		||||
        self.assertFalse(result['user']['is_owner'])
 | 
			
		||||
 | 
			
		||||
        result = ujson.loads(self.client_get('/json/users/{}?include_custom_profile_fields=true'.format(user.id)).content)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -467,6 +467,7 @@ def get_profile_backend(request: HttpRequest, user_profile: UserProfile) -> Http
 | 
			
		||||
                  email          = user_profile.email,
 | 
			
		||||
                  is_bot         = user_profile.is_bot,
 | 
			
		||||
                  is_admin       = user_profile.is_realm_admin,
 | 
			
		||||
                  is_owner       = user_profile.is_realm_owner,
 | 
			
		||||
                  short_name     = user_profile.short_name)
 | 
			
		||||
 | 
			
		||||
    if not user_profile.is_bot:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user