diff --git a/zerver/lib/upload/__init__.py b/zerver/lib/upload/__init__.py index 1d5dcc1e4f..f39ed8289f 100644 --- a/zerver/lib/upload/__init__.py +++ b/zerver/lib/upload/__init__.py @@ -310,12 +310,14 @@ def delete_avatar_image(user_profile: UserProfile, avatar_version: int) -> None: # Realm icon and logo uploads -def upload_icon_image(user_file: IO[bytes], user_profile: UserProfile) -> None: - upload_backend.upload_realm_icon_image(user_file, user_profile) +def upload_icon_image(user_file: IO[bytes], user_profile: UserProfile, content_type: str) -> None: + upload_backend.upload_realm_icon_image(user_file, user_profile, content_type) -def upload_logo_image(user_file: IO[bytes], user_profile: UserProfile, night: bool) -> None: - upload_backend.upload_realm_logo_image(user_file, user_profile, night) +def upload_logo_image( + user_file: IO[bytes], user_profile: UserProfile, night: bool, content_type: str +) -> None: + upload_backend.upload_realm_logo_image(user_file, user_profile, night, content_type) # Realm emoji uploads diff --git a/zerver/lib/upload/base.py b/zerver/lib/upload/base.py index a6b4e4c085..edab31bfc9 100644 --- a/zerver/lib/upload/base.py +++ b/zerver/lib/upload/base.py @@ -90,14 +90,16 @@ class ZulipUploadBackend: def get_realm_icon_url(self, realm_id: int, version: int) -> str: raise NotImplementedError - def upload_realm_icon_image(self, icon_file: IO[bytes], user_profile: UserProfile) -> None: + def upload_realm_icon_image( + self, icon_file: IO[bytes], user_profile: UserProfile, content_type: str + ) -> None: raise NotImplementedError def get_realm_logo_url(self, realm_id: int, version: int, night: bool) -> str: raise NotImplementedError def upload_realm_logo_image( - self, logo_file: IO[bytes], user_profile: UserProfile, night: bool + self, logo_file: IO[bytes], user_profile: UserProfile, night: bool, content_type: str ) -> None: raise NotImplementedError diff --git a/zerver/lib/upload/local.py b/zerver/lib/upload/local.py index 114c93e2d7..f53fe675af 100644 --- a/zerver/lib/upload/local.py +++ b/zerver/lib/upload/local.py @@ -138,7 +138,9 @@ class LocalUploadBackend(ZulipUploadBackend): return f"/user_avatars/{realm_id}/realm/icon.png?version={version}" @override - def upload_realm_icon_image(self, icon_file: IO[bytes], user_profile: UserProfile) -> None: + def upload_realm_icon_image( + self, icon_file: IO[bytes], user_profile: UserProfile, content_type: str + ) -> None: upload_path = self.realm_avatar_and_logo_path(user_profile.realm) image_data = icon_file.read() write_local_file("avatars", os.path.join(upload_path, "icon.original"), image_data) @@ -156,7 +158,7 @@ class LocalUploadBackend(ZulipUploadBackend): @override def upload_realm_logo_image( - self, logo_file: IO[bytes], user_profile: UserProfile, night: bool + self, logo_file: IO[bytes], user_profile: UserProfile, night: bool, content_type: str ) -> None: upload_path = self.realm_avatar_and_logo_path(user_profile.realm) if night: diff --git a/zerver/lib/upload/s3.py b/zerver/lib/upload/s3.py index 0cb1477eb5..7259a720fd 100644 --- a/zerver/lib/upload/s3.py +++ b/zerver/lib/upload/s3.py @@ -12,7 +12,6 @@ from django.conf import settings from mypy_boto3_s3.service_resource import Bucket from typing_extensions import override -from zerver.lib.mime_types import guess_type from zerver.lib.thumbnail import resize_avatar, resize_logo from zerver.lib.upload.base import INLINE_MIME_TYPES, ZulipUploadBackend from zerver.models import Realm, RealmEmoji, UserProfile @@ -87,7 +86,7 @@ def upload_image_to_s3( metadata.update(extra_metadata) extras = {} - if content_type is None: + if content_type is None: # nocoverage content_type = "" if content_type not in INLINE_MIME_TYPES: extras["ContentDisposition"] = "attachment" @@ -297,8 +296,9 @@ class S3UploadBackend(ZulipUploadBackend): return public_url + f"?version={version}" @override - def upload_realm_icon_image(self, icon_file: IO[bytes], user_profile: UserProfile) -> None: - content_type = guess_type(icon_file.name)[0] + def upload_realm_icon_image( + self, icon_file: IO[bytes], user_profile: UserProfile, content_type: str + ) -> None: s3_file_name = os.path.join(self.realm_avatar_and_logo_path(user_profile.realm), "icon") image_data = icon_file.read() @@ -332,9 +332,8 @@ class S3UploadBackend(ZulipUploadBackend): @override def upload_realm_logo_image( - self, logo_file: IO[bytes], user_profile: UserProfile, night: bool + self, logo_file: IO[bytes], user_profile: UserProfile, night: bool, content_type: str ) -> None: - content_type = guess_type(logo_file.name)[0] if night: basename = "night_logo" else: diff --git a/zerver/tests/test_import_export.py b/zerver/tests/test_import_export.py index 39eff0dc9e..a9bd1345d0 100644 --- a/zerver/tests/test_import_export.py +++ b/zerver/tests/test_import_export.py @@ -187,14 +187,18 @@ class ExportFile(ZulipTestCase): realm = user_profile.realm with get_test_image_file("img.png") as img_file: - upload.upload_backend.upload_realm_icon_image(img_file, user_profile) + upload.upload_backend.upload_realm_icon_image(img_file, user_profile, "image/png") do_change_icon_source(realm, Realm.ICON_UPLOADED, acting_user=None) with get_test_image_file("img.png") as img_file: - upload.upload_backend.upload_realm_logo_image(img_file, user_profile, night=False) + upload.upload_backend.upload_realm_logo_image( + img_file, user_profile, night=False, content_type="image/png" + ) do_change_logo_source(realm, Realm.LOGO_UPLOADED, False, acting_user=user_profile) with get_test_image_file("img.png") as img_file: - upload.upload_backend.upload_realm_logo_image(img_file, user_profile, night=True) + upload.upload_backend.upload_realm_logo_image( + img_file, user_profile, night=True, content_type="image/png" + ) do_change_logo_source(realm, Realm.LOGO_UPLOADED, True, acting_user=user_profile) def verify_attachment_json(self, user: UserProfile) -> None: diff --git a/zerver/tests/test_upload_s3.py b/zerver/tests/test_upload_s3.py index 3c43c37e4c..9aa22b0f65 100644 --- a/zerver/tests/test_upload_s3.py +++ b/zerver/tests/test_upload_s3.py @@ -402,7 +402,9 @@ class S3Test(ZulipTestCase): user_profile = self.example_user("hamlet") with get_test_image_file("img.png") as image_file: - zerver.lib.upload.upload_backend.upload_realm_icon_image(image_file, user_profile) + zerver.lib.upload.upload_backend.upload_realm_icon_image( + image_file, user_profile, content_type="image/png" + ) original_path_id = os.path.join(str(user_profile.realm.id), "realm", "icon.original") original_key = bucket.Object(original_path_id) @@ -421,7 +423,7 @@ class S3Test(ZulipTestCase): user_profile = self.example_user("hamlet") with get_test_image_file("img.png") as image_file: zerver.lib.upload.upload_backend.upload_realm_logo_image( - image_file, user_profile, night + image_file, user_profile, night, "image/png" ) original_path_id = os.path.join( diff --git a/zerver/views/realm_icon.py b/zerver/views/realm_icon.py index b6b5fd225b..d2ffd86959 100644 --- a/zerver/views/realm_icon.py +++ b/zerver/views/realm_icon.py @@ -9,7 +9,7 @@ from zerver.decorator import require_realm_admin from zerver.lib.exceptions import JsonableError from zerver.lib.realm_icon import realm_icon_url from zerver.lib.response import json_success -from zerver.lib.upload import upload_icon_image +from zerver.lib.upload import get_file_info, upload_icon_image from zerver.lib.url_encoding import append_url_query_string from zerver.models import UserProfile @@ -28,7 +28,8 @@ def upload_icon(request: HttpRequest, user_profile: UserProfile) -> HttpResponse max_size=settings.MAX_ICON_FILE_SIZE_MIB, ) ) - upload_icon_image(icon_file, user_profile) + _filename, content_type = get_file_info(icon_file) + upload_icon_image(icon_file, user_profile, content_type=content_type) do_change_icon_source( user_profile.realm, user_profile.realm.ICON_UPLOADED, acting_user=user_profile ) diff --git a/zerver/views/realm_logo.py b/zerver/views/realm_logo.py index 418ae6841e..99dd5aa94a 100644 --- a/zerver/views/realm_logo.py +++ b/zerver/views/realm_logo.py @@ -10,7 +10,7 @@ from zerver.lib.exceptions import JsonableError from zerver.lib.realm_logo import get_realm_logo_url from zerver.lib.request import REQ, has_request_variables from zerver.lib.response import json_success -from zerver.lib.upload import upload_logo_image +from zerver.lib.upload import get_file_info, upload_logo_image from zerver.lib.url_encoding import append_url_query_string from zerver.lib.validator import check_bool from zerver.models import UserProfile @@ -34,7 +34,8 @@ def upload_logo( max_size=settings.MAX_LOGO_FILE_SIZE_MIB, ) ) - upload_logo_image(logo_file, user_profile, night) + _filename, content_type = get_file_info(logo_file) + upload_logo_image(logo_file, user_profile, night, content_type=content_type) do_change_logo_source( user_profile.realm, user_profile.realm.LOGO_UPLOADED, night, acting_user=user_profile )