def _setup_export_files(self) -> Tuple[str, str, str, bytes]: realm = Realm.objects.get(string_id='zulip') message = Message.objects.all()[0] user_profile = message.sender url = upload_message_file(u'dummy.txt', len(b'zulip!'), u'text/plain', b'zulip!', user_profile) attachment_path_id = url.replace('/user_uploads/', '') claim_attachment( user_profile=user_profile, path_id=attachment_path_id, message=message, is_message_realm_public=True ) avatar_path_id = user_avatar_path(user_profile) original_avatar_path_id = avatar_path_id + ".original" emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format( realm_id=realm.id, emoji_file_name='1.png', ) with get_test_image_file('img.png') as img_file: upload_emoji_image(img_file, '1.png', user_profile) with get_test_image_file('img.png') as img_file: upload_avatar_image(img_file, user_profile, user_profile) test_image = open(get_test_image_file('img.png').name, 'rb').read() message.sender.avatar_source = 'U' message.sender.save() return attachment_path_id, emoji_path, original_avatar_path_id, test_image
def _setup_export_files(self) -> Tuple[str, str, str, bytes]: realm = Realm.objects.get(string_id='zulip') message = Message.objects.all()[0] user_profile = message.sender url = upload_message_file(u'dummy.txt', len(b'zulip!'), u'text/plain', b'zulip!', user_profile) attachment_path_id = url.replace('/user_uploads/', '') claim_attachment(user_profile=user_profile, path_id=attachment_path_id, message=message, is_message_realm_public=True) avatar_path_id = user_avatar_path(user_profile) original_avatar_path_id = avatar_path_id + ".original" emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format( realm_id=realm.id, emoji_file_name='1.png', ) with get_test_image_file('img.png') as img_file: upload_emoji_image(img_file, '1.png', user_profile) with get_test_image_file('img.png') as img_file: upload_avatar_image(img_file, user_profile, user_profile) test_image = open(get_test_image_file('img.png').name, 'rb').read() message.sender.avatar_source = 'U' message.sender.save() return attachment_path_id, emoji_path, original_avatar_path_id, test_image
def test_attachment_and_emoji(self) -> None: message = Message.objects.all()[0] user_profile = message.sender url = upload_message_file(u'dummy.txt', len(b'zulip!'), u'text/plain', b'zulip!', user_profile) path_id = url.replace('/user_uploads/', '') claim_attachment(user_profile=user_profile, path_id=path_id, message=message, is_message_realm_public=True) realm = Realm.objects.get(string_id='zulip') with get_test_image_file('img.png') as img_file: upload_emoji_image(img_file, '1.png', user_profile) full_data = self._export_realm(realm) data = full_data['attachment'] self.assertEqual(len(data['zerver_attachment']), 1) record = data['zerver_attachment'][0] self.assertEqual(record['path_id'], path_id) fn = os.path.join(full_data['uploads_dir'], path_id) with open(fn) as f: self.assertEqual(f.read(), 'zulip!') fn = os.path.join( full_data['emoji_dir'], RealmEmoji.PATH_ID_TEMPLATE.format(realm_id=realm.id, emoji_file_name='1.png')) fn = fn.replace('1.png', '') self.assertEqual('1.png', os.listdir(fn)[0])
def test_export_files_from_s3(self) -> None: conn = S3Connection(settings.S3_KEY, settings.S3_SECRET_KEY) conn.create_bucket(settings.S3_AUTH_UPLOADS_BUCKET) conn.create_bucket(settings.S3_AVATAR_BUCKET) realm = Realm.objects.get(string_id='zulip') message = Message.objects.all()[0] user_profile = message.sender url = upload_message_file(u'dummy.txt', len(b'zulip!'), u'text/plain', b'zulip!', user_profile) attachment_path_id = url.replace('/user_uploads/', '') claim_attachment( user_profile=user_profile, path_id=attachment_path_id, message=message, is_message_realm_public=True ) avatar_path_id = user_avatar_path(user_profile) original_avatar_path_id = avatar_path_id + ".original" emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format( realm_id=realm.id, emoji_file_name='1.png', ) with get_test_image_file('img.png') as img_file: upload_emoji_image(img_file, '1.png', user_profile) with get_test_image_file('img.png') as img_file: upload_avatar_image(img_file, user_profile, user_profile) test_image = open(get_test_image_file('img.png').name, 'rb').read() full_data = self._export_realm(realm) data = full_data['attachment'] self.assertEqual(len(data['zerver_attachment']), 1) record = data['zerver_attachment'][0] self.assertEqual(record['path_id'], attachment_path_id) # Test uploads fields = attachment_path_id.split('/') fn = os.path.join(full_data['uploads_dir'], os.path.join(fields[1], fields[2])) with open(fn) as f: self.assertEqual(f.read(), 'zulip!') # Test emojis fn = os.path.join(full_data['emoji_dir'], emoji_path) fn = fn.replace('1.png', '') self.assertIn('1.png', os.listdir(fn)) # Test avatars fn = os.path.join(full_data['avatar_dir'], original_avatar_path_id) fn_data = open(fn, 'rb').read() self.assertEqual(fn_data, test_image)
def test_export_files_from_s3(self) -> None: conn = S3Connection(settings.S3_KEY, settings.S3_SECRET_KEY) conn.create_bucket(settings.S3_AUTH_UPLOADS_BUCKET) conn.create_bucket(settings.S3_AVATAR_BUCKET) realm = Realm.objects.get(string_id='zulip') message = Message.objects.all()[0] user_profile = message.sender url = upload_message_file(u'dummy.txt', len(b'zulip!'), u'text/plain', b'zulip!', user_profile) attachment_path_id = url.replace('/user_uploads/', '') claim_attachment(user_profile=user_profile, path_id=attachment_path_id, message=message, is_message_realm_public=True) avatar_path_id = user_avatar_path(user_profile) original_avatar_path_id = avatar_path_id + ".original" emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format( realm_id=realm.id, emoji_file_name='1.png', ) with get_test_image_file('img.png') as img_file: upload_emoji_image(img_file, '1.png', user_profile) with get_test_image_file('img.png') as img_file: upload_avatar_image(img_file, user_profile, user_profile) test_image = open(get_test_image_file('img.png').name, 'rb').read() full_data = self._export_realm(realm) data = full_data['attachment'] self.assertEqual(len(data['zerver_attachment']), 1) record = data['zerver_attachment'][0] self.assertEqual(record['path_id'], attachment_path_id) # Test uploads fields = attachment_path_id.split('/') fn = os.path.join(full_data['uploads_dir'], os.path.join(fields[1], fields[2])) with open(fn) as f: self.assertEqual(f.read(), 'zulip!') # Test emojis fn = os.path.join(full_data['emoji_dir'], emoji_path) fn = fn.replace('1.png', '') self.assertIn('1.png', os.listdir(fn)) # Test avatars fn = os.path.join(full_data['avatar_dir'], original_avatar_path_id) fn_data = open(fn, 'rb').read() self.assertEqual(fn_data, test_image)
def check_add_realm_emoji(realm: Realm, name: str, author: UserProfile, image_file: IO[bytes]) -> RealmEmoji: try: realm_emoji = RealmEmoji(realm=realm, name=name, author=author) realm_emoji.full_clean() realm_emoji.save() except django.db.utils.IntegrityError: # Match the string in upload_emoji. raise JsonableError(_("A custom emoji with this name already exists.")) emoji_file_name = get_emoji_file_name(image_file.name, realm_emoji.id) # The only user-controlled portion of 'emoji_file_name' is an extension, # which can not contain '..' or '/' or '\', making it difficult to exploit emoji_file_name = mark_sanitized(emoji_file_name) emoji_uploaded_successfully = False is_animated = False try: is_animated = upload_emoji_image(image_file, emoji_file_name, author) emoji_uploaded_successfully = True finally: if not emoji_uploaded_successfully: realm_emoji.delete() realm_emoji.file_name = emoji_file_name realm_emoji.is_animated = is_animated realm_emoji.save(update_fields=["file_name", "is_animated"]) notify_realm_emoji(realm_emoji.realm) return realm_emoji
def upload_emoji(request: HttpRequest, user_profile: UserProfile, emoji_name: Text=REQ()) -> HttpResponse: check_valid_emoji_name(emoji_name) check_emoji_admin(user_profile) if len(request.FILES) != 1: return json_error(_("You must upload exactly one file.")) emoji_file = list(request.FILES.values())[0] if (settings.MAX_EMOJI_FILE_SIZE * 1024 * 1024) < emoji_file.size: return json_error(_("Uploaded file is larger than the allowed limit of %s MB") % ( settings.MAX_EMOJI_FILE_SIZE)) emoji_file_name = get_emoji_file_name(emoji_file.name, emoji_name) upload_emoji_image(emoji_file, emoji_file_name, user_profile) try: check_add_realm_emoji(user_profile.realm, emoji_name, emoji_file_name, author=user_profile) except ValidationError as e: return json_error(e.messages[0]) return json_success()
def test_export_files_from_local(self) -> None: message = Message.objects.all()[0] user_profile = message.sender url = upload_message_file(u'dummy.txt', len(b'zulip!'), u'text/plain', b'zulip!', user_profile) path_id = url.replace('/user_uploads/', '') claim_attachment(user_profile=user_profile, path_id=path_id, message=message, is_message_realm_public=True) avatar_path_id = user_avatar_path(user_profile) original_avatar_path_id = avatar_path_id + ".original" realm = Realm.objects.get(string_id='zulip') with get_test_image_file('img.png') as img_file: upload_emoji_image(img_file, '1.png', user_profile) with get_test_image_file('img.png') as img_file: upload_avatar_image(img_file, user_profile, user_profile) test_image = open(get_test_image_file('img.png').name, 'rb').read() message.sender.avatar_source = 'U' message.sender.save() full_data = self._export_realm(realm) data = full_data['attachment'] self.assertEqual(len(data['zerver_attachment']), 1) record = data['zerver_attachment'][0] self.assertEqual(record['path_id'], path_id) # Test uploads fn = os.path.join(full_data['uploads_dir'], path_id) with open(fn) as f: self.assertEqual(f.read(), 'zulip!') # Test emojis fn = os.path.join( full_data['emoji_dir'], RealmEmoji.PATH_ID_TEMPLATE.format(realm_id=realm.id, emoji_file_name='1.png')) fn = fn.replace('1.png', '') self.assertEqual('1.png', os.listdir(fn)[0]) # Test avatars fn = os.path.join(full_data['avatar_dir'], original_avatar_path_id) fn_data = open(fn, 'rb').read() self.assertEqual(fn_data, test_image)
def test_export_files_from_local(self) -> None: message = Message.objects.all()[0] user_profile = message.sender url = upload_message_file(u'dummy.txt', len(b'zulip!'), u'text/plain', b'zulip!', user_profile) path_id = url.replace('/user_uploads/', '') claim_attachment( user_profile=user_profile, path_id=path_id, message=message, is_message_realm_public=True ) avatar_path_id = user_avatar_path(user_profile) original_avatar_path_id = avatar_path_id + ".original" realm = Realm.objects.get(string_id='zulip') with get_test_image_file('img.png') as img_file: upload_emoji_image(img_file, '1.png', user_profile) with get_test_image_file('img.png') as img_file: upload_avatar_image(img_file, user_profile, user_profile) test_image = open(get_test_image_file('img.png').name, 'rb').read() message.sender.avatar_source = 'U' message.sender.save() full_data = self._export_realm(realm) data = full_data['attachment'] self.assertEqual(len(data['zerver_attachment']), 1) record = data['zerver_attachment'][0] self.assertEqual(record['path_id'], path_id) # Test uploads fn = os.path.join(full_data['uploads_dir'], path_id) with open(fn) as f: self.assertEqual(f.read(), 'zulip!') # Test emojis fn = os.path.join(full_data['emoji_dir'], RealmEmoji.PATH_ID_TEMPLATE.format(realm_id=realm.id, emoji_file_name='1.png')) fn = fn.replace('1.png', '') self.assertEqual('1.png', os.listdir(fn)[0]) # Test avatars fn = os.path.join(full_data['avatar_dir'], original_avatar_path_id) fn_data = open(fn, 'rb').read() self.assertEqual(fn_data, test_image)
def upload_emoji(request, user_profile, emoji_name=REQ()): # type: (HttpRequest, UserProfile, Text) -> HttpResponse check_valid_emoji_name(emoji_name) check_emoji_admin(user_profile) if len(request.FILES) != 1: return json_error(_("You must upload exactly one file.")) emoji_file = list(request.FILES.values())[0] if (settings.MAX_EMOJI_FILE_SIZE * 1024 * 1024) < emoji_file.size: return json_error( _("Uploaded file is larger than the allowed limit of %s MB") % (settings.MAX_EMOJI_FILE_SIZE)) emoji_file_name = get_emoji_file_name(emoji_file.name, emoji_name) upload_emoji_image(emoji_file, emoji_file_name, user_profile) try: check_add_realm_emoji(user_profile.realm, emoji_name, emoji_file_name, author=user_profile) except ValidationError as e: return json_error(e.messages[0]) return json_success()
def test_s3_source_type(self) -> None: def get_file_path_urlpart(uri: str, size: str = '') -> str: url_in_result = 'smart/filters:no_upscale()%s/%s/source_type/s3' sharpen_filter = '' if size: url_in_result = '/%s/%s' % (size, url_in_result) sharpen_filter = ':sharpen(0.5,0.2,true)' hex_uri = base64.urlsafe_b64encode(uri.encode()).decode('utf-8') return url_in_result % (sharpen_filter, hex_uri) create_s3_buckets(settings.S3_AUTH_UPLOADS_BUCKET, settings.S3_AVATAR_BUCKET) self.login(self.example_email("hamlet")) fp = StringIO("zulip!") fp.name = "zulip.jpeg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = ujson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] base = '/user_uploads/' self.assertEqual(base, uri[:len(base)]) quoted_uri = urllib.parse.quote(uri[1:], safe='') # Test full size image. result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test thumbnail size. result = self.client_get("/thumbnail?url=%s&size=thumbnail" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri, '0x300') self.assertIn(expected_part_url, result.url) # Test custom emoji urls in Zulip messages. user_profile = self.example_user("hamlet") image_file = get_test_image_file("img.png") file_name = "emoji.png" upload_emoji_image(image_file, file_name, user_profile) custom_emoji_url = upload_backend.get_emoji_url( file_name, user_profile.realm_id) emoji_url_base = '/user_avatars/' self.assertEqual(emoji_url_base, custom_emoji_url[:len(emoji_url_base)]) quoted_emoji_url = urllib.parse.quote(custom_emoji_url[1:], safe='') # Test full size custom emoji image (for emoji link in messages case). result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_emoji_url)) self.assertEqual(result.status_code, 302, result) self.assertIn(custom_emoji_url, result.url) # Tests the /api/v1/thumbnail api endpoint with standard API auth self.logout() result = self.api_get(self.example_email("hamlet"), '/thumbnail?url=%s&size=full' % (quoted_uri, )) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test with another user trying to access image using thumbor. self.login(self.example_email("iago")) result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 403, result) self.assert_in_response("You are not authorized to view this file.", result)
def test_local_file_type(self) -> None: def get_file_path_urlpart(uri: str, size: str = '') -> str: url_in_result = 'smart/filters:no_upscale():sharpen(2.2,0.8,false)/%s/source_type/local_file' if size: url_in_result = '/%s/%s' % (size, url_in_result) hex_uri = base64.urlsafe_b64encode(uri.encode()).decode('utf-8') return url_in_result % (hex_uri) self.login(self.example_email("hamlet")) fp = StringIO("zulip!") fp.name = "zulip.jpeg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = ujson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] base = '/user_uploads/' self.assertEqual(base, uri[:len(base)]) # Test full size image. # We remove the forward slash infront of the `/user_uploads/` to match # bugdown behaviour. quoted_uri = urllib.parse.quote(uri[1:], safe='') result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test thumbnail size. result = self.client_get("/thumbnail?url=%s&size=thumbnail" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri, '0x300') self.assertIn(expected_part_url, result.url) # Test with a unicode filename. fp = StringIO("zulip!") fp.name = "μένει.jpg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = ujson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] # We remove the forward slash infront of the `/user_uploads/` to match # bugdown behaviour. quoted_uri = urllib.parse.quote(uri[1:], safe='') result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test custom emoji urls in Zulip messages. user_profile = self.example_user("hamlet") image_file = get_test_image_file("img.png") file_name = "emoji.png" upload_emoji_image(image_file, file_name, user_profile) custom_emoji_url = upload_backend.get_emoji_url( file_name, user_profile.realm_id) emoji_url_base = '/user_avatars/' self.assertEqual(emoji_url_base, custom_emoji_url[:len(emoji_url_base)]) quoted_emoji_url = urllib.parse.quote(custom_emoji_url[1:], safe='') # Test full size custom emoji image (for emoji link in messages case). result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_emoji_url)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(custom_emoji_url) self.assertIn(expected_part_url, result.url) # Tests the /api/v1/thumbnail api endpoint with HTTP basic auth. self.logout() user_profile = self.example_user("hamlet") result = self.api_get(self.example_email("hamlet"), '/thumbnail?url=%s&size=full' % (quoted_uri, )) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Tests the /api/v1/thumbnail api endpoint with ?api_key # auth. user_profile = self.example_user("hamlet") result = self.client_get('/thumbnail?url=%s&size=full&api_key=%s' % (quoted_uri, get_api_key(user_profile))) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test with another user trying to access image using thumbor. self.login(self.example_email("iago")) result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 403, result) self.assert_in_response("You are not authorized to view this file.", result)
def test_local_file_type(self) -> None: def get_file_path_urlpart(uri: str, size: str = '') -> str: url_in_result = 'smart/filters:no_upscale()%s/%s/source_type/local_file' sharpen_filter = '' if size: url_in_result = f'/{size}/{url_in_result}' sharpen_filter = ':sharpen(0.5,0.2,true)' hex_uri = base64.urlsafe_b64encode(uri.encode()).decode('utf-8') return url_in_result % (sharpen_filter, hex_uri) self.login('hamlet') fp = StringIO("zulip!") fp.name = "zulip.jpeg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = orjson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] base = '/user_uploads/' self.assertEqual(base, uri[:len(base)]) # Test full size image. # We remove the forward slash infront of the `/user_uploads/` to match # Markdown behaviour. result = self.client_get("/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test thumbnail size. result = self.client_get("/thumbnail", { "url": uri[1:], "size": "thumbnail" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri, '0x300') self.assertIn(expected_part_url, result.url) # Test with a Unicode filename. fp = StringIO("zulip!") fp.name = "μένει.jpg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = orjson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] # We remove the forward slash infront of the `/user_uploads/` to match # Markdown behaviour. result = self.client_get("/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test custom emoji urls in Zulip messages. user_profile = self.example_user("hamlet") file_name = "emoji.png" with get_test_image_file("img.png") as image_file: upload_emoji_image(image_file, file_name, user_profile) custom_emoji_url = upload_backend.get_emoji_url( file_name, user_profile.realm_id) emoji_url_base = '/user_avatars/' self.assertEqual(emoji_url_base, custom_emoji_url[:len(emoji_url_base)]) # Test full size custom emoji image (for emoji link in messages case). result = self.client_get("/thumbnail", { "url": custom_emoji_url[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) self.assertIn(custom_emoji_url, result.url) # Tests the /api/v1/thumbnail API endpoint with HTTP basic auth. self.logout() user_profile = self.example_user("hamlet") result = self.api_get(user_profile, "/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Tests the /api/v1/thumbnail API endpoint with ?api_key # auth. user_profile = self.example_user("hamlet") result = self.client_get("/thumbnail", { "url": uri[1:], "size": "full", "api_key": get_api_key(user_profile) }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test with another user trying to access image using thumbor. self.login('iago') result = self.client_get("/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 403, result) self.assert_in_response("You are not authorized to view this file.", result)
def test_s3_source_type(self) -> None: def get_file_path_urlpart(uri: str, size: str = "") -> str: url_in_result = "smart/filters:no_upscale()%s/%s/source_type/s3" sharpen_filter = "" if size: url_in_result = f"/{size}/{url_in_result}" sharpen_filter = ":sharpen(0.5,0.2,true)" hex_uri = base64.urlsafe_b64encode(uri.encode()).decode("utf-8") return url_in_result % (sharpen_filter, hex_uri) create_s3_buckets(settings.S3_AUTH_UPLOADS_BUCKET, settings.S3_AVATAR_BUCKET) hamlet = self.example_user("hamlet") self.login_user(hamlet) fp = StringIO("zulip!") fp.name = "zulip.jpeg" result = self.client_post("/json/user_uploads", {"file": fp}) self.assert_json_success(result) json = orjson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] base = "/user_uploads/" self.assertEqual(base, uri[:len(base)]) # Test full size image. result = self.client_get("/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test thumbnail size. result = self.client_get("/thumbnail", { "url": uri[1:], "size": "thumbnail" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri, "0x300") self.assertIn(expected_part_url, result.url) # Test custom emoji URLs in Zulip messages. user_profile = self.example_user("hamlet") file_name = "emoji.png" with get_test_image_file("img.png") as image_file: upload_emoji_image(image_file, file_name, user_profile) custom_emoji_url = upload_backend.get_emoji_url( file_name, user_profile.realm_id) emoji_url_base = "/user_avatars/" self.assertEqual(emoji_url_base, custom_emoji_url[:len(emoji_url_base)]) # Test full size custom emoji image (for emoji link in messages case). result = self.client_get("/thumbnail", { "url": custom_emoji_url[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) self.assertIn(custom_emoji_url, result.url) # Tests the /api/v1/thumbnail API endpoint with standard API auth self.logout() result = self.api_get(hamlet, "/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test with another user trying to access image using thumbor. self.login("iago") result = self.client_get("/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 403, result) self.assert_in_response("You are not authorized to view this file.", result)
def test_s3_source_type(self) -> None: def get_file_path_urlpart(uri: str, size: str='') -> str: url_in_result = 'smart/filters:no_upscale()%s/%s/source_type/s3' sharpen_filter = '' if size: url_in_result = '/%s/%s' % (size, url_in_result) sharpen_filter = ':sharpen(0.5,0.2,true)' hex_uri = base64.urlsafe_b64encode(uri.encode()).decode('utf-8') return url_in_result % (sharpen_filter, hex_uri) create_s3_buckets( settings.S3_AUTH_UPLOADS_BUCKET, settings.S3_AVATAR_BUCKET) self.login(self.example_email("hamlet")) fp = StringIO("zulip!") fp.name = "zulip.jpeg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = ujson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] base = '/user_uploads/' self.assertEqual(base, uri[:len(base)]) quoted_uri = urllib.parse.quote(uri[1:], safe='') # Test full size image. result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test thumbnail size. result = self.client_get("/thumbnail?url=%s&size=thumbnail" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri, '0x300') self.assertIn(expected_part_url, result.url) # Test custom emoji urls in Zulip messages. user_profile = self.example_user("hamlet") image_file = get_test_image_file("img.png") file_name = "emoji.png" upload_emoji_image(image_file, file_name, user_profile) custom_emoji_url = upload_backend.get_emoji_url(file_name, user_profile.realm_id) emoji_url_base = '/user_avatars/' self.assertEqual(emoji_url_base, custom_emoji_url[:len(emoji_url_base)]) quoted_emoji_url = urllib.parse.quote(custom_emoji_url[1:], safe='') # Test full size custom emoji image (for emoji link in messages case). result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_emoji_url)) self.assertEqual(result.status_code, 302, result) self.assertIn(custom_emoji_url, result.url) # Tests the /api/v1/thumbnail api endpoint with standard API auth self.logout() result = self.api_get( self.example_email("hamlet"), '/thumbnail?url=%s&size=full' % (quoted_uri,)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test with another user trying to access image using thumbor. self.login(self.example_email("iago")) result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 403, result) self.assert_in_response("You are not authorized to view this file.", result)
def test_local_file_type(self) -> None: def get_file_path_urlpart(uri: str, size: str='') -> str: url_in_result = 'smart/filters:no_upscale():sharpen(0.5,0.2,true)/%s/source_type/local_file' if size: url_in_result = '/%s/%s' % (size, url_in_result) hex_uri = base64.urlsafe_b64encode(uri.encode()).decode('utf-8') return url_in_result % (hex_uri) self.login(self.example_email("hamlet")) fp = StringIO("zulip!") fp.name = "zulip.jpeg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = ujson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] base = '/user_uploads/' self.assertEqual(base, uri[:len(base)]) # Test full size image. # We remove the forward slash infront of the `/user_uploads/` to match # bugdown behaviour. quoted_uri = urllib.parse.quote(uri[1:], safe='') result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test thumbnail size. result = self.client_get("/thumbnail?url=%s&size=thumbnail" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri, '0x300') self.assertIn(expected_part_url, result.url) # Test with a unicode filename. fp = StringIO("zulip!") fp.name = "μένει.jpg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = ujson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] # We remove the forward slash infront of the `/user_uploads/` to match # bugdown behaviour. quoted_uri = urllib.parse.quote(uri[1:], safe='') result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test custom emoji urls in Zulip messages. user_profile = self.example_user("hamlet") image_file = get_test_image_file("img.png") file_name = "emoji.png" upload_emoji_image(image_file, file_name, user_profile) custom_emoji_url = upload_backend.get_emoji_url(file_name, user_profile.realm_id) emoji_url_base = '/user_avatars/' self.assertEqual(emoji_url_base, custom_emoji_url[:len(emoji_url_base)]) quoted_emoji_url = urllib.parse.quote(custom_emoji_url[1:], safe='') # Test full size custom emoji image (for emoji link in messages case). result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_emoji_url)) self.assertEqual(result.status_code, 302, result) self.assertIn(custom_emoji_url, result.url) # Tests the /api/v1/thumbnail api endpoint with HTTP basic auth. self.logout() user_profile = self.example_user("hamlet") result = self.api_get( self.example_email("hamlet"), '/thumbnail?url=%s&size=full' % (quoted_uri,)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Tests the /api/v1/thumbnail api endpoint with ?api_key # auth. user_profile = self.example_user("hamlet") result = self.client_get( '/thumbnail?url=%s&size=full&api_key=%s' % (quoted_uri, get_api_key(user_profile))) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test with another user trying to access image using thumbor. self.login(self.example_email("iago")) result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 403, result) self.assert_in_response("You are not authorized to view this file.", result)