diff --git a/templates/zerver/api/changelog.md b/templates/zerver/api/changelog.md index da3850956f..8e08a8a66d 100644 --- a/templates/zerver/api/changelog.md +++ b/templates/zerver/api/changelog.md @@ -12,6 +12,9 @@ below features are supported. **Feature level 10** +* [`GET users/me`](/api/get-profile): Added `avatar_version`, `is_guest`, + `is_active`, `timezone`, and `date_joined` fields to the User objects. + **Feature level 9** * [`POST users/me/subscriptions`](/api/add-subscriptions), [`DELETE diff --git a/zerver/openapi/zulip.yaml b/zerver/openapi/zulip.yaml index 2587f3f943..8116b1c025 100644 --- a/zerver/openapi/zulip.yaml +++ b/zerver/openapi/zulip.yaml @@ -1836,6 +1836,16 @@ paths: **Changes**: New in Zulip 2.1.0. example: "x" + avatar_version: + type: integer + description: | + Version for the the user's avatar. Used for cache-busting requests + for the user's avatar. Clients generally shouldn't need to use this; + most avatar URLs sent by Zulip will already end with `?v={avatar_version}`. + + **Changes**: New in Zulip 2.2 (feature level 10). Previous + versions do not return this field. + example: 1 client_id: type: string description: | @@ -1864,11 +1874,43 @@ paths: **Changes**: New in Zulip 2.2 (feature level 8). example: false + is_guest: + type: boolean + description: | + A boolean indicating if the requesting user is a guest. + + **Changes**: New in Zulip 2.2 (feature level 10). Previous + versions do not return this field. + example: false is_bot: type: boolean description: | A boolean indicating if the requesting user is a bot. example: false + is_active: + type: boolean + description: | + A boolean specifying whether the user account has been deactivated. + + **Changes**: New in Zulip 2.2 (feature level 10). Previous + versions do not return this field. + example: true + timezone: + type: string + description: | + The time zone of the user. + + **Changes**: New in Zulip 2.2 (feature level 10). Previous + versions do not return this field. + example: "" + date_joined: + type: string + description: | + The time the user account was created. + + **Changes**: New in Zulip 2.2 (feature level 10). Previous + versions do not return this field. + example: "2019-10-20T07:50:53.728864+00:00" max_message_id: type: integer description: | @@ -1899,12 +1941,17 @@ paths: - example: { "avatar_url": "https://secure.gravatar.com/avatar/af4f06322c177ef4e1e9b2c424986b54?d=identicon&version=1", + "avatar_version": 1, "client_id": "74c768b081076fdb3c4326256c17467e", "email": "iago@zulip.com", "full_name": "Iago", "is_admin": true, "is_owner": false, + "is_guest": false, "is_bot": false, + "is_active": true, + "timezone": "", + "date_joined": "2019-10-20T07:50:53.728864+00:00", "max_message_id": 30, "msg": "", "pointer": -1, diff --git a/zerver/tests/test_custom_profile_data.py b/zerver/tests/test_custom_profile_data.py index 31ce952621..4b8f858ae5 100644 --- a/zerver/tests/test_custom_profile_data.py +++ b/zerver/tests/test_custom_profile_data.py @@ -698,7 +698,8 @@ class ListCustomProfileFieldTest(CustomProfileFieldTestCase): expected_keys = { "result", "msg", "pointer", "client_id", "max_message_id", "user_id", "avatar_url", "full_name", "email", "is_bot", "is_admin", "is_owner", - "short_name", "profile_data"} + "short_name", "profile_data", "avatar_version", "timezone", "delivery_email", + "is_active", "is_guest", "date_joined"} url = "/json/users/me" response = self.client_get(url) diff --git a/zerver/tests/test_users.py b/zerver/tests/test_users.py index b1c052dcd2..04b7512cd0 100644 --- a/zerver/tests/test_users.py +++ b/zerver/tests/test_users.py @@ -1379,6 +1379,7 @@ class GetProfileTest(ZulipTestCase): self.assertFalse(result['is_bot']) self.assertFalse(result['is_admin']) self.assertFalse(result['is_owner']) + self.assertFalse(result['is_guest']) self.assertFalse('delivery_email' in result) self.login('iago') result = ujson.loads(self.client_get('/json/users/me').content) @@ -1388,6 +1389,7 @@ class GetProfileTest(ZulipTestCase): self.assertFalse(result['is_bot']) self.assertTrue(result['is_admin']) self.assertFalse(result['is_owner']) + self.assertFalse(result['is_guest']) self.login('desdemona') result = ujson.loads(self.client_get('/json/users/me').content) self.assertEqual(result['short_name'], 'desdemona') @@ -1395,6 +1397,7 @@ class GetProfileTest(ZulipTestCase): self.assertFalse(result['is_bot']) self.assertTrue(result['is_admin']) self.assertTrue(result['is_owner']) + self.assertFalse(result['is_guest']) # Tests the GET ../users/{id} api endpoint. user = self.example_user('hamlet') diff --git a/zerver/views/users.py b/zerver/views/users.py index 5d4cee2752..82b7d3b628 100644 --- a/zerver/views/users.py +++ b/zerver/views/users.py @@ -458,32 +458,14 @@ def generate_client_id() -> str: return generate_random_token(32) def get_profile_backend(request: HttpRequest, user_profile: UserProfile) -> HttpResponse: - result = dict(pointer = user_profile.pointer, - client_id = generate_client_id(), - max_message_id = -1, - user_id = user_profile.id, - avatar_url = avatar_url(user_profile), - full_name = user_profile.full_name, - 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) + raw_user_data = get_raw_user_data(user_profile.realm, user_profile, + client_gravatar=False, target_user=user_profile) + result: Dict[str, Any] = raw_user_data[user_profile.id] - if not user_profile.is_bot: - custom_profile_field_values = user_profile.customprofilefieldvalue_set.all() - profile_data: Dict[int, Dict[str, Any]] = dict() - for profile_field in custom_profile_field_values: - if profile_field.field.is_renderable(): - profile_data[profile_field.field_id] = { - "value": profile_field.value, - "rendered_value": profile_field.rendered_value - } - else: - profile_data[profile_field.field_id] = { - "value": profile_field.value - } - result["profile_data"] = profile_data + result['client_id'] = generate_client_id() + result['short_name'] = user_profile.short_name + result['max_message_id'] = -1 + result['pointer'] = user_profile.pointer messages = Message.objects.filter(usermessage__user_profile=user_profile).order_by('-id')[:1] if messages: