settings_emoji: Allow only admins to override existing emojis.

Previously, even non-admins had the option to override built-in
emojis in the `Settings Emoji` UI.

This commits essentially limits the functionality of overriding
custom and allows only realm administrators to
override built-in emojis with their custom emojis by adding an
authorization check in the backend.

It also adds relevant tests in `test_realm_emoji` which tests
for the cases where an admin and non admin tries to override
the built-in emoji.

Fixes #18860.
This commit is contained in:
aryanshridhar 2021-06-17 00:19:41 +05:30 committed by Tim Abbott
parent ab380b122b
commit 7dc56fdcf2
2 changed files with 27 additions and 1 deletions

View File

@ -79,6 +79,28 @@ class RealmEmojiTest(ZulipTestCase):
author = UserProfile.objects.get(id=test_emoji["author_id"]) author = UserProfile.objects.get(id=test_emoji["author_id"])
self.assertEqual(author.email, email) self.assertEqual(author.email, email)
def test_override_built_in_emoji_by_admin(self) -> None:
# Test that only administrators can override built-in emoji.
self.login("othello")
with get_test_image_file("img.png") as fp1:
emoji_data = {"f1": fp1}
result = self.client_post("/json/realm/emoji/laughing", info=emoji_data)
self.assert_json_error(
result,
"Only administrators can override built-in emoji.",
)
user = self.example_user("iago")
email = user.email
self.login_user(user)
with get_test_image_file("img.png") as fp1:
emoji_data = {"f1": fp1}
result = self.client_post("/json/realm/emoji/smile", info=emoji_data)
self.assert_json_success(result)
self.assertEqual(200, result.status_code)
realm_emoji = RealmEmoji.objects.get(name="smile")
self.assertEqual(realm_emoji.author.email, email)
def test_realm_emoji_repr(self) -> None: def test_realm_emoji_repr(self) -> None:
realm_emoji = RealmEmoji.objects.get(name="green_tick") realm_emoji = RealmEmoji.objects.get(name="green_tick")
file_name = str(realm_emoji.id) + ".png" file_name = str(realm_emoji.id) + ".png"

View File

@ -4,7 +4,7 @@ from django.utils.translation import gettext as _
from zerver.decorator import require_member_or_admin from zerver.decorator import require_member_or_admin
from zerver.lib.actions import check_add_realm_emoji, do_remove_realm_emoji from zerver.lib.actions import check_add_realm_emoji, do_remove_realm_emoji
from zerver.lib.emoji import check_emoji_admin, check_valid_emoji_name from zerver.lib.emoji import check_emoji_admin, check_valid_emoji_name, name_to_codepoint
from zerver.lib.request import REQ, JsonableError, has_request_variables from zerver.lib.request import REQ, JsonableError, has_request_variables
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.models import RealmEmoji, UserProfile from zerver.models import RealmEmoji, UserProfile
@ -23,6 +23,7 @@ def upload_emoji(
request: HttpRequest, user_profile: UserProfile, emoji_name: str = REQ(path_only=True) request: HttpRequest, user_profile: UserProfile, emoji_name: str = REQ(path_only=True)
) -> HttpResponse: ) -> HttpResponse:
emoji_name = emoji_name.strip().replace(" ", "_") emoji_name = emoji_name.strip().replace(" ", "_")
valid_built_in_emoji = name_to_codepoint.keys()
check_valid_emoji_name(emoji_name) check_valid_emoji_name(emoji_name)
check_emoji_admin(user_profile) check_emoji_admin(user_profile)
if RealmEmoji.objects.filter( if RealmEmoji.objects.filter(
@ -31,6 +32,9 @@ def upload_emoji(
raise JsonableError(_("A custom emoji with this name already exists.")) raise JsonableError(_("A custom emoji with this name already exists."))
if len(request.FILES) != 1: if len(request.FILES) != 1:
raise JsonableError(_("You must upload exactly one file.")) raise JsonableError(_("You must upload exactly one file."))
if emoji_name in valid_built_in_emoji:
if not user_profile.is_realm_admin:
raise JsonableError(_("Only administrators can override built-in emoji."))
emoji_file = list(request.FILES.values())[0] emoji_file = list(request.FILES.values())[0]
if (settings.MAX_EMOJI_FILE_SIZE_MIB * 1024 * 1024) < emoji_file.size: if (settings.MAX_EMOJI_FILE_SIZE_MIB * 1024 * 1024) < emoji_file.size:
raise JsonableError( raise JsonableError(