示例#1
0
    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
示例#2
0
 def test_multiple_upload(self):
     # type: () -> None
     email = self.example_email('iago')
     self.login(email)
     with get_test_image_file('img.png') as fp1, get_test_image_file('img.png') as fp2:
         result = self.client_post('/json/realm/emoji/my_emoji', {'f1': fp1, 'f2': fp2})
     self.assert_json_error(result, 'You must upload exactly one file.')
示例#3
0
    def test_upload_avatar_image(self) -> None:
        conn = S3Connection(settings.S3_KEY, settings.S3_SECRET_KEY)
        bucket = conn.create_bucket(settings.S3_AVATAR_BUCKET)

        user_profile = self.example_user('hamlet')
        path_id = user_avatar_path(user_profile)
        original_image_path_id = path_id + ".original"
        medium_path_id = path_id + "-medium.png"

        with get_test_image_file('img.png') as image_file:
            zerver.lib.upload.upload_backend.upload_avatar_image(image_file, user_profile, user_profile)
        test_image_data = open(get_test_image_file('img.png').name, 'rb').read()
        test_medium_image_data = resize_avatar(test_image_data, MEDIUM_AVATAR_SIZE)

        original_image_key = bucket.get_key(original_image_path_id)
        self.assertEqual(original_image_key.key, original_image_path_id)
        image_data = original_image_key.get_contents_as_string()
        self.assertEqual(image_data, test_image_data)

        medium_image_key = bucket.get_key(medium_path_id)
        self.assertEqual(medium_image_key.key, medium_path_id)
        medium_image_data = medium_image_key.get_contents_as_string()
        self.assertEqual(medium_image_data, test_medium_image_data)
        bucket.delete_key(medium_image_key)

        zerver.lib.upload.upload_backend.ensure_medium_avatar_image(user_profile)
        medium_image_key = bucket.get_key(medium_path_id)
        self.assertEqual(medium_image_key.key, medium_path_id)
示例#4
0
 def test_multiple_upload_failure(self) -> None:
     """
     Attempting to upload two files should fail.
     """
     self.login(self.example_email("hamlet"))
     with get_test_image_file('img.png') as fp1, \
             get_test_image_file('img.png') as fp2:
         result = self.client_post("/json/users/me/avatar", {'f1': fp1, 'f2': fp2})
     self.assert_json_error(result, "You must upload exactly one avatar.")
示例#5
0
 def test_multiple_upload_failure(self) -> None:
     """
     Attempting to upload two files should fail.
     """
     # Log in as admin
     self.login(self.example_email("iago"))
     with get_test_image_file('img.png') as fp1, \
             get_test_image_file('img.png') as fp2:
         result = self.client_post("/json/realm/icon", {'f1': fp1, 'f2': fp2})
     self.assert_json_error(result, "You must upload exactly one icon.")
示例#6
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)
示例#7
0
 def test_add_bot_with_too_many_files(self) -> None:
     self.login(self.example_email('hamlet'))
     self.assert_num_bots_equal(0)
     with get_test_image_file('img.png') as fp1, \
             get_test_image_file('img.gif') as fp2:
         bot_info = dict(
             full_name='whatever',
             short_name='whatever',
             file1=fp1,
             file2=fp2,
         )
         result = self.client_post("/json/bots", bot_info)
     self.assert_json_error(result, 'You may only upload one file at a time')
     self.assert_num_bots_equal(0)
示例#8
0
 def test_realm_icon_upload_file_size_error(self):
     # type: () -> None
     self.login(self.example_email("iago"))
     with get_test_image_file(self.correct_files[0][0]) as fp:
         with self.settings(MAX_ICON_FILE_SIZE=0):
             result = self.client_post("/json/realm/icon", {'file': fp})
     self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MB")
示例#9
0
 def test_avatar_upload_file_size_error(self):
     # type: () -> None
     self.login(self.example_email("hamlet"))
     with get_test_image_file(self.correct_files[0][0]) as fp:
         with self.settings(MAX_AVATAR_FILE_SIZE=0):
             result = self.client_post("/json/users/me/avatar", {'file': fp})
     self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MB")
示例#10
0
 def test_emoji_upload_by_guest_user(self) -> None:
     email = self.example_email('polonius')
     self.login(email)
     with get_test_image_file('img.png') as fp1:
         emoji_data = {'f1': fp1}
         result = self.client_post('/json/realm/emoji/my_emoji', info=emoji_data)
     self.assert_json_error(result, 'Not allowed for guest users')
示例#11
0
    def test_transfer_emoji_to_s3(self) -> None:
        bucket = create_s3_buckets(settings.S3_AVATAR_BUCKET)[0]
        othello = self.example_user('othello')
        RealmEmoji.objects.all().delete()

        emoji_name = "emoji.png"
        image_file = get_test_image_file("img.png")

        emoji = check_add_realm_emoji(othello.realm, emoji_name, othello, image_file)
        if not emoji:
            raise AssertionError("Unable to add emoji.")

        emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format(
            realm_id=othello.realm_id,
            emoji_file_name=emoji.file_name,
        )

        transfer_emoji_to_s3(1)

        self.assertEqual(len(bucket.get_all_keys()), 2)
        original_key = bucket.get_key(emoji_path + ".original")
        resized_key = bucket.get_key(emoji_path)

        image_file.seek(0)
        image_data = image_file.read()
        resized_image_data = resize_emoji(image_data)

        self.assertEqual(image_data, original_key.get_contents_as_string())
        self.assertEqual(resized_image_data, resized_key.get_contents_as_string())
示例#12
0
 def test_emoji_upload_file_size_error(self) -> None:
     email = self.example_email('iago')
     self.login(email)
     with get_test_image_file('img.png') as fp:
         with self.settings(MAX_EMOJI_FILE_SIZE=0):
             result = self.client_post('/json/realm/emoji/my_emoji', {'file': fp})
     self.assert_json_error(result, 'Uploaded file is larger than the allowed limit of 0 MB')
示例#13
0
 def test_upload_already_existed_emoji(self) -> None:
     email = self.example_email('iago')
     self.login(email)
     with get_test_image_file('img.png') as fp1:
         emoji_data = {'f1': fp1}
         result = self.client_post('/json/realm/emoji/green_tick', info=emoji_data)
     self.assert_json_error(result, 'Realm emoji with this Realm and Name already exists.')
示例#14
0
    def test_upload(self) -> None:
        email = self.example_email('iago')
        self.login(email)
        with get_test_image_file('img.png') as fp1:
            emoji_data = {'f1': fp1}
            result = self.client_post('/json/realm/emoji/my_emoji', info=emoji_data)
        self.assert_json_success(result)
        self.assertEqual(200, result.status_code)
        emoji = RealmEmoji.objects.get(name="my_emoji")
        self.assertEqual(emoji.author.email, email)

        result = self.client_get("/json/realm/emoji")
        content = result.json()
        self.assert_json_success(result)
        self.assertEqual(len(content["emoji"]), 2)
        self.assertIn('author', content["emoji"]['my_emoji'])
        self.assertEqual(
            content["emoji"]['my_emoji']['author']['email'], email)

        realm_emoji = RealmEmoji.objects.get(name='my_emoji')
        file_name = realm_emoji.name + '.png'
        self.assertEqual(
            str(realm_emoji),
            '<RealmEmoji(zulip): %s my_emoji False %s>' % (realm_emoji.id, file_name)
        )
示例#15
0
 def test_upload_uppercase_exception(self) -> None:
     email = self.example_email('iago')
     self.login(email)
     with get_test_image_file('img.png') as fp1:
         emoji_data = {'f1': fp1}
         result = self.client_post('/json/realm/emoji/my_EMoji', info=emoji_data)
     self.assert_json_error(result, 'Invalid characters in emoji name')
示例#16
0
 def test_failed_file_upload(self) -> None:
     email = self.example_email('iago')
     self.login(email)
     with mock.patch('zerver.lib.upload.write_local_file', side_effect=Exception()):
         with get_test_image_file('img.png') as fp1:
             emoji_data = {'f1': fp1}
             result = self.client_post('/json/realm/emoji/my_emoji', info=emoji_data)
     self.assert_json_error(result, "Image file upload failed.")
示例#17
0
    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)
示例#18
0
 def test_realm_icon_version(self) -> None:
     self.login(self.example_email("iago"))
     realm = get_realm('zulip')
     icon_version = realm.icon_version
     self.assertEqual(icon_version, 1)
     with get_test_image_file(self.correct_files[0][0]) as fp:
         self.client_post("/json/realm/icon", {'file': fp})
     realm = get_realm('zulip')
     self.assertEqual(realm.icon_version, icon_version + 1)
示例#19
0
 def create_test_emoji(self, name: str, author: UserProfile) -> RealmEmoji:
     with get_test_image_file('img.png') as img_file:
         realm_emoji = check_add_realm_emoji(realm=author.realm,
                                             name=name,
                                             author=author,
                                             image_file=img_file)
         if realm_emoji is None:
             raise Exception("Error creating test emoji.")   # nocoverage
     return realm_emoji
示例#20
0
 def test_upload_anyone(self) -> None:
     email = self.example_email('othello')
     self.login(email)
     realm = get_realm('zulip')
     realm.add_emoji_by_admins_only = False
     realm.save()
     with get_test_image_file('img.png') as fp1:
         emoji_data = {'f1': fp1}
         result = self.client_post('/json/realm/emoji/my_emoji', info=emoji_data)
     self.assert_json_success(result)
示例#21
0
 def test_upload_admins_only(self) -> None:
     email = self.example_email('othello')
     self.login(email)
     realm = get_realm('zulip')
     realm.add_emoji_by_admins_only = True
     realm.save()
     with get_test_image_file('img.png') as fp1:
         emoji_data = {'f1': fp1}
         result = self.client_post('/json/realm/emoji/my_emoji', info=emoji_data)
     self.assert_json_error(result, 'Must be an organization administrator')
示例#22
0
    def test_invalid_icons(self) -> None:
        """
        A PUT request to /json/realm/icon with an invalid file should fail.
        """
        for fname in self.corrupt_files:
            # with self.subTest(fname=fname):
            self.login(self.example_email("iago"))
            with get_test_image_file(fname) as fp:
                result = self.client_post("/json/realm/icon", {'file': fp})

            self.assert_json_error(result, "Could not decode image; did you upload an image file?")
示例#23
0
    def test_reupload(self) -> None:
        # An user should be able to reupload an emoji with same name.
        email = self.example_email('iago')
        self.login(email)
        with get_test_image_file('img.png') as fp1:
            emoji_data = {'f1': fp1}
            result = self.client_post('/json/realm/emoji/my_emoji', info=emoji_data)
        self.assert_json_success(result)

        result = self.client_delete("/json/realm/emoji/my_emoji")
        self.assert_json_success(result)

        with get_test_image_file('img.png') as fp1:
            emoji_data = {'f1': fp1}
            result = self.client_post('/json/realm/emoji/my_emoji', info=emoji_data)
        self.assert_json_success(result)

        result = self.client_get("/json/realm/emoji")
        emojis = result.json()["emoji"]
        self.assert_json_success(result)
        self.assertEqual(len(emojis), 3)
示例#24
0
    def test_patch_bot_avatar(self) -> None:
        self.login(self.example_email('hamlet'))
        bot_info = {
            'full_name': 'The Bot of Hamlet',
            'short_name': 'hambot',
        }
        result = self.client_post("/json/bots", bot_info)
        self.assert_json_success(result)

        bot_email = '*****@*****.**'
        bot_realm = get_realm('zulip')
        profile = get_user(bot_email, bot_realm)
        self.assertEqual(profile.avatar_source, UserProfile.AVATAR_FROM_GRAVATAR)

        # Try error case first (too many files):
        with get_test_image_file('img.png') as fp1, \
                get_test_image_file('img.gif') as fp2:
            result = self.client_patch_multipart(
                '/json/bots/[email protected]',
                dict(file1=fp1, file2=fp2))
        self.assert_json_error(result, 'You may only upload one file at a time')

        profile = get_user(bot_email, bot_realm)
        self.assertEqual(profile.avatar_version, 1)

        # HAPPY PATH
        with get_test_image_file('img.png') as fp:
            result = self.client_patch_multipart(
                '/json/bots/[email protected]',
                dict(file=fp))
            profile = get_user(bot_email, bot_realm)
            self.assertEqual(profile.avatar_version, 2)
            # Make sure that avatar image that we've uploaded is same with avatar image in the server
            self.assertTrue(filecmp.cmp(fp.name,
                                        os.path.splitext(avatar_disk_path(profile))[0] +
                                        ".original"))
        self.assert_json_success(result)

        self.assertEqual(profile.avatar_source, UserProfile.AVATAR_FROM_USER)
        self.assertTrue(os.path.exists(avatar_disk_path(profile)))
示例#25
0
    def test_invalid_avatars(self) -> None:
        """
        A PUT request to /json/users/me/avatar with an invalid file should fail.
        """
        for fname in self.corrupt_files:
            # with self.subTest(fname=fname):
            self.login(self.example_email("hamlet"))
            with get_test_image_file(fname) as fp:
                result = self.client_post("/json/users/me/avatar", {'file': fp})

            self.assert_json_error(result, "Could not decode image; did you upload an image file?")
            user_profile = self.example_user('hamlet')
            self.assertEqual(user_profile.avatar_version, 1)
示例#26
0
    def test_invalid_icons(self):
        # type: () -> None
        """
        A PUT request to /json/realm/icon with an invalid file should fail.
        """
        for fname in self.corrupt_files:
            # with self.subTest(fname=fname):
            self.login(self.example_email("iago"))
            with get_test_image_file(fname) as fp:
                result = self.client_post("/json/realm/icon", {'file': fp})

            self.assert_json_error(
                result,
                "Could not decode image; did you upload an image file?")
示例#27
0
    def test_reupload(self) -> None:
        # An user should be able to reupload an emoji with same name.
        email = self.example_email('iago')
        self.login(email)
        with get_test_image_file('img.png') as fp1:
            emoji_data = {'f1': fp1}
            result = self.client_post('/json/realm/emoji/my_emoji',
                                      info=emoji_data)
        self.assert_json_success(result)

        result = self.client_delete("/json/realm/emoji/my_emoji")
        self.assert_json_success(result)

        with get_test_image_file('img.png') as fp1:
            emoji_data = {'f1': fp1}
            result = self.client_post('/json/realm/emoji/my_emoji',
                                      info=emoji_data)
        self.assert_json_success(result)

        result = self.client_get("/json/realm/emoji")
        emojis = result.json()["emoji"]
        self.assert_json_success(result)
        self.assertEqual(len(emojis), 3)
示例#28
0
    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)
示例#29
0
    def test_invalid_avatars(self):
        # type: () -> None
        """
        A PUT request to /json/users/me/avatar with an invalid file should fail.
        """
        for fname in self.corrupt_files:
            # with self.subTest(fname=fname):
            self.login(self.example_email("hamlet"))
            with get_test_image_file(fname) as fp:
                result = self.client_post("/json/users/me/avatar", {'file': fp})

            self.assert_json_error(result, "Could not decode image; did you upload an image file?")
            user_profile = self.example_user('hamlet')
            self.assertEqual(user_profile.avatar_version, 1)
示例#30
0
    def test_avatar_changes_disabled(self) -> None:
        self.login("hamlet")

        with self.settings(AVATAR_CHANGES_DISABLED=True):
            result = self.client_delete("/json/users/me/avatar")
            self.assert_json_error(
                result, "Avatar changes are disabled in this organization.",
                400)

        with self.settings(AVATAR_CHANGES_DISABLED=True):
            with get_test_image_file("img.png") as fp1:
                result = self.client_post("/json/users/me/avatar", {"f1": fp1})
            self.assert_json_error(
                result, "Avatar changes are disabled in this organization.",
                400)
示例#31
0
    def test_add_bot_with_user_avatar(self) -> None:
        email = '*****@*****.**'
        realm = get_realm('zulip')
        self.login(self.example_email('hamlet'))
        self.assert_num_bots_equal(0)
        with get_test_image_file('img.png') as fp:
            self.create_bot(file=fp)
            profile = get_user(email, realm)
            # Make sure that avatar image that we've uploaded is same with avatar image in the server
            self.assertTrue(filecmp.cmp(fp.name,
                                        os.path.splitext(avatar_disk_path(profile))[0] +
                                        ".original"))
        self.assert_num_bots_equal(1)

        self.assertEqual(profile.avatar_source, UserProfile.AVATAR_FROM_USER)
        self.assertTrue(os.path.exists(avatar_disk_path(profile)))
示例#32
0
    def test_add_bot_with_user_avatar(self) -> None:
        email = '*****@*****.**'
        realm = get_realm('zulip')
        self.login(self.example_email('hamlet'))
        self.assert_num_bots_equal(0)
        with get_test_image_file('img.png') as fp:
            self.create_bot(file=fp)
            profile = get_user(email, realm)
            # Make sure that avatar image that we've uploaded is same with avatar image in the server
            self.assertTrue(filecmp.cmp(fp.name,
                                        os.path.splitext(avatar_disk_path(profile))[0] +
                                        ".original"))
        self.assert_num_bots_equal(1)

        self.assertEqual(profile.avatar_source, UserProfile.AVATAR_FROM_USER)
        self.assertTrue(os.path.exists(avatar_disk_path(profile)))
示例#33
0
    def test_avatar_changes_disabled(self) -> None:
        user = self.example_user('hamlet')
        email = user.email
        self.login(email)

        with self.settings(AVATAR_CHANGES_DISABLED=True):
            result = self.client_delete("/json/users/me/avatar")
            self.assert_json_error(
                result, "Avatar changes are disabled in this organization.",
                400)

        with self.settings(AVATAR_CHANGES_DISABLED=True):
            with get_test_image_file('img.png') as fp1:
                result = self.client_post("/json/users/me/avatar", {'f1': fp1})
            self.assert_json_error(
                result, "Avatar changes are disabled in this organization.",
                400)
示例#34
0
    def test_upload(self) -> None:
        email = self.example_email('iago')
        self.login(email)
        with get_test_image_file('img.png') as fp1:
            emoji_data = {'f1': fp1}
            result = self.client_post('/json/realm/emoji/my_emoji', info=emoji_data)
        self.assert_json_success(result)
        self.assertEqual(200, result.status_code)
        realm_emoji = RealmEmoji.objects.get(name="my_emoji")
        self.assertEqual(realm_emoji.author.email, email)

        result = self.client_get("/json/realm/emoji")
        content = result.json()
        self.assert_json_success(result)
        self.assertEqual(len(content["emoji"]), 2)
        test_emoji = content["emoji"][str(realm_emoji.id)]
        self.assertIn('author', test_emoji)
        self.assertEqual(test_emoji['author']['email'], email)
示例#35
0
    def test_import_files_from_s3(self) -> None:
        uploads_bucket, avatar_bucket = create_s3_buckets(
            settings.S3_AUTH_UPLOADS_BUCKET, settings.S3_AVATAR_BUCKET)

        realm = Realm.objects.get(string_id='zulip')
        self._setup_export_files()
        self._export_realm(realm)
        with patch('logging.info'):
            do_import_realm(
                os.path.join(settings.TEST_WORKER_DIR, 'test-export'),
                'test-zulip')
        imported_realm = Realm.objects.get(string_id='test-zulip')
        with open(get_test_image_file('img.png').name, 'rb') as f:
            test_image_data = f.read()

        # Test attachments
        uploaded_file = Attachment.objects.get(realm=imported_realm)
        self.assertEqual(len(b'zulip!'), uploaded_file.size)

        attachment_content = uploads_bucket.get_key(
            uploaded_file.path_id).get_contents_as_string()
        self.assertEqual(b"zulip!", attachment_content)

        # Test emojis
        realm_emoji = RealmEmoji.objects.get(realm=imported_realm)
        emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format(
            realm_id=imported_realm.id,
            emoji_file_name=realm_emoji.file_name,
        )
        emoji_key = avatar_bucket.get_key(emoji_path)
        self.assertIsNotNone(emoji_key)
        self.assertEqual(emoji_key.key, emoji_path)

        # Test avatars
        user_email = Message.objects.all()[0].sender.email
        user_profile = UserProfile.objects.get(email=user_email,
                                               realm=imported_realm)
        avatar_path_id = user_avatar_path(user_profile) + ".original"
        original_image_key = avatar_bucket.get_key(avatar_path_id)
        self.assertEqual(original_image_key.key, avatar_path_id)
        image_data = original_image_key.get_contents_as_string()
        self.assertEqual(image_data, test_image_data)
示例#36
0
    def test_valid_avatars(self):
        # type: () -> None
        """
        A PUT request to /json/users/me/avatar with a valid file should return a url and actually create an avatar.
        """
        version = 2
        for fname, rfname in self.correct_files:
            # TODO: use self.subTest once we're exclusively on python 3 by uncommenting the line below.
            # with self.subTest(fname=fname):
            self.login(self.example_email("hamlet"))
            with get_test_image_file(fname) as fp:
                result = self.client_post("/json/users/me/avatar",
                                          {'file': fp})

            self.assert_json_success(result)
            self.assertIn("avatar_url", result.json())
            base = '/user_avatars/'
            url = result.json()['avatar_url']
            self.assertEqual(base, url[:len(base)])

            if rfname is not None:
                response = self.client_get(url)
                data = b"".join(response.streaming_content)
                self.assertEqual(Image.open(io.BytesIO(data)).size, (100, 100))

            # Verify that the medium-size avatar was created
            user_profile = self.example_user('hamlet')
            medium_avatar_disk_path = avatar_disk_path(user_profile,
                                                       medium=True)
            self.assertTrue(os.path.exists(medium_avatar_disk_path))

            # Confirm that ensure_medium_avatar_url works to recreate
            # medium size avatars from the original if needed
            os.remove(medium_avatar_disk_path)
            self.assertFalse(os.path.exists(medium_avatar_disk_path))
            zerver.lib.upload.upload_backend.ensure_medium_avatar_image(
                user_profile)
            self.assertTrue(os.path.exists(medium_avatar_disk_path))

            # Verify whether the avatar_version gets incremented with every new upload
            self.assertEqual(user_profile.avatar_version, version)
            version += 1
示例#37
0
    def test_transfer_avatars_to_s3(self) -> None:
        bucket = create_s3_buckets(settings.S3_AVATAR_BUCKET)[0]

        self.login('hamlet')
        with get_test_image_file('img.png') as image_file:
            self.client_post("/json/users/me/avatar", {'file': image_file})

        user = self.example_user("hamlet")

        transfer_avatars_to_s3(1)

        path_id = user_avatar_path(user)
        image_key = bucket.get_key(path_id)
        original_image_key = bucket.get_key(path_id + ".original")
        medium_image_key = bucket.get_key(path_id + "-medium.png")

        self.assertEqual(len(bucket.get_all_keys()), 3)
        self.assertEqual(image_key.get_contents_as_string(), open(avatar_disk_path(user), "rb").read())
        self.assertEqual(original_image_key.get_contents_as_string(), open(avatar_disk_path(user, original=True), "rb").read())
        self.assertEqual(medium_image_key.get_contents_as_string(), open(avatar_disk_path(user, medium=True), "rb").read())
示例#38
0
    def test_transfer_avatars_to_s3(self) -> None:
        bucket = create_s3_buckets(settings.S3_AVATAR_BUCKET)[0]

        self.login(self.example_email("hamlet"))
        with get_test_image_file('img.png') as image_file:
            self.client_post("/json/users/me/avatar", {'file': image_file})

        user = self.example_user("hamlet")

        transfer_avatars_to_s3(1)

        path_id = user_avatar_path(user)
        image_key = bucket.get_key(path_id)
        original_image_key = bucket.get_key(path_id + ".original")
        medium_image_key = bucket.get_key(path_id + "-medium.png")

        self.assertEqual(len(bucket.get_all_keys()), 3)
        self.assertEqual(image_key.get_contents_as_string(), open(avatar_disk_path(user), "rb").read())
        self.assertEqual(original_image_key.get_contents_as_string(), open(avatar_disk_path(user, original=True), "rb").read())
        self.assertEqual(medium_image_key.get_contents_as_string(), open(avatar_disk_path(user, medium=True), "rb").read())
示例#39
0
    def test_upload(self) -> None:
        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/my_emoji", info=emoji_data)
        self.assert_json_success(result)
        self.assertEqual(200, result.status_code)
        realm_emoji = RealmEmoji.objects.get(name="my_emoji")
        self.assertEqual(realm_emoji.author.email, email)

        result = self.client_get("/json/realm/emoji")
        content = result.json()
        self.assert_json_success(result)
        self.assert_length(content["emoji"], 2)
        test_emoji = content["emoji"][str(realm_emoji.id)]
        self.assertIn("author_id", test_emoji)
        author = UserProfile.objects.get(id=test_emoji["author_id"])
        self.assertEqual(author.email, email)
示例#40
0
    def test_valid_avatars(self):
        # type: () -> None
        """
        A PUT request to /json/users/me/avatar with a valid file should return a url and actually create an avatar.
        """
        version = 2
        for fname, rfname in self.correct_files:
            # TODO: use self.subTest once we're exclusively on python 3 by uncommenting the line below.
            # with self.subTest(fname=fname):
            self.login(self.example_email("hamlet"))
            with get_test_image_file(fname) as fp:
                result = self.client_post("/json/users/me/avatar", {'file': fp})

            self.assert_json_success(result)
            self.assertIn("avatar_url", result.json())
            base = '/user_avatars/'
            url = result.json()['avatar_url']
            self.assertEqual(base, url[:len(base)])

            if rfname is not None:
                response = self.client_get(url)
                data = b"".join(response.streaming_content)
                self.assertEqual(Image.open(io.BytesIO(data)).size, (100, 100))

            # Verify that the medium-size avatar was created
            user_profile = self.example_user('hamlet')
            medium_avatar_disk_path = avatar_disk_path(user_profile, medium=True)
            self.assertTrue(os.path.exists(medium_avatar_disk_path))

            # Confirm that ensure_medium_avatar_url works to recreate
            # medium size avatars from the original if needed
            os.remove(medium_avatar_disk_path)
            self.assertFalse(os.path.exists(medium_avatar_disk_path))
            zerver.lib.upload.upload_backend.ensure_medium_avatar_image(user_profile)
            self.assertTrue(os.path.exists(medium_avatar_disk_path))

            # Verify whether the avatar_version gets incremented with every new upload
            self.assertEqual(user_profile.avatar_version, version)
            version += 1
示例#41
0
    def test_valid_icons(self) -> None:
        """
        A PUT request to /json/realm/icon with a valid file should return a url
        and actually create an realm icon.
        """
        for fname, rfname in self.correct_files:
            # TODO: use self.subTest once we're exclusively on python 3 by uncommenting the line below.
            # with self.subTest(fname=fname):
            self.login(self.example_email("iago"))
            with get_test_image_file(fname) as fp:
                result = self.client_post("/json/realm/icon", {'file': fp})
            realm = get_realm('zulip')
            self.assert_json_success(result)
            self.assertIn("icon_url", result.json())
            base = '/user_avatars/%s/realm/icon.png' % (realm.id, )
            url = result.json()['icon_url']
            self.assertEqual(base, url[:len(base)])

            if rfname is not None:
                response = self.client_get(url)
                data = b"".join(response.streaming_content)
                self.assertEqual(Image.open(io.BytesIO(data)).size, (100, 100))
示例#42
0
    def test_valid_icons(self) -> None:
        """
        A PUT request to /json/realm/icon with a valid file should return a url
        and actually create an realm icon.
        """
        for fname, rfname in self.correct_files:
            # TODO: use self.subTest once we're exclusively on python 3 by uncommenting the line below.
            # with self.subTest(fname=fname):
            self.login(self.example_email("iago"))
            with get_test_image_file(fname) as fp:
                result = self.client_post("/json/realm/icon", {'file': fp})
            realm = get_realm('zulip')
            self.assert_json_success(result)
            self.assertIn("icon_url", result.json())
            base = '/user_avatars/%s/realm/icon.png' % (realm.id,)
            url = result.json()['icon_url']
            self.assertEqual(base, url[:len(base)])

            if rfname is not None:
                response = self.client_get(url)
                data = b"".join(response.streaming_content)
                self.assertEqual(Image.open(io.BytesIO(data)).size, (100, 100))
示例#43
0
    def test_transfer_avatars_to_s3(self) -> None:
        bucket = create_s3_buckets(settings.S3_AVATAR_BUCKET)[0]

        self.login("hamlet")
        with get_test_image_file("img.png") as image_file:
            self.client_post("/json/users/me/avatar", {"file": image_file})

        user = self.example_user("hamlet")

        with self.assertLogs(level="INFO"):
            transfer_avatars_to_s3(1)

        path_id = user_avatar_path(user)
        image_key = bucket.Object(path_id)
        original_image_key = bucket.Object(path_id + ".original")
        medium_image_key = bucket.Object(path_id + "-medium.png")

        self.assert_length(list(bucket.objects.all()), 3)
        with open(avatar_disk_path(user), "rb") as f:
            self.assertEqual(image_key.get()["Body"].read(), f.read())
        with open(avatar_disk_path(user, original=True), "rb") as f:
            self.assertEqual(original_image_key.get()["Body"].read(), f.read())
        with open(avatar_disk_path(user, medium=True), "rb") as f:
            self.assertEqual(medium_image_key.get()["Body"].read(), f.read())
示例#44
0
 def test_upload_already_existed_emoji(self) -> None:
     self.login('iago')
     with get_test_image_file('img.png') as fp1:
         emoji_data = {'f1': fp1}
         result = self.client_post('/json/realm/emoji/green_tick', info=emoji_data)
     self.assert_json_error(result, 'A custom emoji with this name already exists.')
示例#45
0
 def test_upload_uppercase_exception(self) -> None:
     self.login('iago')
     with get_test_image_file('img.png') as fp1:
         emoji_data = {'f1': fp1}
         result = self.client_post('/json/realm/emoji/my_EMoji', info=emoji_data)
     self.assert_json_error(result, 'Invalid characters in emoji name')
示例#46
0
    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)
示例#47
0
 def test_avatar_upload_file_size_error(self) -> None:
     self.login(self.example_email("hamlet"))
     with get_test_image_file(self.correct_files[0][0]) as fp:
         with self.settings(MAX_AVATAR_FILE_SIZE=0):
             result = self.client_post("/json/users/me/avatar", {'file': fp})
     self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MB")
示例#48
0
 def test_multiple_upload(self) -> None:
     email = self.example_email('iago')
     self.login(email)
     with get_test_image_file('img.png') as fp1, get_test_image_file('img.png') as fp2:
         result = self.client_post('/json/realm/emoji/my_emoji', {'f1': fp1, 'f2': fp2})
     self.assert_json_error(result, 'You must upload exactly one file.')
示例#49
0
 def test_no_admin_user_upload(self) -> None:
     self.login(self.example_email("hamlet"))
     with get_test_image_file(self.correct_files[0][0]) as fp:
         result = self.client_post("/json/realm/icon", {'file': fp})
     self.assert_json_error(result, 'Must be a realm administrator')
示例#50
0
 def test_emoji_upload_resize_success(self) -> None:
     self.login("iago")
     with get_test_image_file("still_large_img.gif") as fp:
         result = self.client_post("/json/realm/emoji/my_emoji",
                                   {"file": fp})
     self.assert_json_success(result)
示例#51
0
    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)
示例#52
0
    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)
示例#53
0
 def test_missing_name_exception(self) -> None:
     self.login("iago")
     with get_test_image_file("img.png") as fp1:
         emoji_data = {"f1": fp1}
         result = self.client_post("/json/realm/emoji/%20", info=emoji_data)
     self.assert_json_error(result, "Emoji name is missing")
示例#54
0
    def test_transfer_emoji_to_s3(self) -> None:
        bucket = create_s3_buckets(settings.S3_AVATAR_BUCKET)[0]
        othello = self.example_user("othello")
        RealmEmoji.objects.all().delete()

        emoji_name = "emoji.png"

        with get_test_image_file("img.png") as image_file:
            emoji = check_add_realm_emoji(othello.realm, emoji_name, othello, image_file)
        if not emoji:
            raise AssertionError("Unable to add emoji.")

        emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format(
            realm_id=othello.realm_id,
            emoji_file_name=emoji.file_name,
        )

        with self.assertLogs(level="INFO"):
            transfer_emoji_to_s3(1)

        self.assert_length(list(bucket.objects.all()), 2)
        original_key = bucket.Object(emoji_path + ".original")
        resized_key = bucket.Object(emoji_path)

        image_data = read_test_image_file("img.png")
        resized_image_data, is_animated, still_image_data = resize_emoji(image_data)

        self.assertEqual(is_animated, False)
        self.assertEqual(still_image_data, None)
        self.assertEqual(image_data, original_key.get()["Body"].read())
        self.assertEqual(resized_image_data, resized_key.get()["Body"].read())

        emoji_name = "emoji2.png"

        with get_test_image_file("animated_img.gif") as image_file:
            emoji = check_add_realm_emoji(othello.realm, emoji_name, othello, image_file)
        if not emoji:
            raise AssertionError("Unable to add emoji.")

        emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format(
            realm_id=othello.realm_id,
            emoji_file_name=emoji.file_name,
        )

        with self.assertLogs(level="INFO"):
            transfer_emoji_to_s3(1)

        self.assert_length(list(bucket.objects.all()), 5)
        original_key = bucket.Object(emoji_path + ".original")
        resized_key = bucket.Object(emoji_path)
        assert emoji.file_name
        still_key = bucket.Object(
            RealmEmoji.STILL_PATH_ID_TEMPLATE.format(
                realm_id=othello.realm_id,
                emoji_filename_without_extension=os.path.splitext(emoji.file_name)[0],
            )
        )

        image_data = read_test_image_file("animated_img.gif")
        resized_image_data, is_animated, still_image_data = resize_emoji(image_data)

        self.assertEqual(is_animated, True)
        self.assertEqual(type(still_image_data), bytes)
        self.assertEqual(image_data, original_key.get()["Body"].read())
        self.assertEqual(resized_image_data, resized_key.get()["Body"].read())
        self.assertEqual(still_image_data, still_key.get()["Body"].read())
示例#55
0
    def test_slack_import_to_existing_database(
            self, mock_get_slack_api_data: mock.Mock,
            mock_build_avatar_url: mock.Mock, mock_build_avatar: mock.Mock,
            mock_process_uploads: mock.Mock, mock_attachment: mock.Mock,
            mock_requests_get: mock.Mock) -> None:
        test_slack_dir = os.path.join(settings.DEPLOY_ROOT, "zerver", "tests",
                                      "fixtures", "slack_fixtures")
        test_slack_zip_file = os.path.join(test_slack_dir,
                                           "test_slack_importer.zip")
        test_slack_unzipped_file = os.path.join(test_slack_dir,
                                                "test_slack_importer")

        test_realm_subdomain = 'test-slack-import'
        output_dir = os.path.join(settings.DEPLOY_ROOT, "var",
                                  "test-slack-importer-data")
        token = 'valid-token'

        # If the test fails, the 'output_dir' would not be deleted and hence it would give an
        # error when we run the tests next time, as 'do_convert_data' expects an empty 'output_dir'
        # hence we remove it before running 'do_convert_data'
        self.rm_tree(output_dir)
        # Also the unzipped data file should be removed if the test fails at 'do_convert_data'
        self.rm_tree(test_slack_unzipped_file)

        user_data_fixture = ujson.loads(
            self.fixture_data('user_data.json', type='slack_fixtures'))
        team_info_fixture = ujson.loads(
            self.fixture_data('team_info.json', type='slack_fixtures'))
        mock_get_slack_api_data.side_effect = [
            user_data_fixture['members'], {}, team_info_fixture["team"]
        ]
        mock_requests_get.return_value.raw = get_test_image_file("img.png")

        do_convert_data(test_slack_zip_file, output_dir, token)
        self.assertTrue(os.path.exists(output_dir))
        self.assertTrue(os.path.exists(output_dir + '/realm.json'))

        realm_icons_path = os.path.join(output_dir, 'realm_icons')
        realm_icon_records_path = os.path.join(realm_icons_path,
                                               'records.json')

        self.assertTrue(os.path.exists(realm_icon_records_path))
        with open(realm_icon_records_path) as f:
            records = ujson.load(f)
            self.assertEqual(len(records), 2)
            self.assertEqual(records[0]["path"], "0/icon.original")
            self.assertTrue(
                os.path.exists(
                    os.path.join(realm_icons_path, records[0]["path"])))

            self.assertEqual(records[1]["path"], "0/icon.png")
            self.assertTrue(
                os.path.exists(
                    os.path.join(realm_icons_path, records[1]["path"])))

        # test import of the converted slack data into an existing database
        with self.settings(BILLING_ENABLED=False):
            do_import_realm(output_dir, test_realm_subdomain)
        realm = get_realm(test_realm_subdomain)
        self.assertTrue(realm.name, test_realm_subdomain)
        self.assertEqual(realm.icon_source, Realm.ICON_UPLOADED)

        # test RealmAuditLog
        realmauditlog = RealmAuditLog.objects.filter(realm=realm)
        realmauditlog_event_type = {log.event_type for log in realmauditlog}
        self.assertEqual(
            realmauditlog_event_type, {
                RealmAuditLog.SUBSCRIPTION_CREATED,
                RealmAuditLog.REALM_PLAN_TYPE_CHANGED
            })

        Realm.objects.filter(name=test_realm_subdomain).delete()

        remove_folder(output_dir)
        # remove tar file created in 'do_convert_data' function
        os.remove(output_dir + '.tar.gz')
        self.assertFalse(os.path.exists(output_dir))
示例#56
0
    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)
示例#57
0
    def test_user_settings_for_adding_custom_emoji(self) -> None:
        othello = self.example_user("othello")
        self.login_user(othello)

        do_change_user_role(othello,
                            UserProfile.ROLE_MODERATOR,
                            acting_user=None)
        do_set_realm_property(othello.realm,
                              "add_custom_emoji_policy",
                              Realm.POLICY_ADMINS_ONLY,
                              acting_user=None)
        with get_test_image_file("img.png") as fp1:
            emoji_data = {"f1": fp1}
            result = self.client_post("/json/realm/emoji/my_emoji_1",
                                      info=emoji_data)
        self.assert_json_error(result, "Insufficient permission")

        do_change_user_role(othello,
                            UserProfile.ROLE_REALM_ADMINISTRATOR,
                            acting_user=None)
        with get_test_image_file("img.png") as fp1:
            emoji_data = {"f1": fp1}
            result = self.client_post("/json/realm/emoji/my_emoji_1",
                                      info=emoji_data)
        self.assert_json_success(result)

        do_set_realm_property(othello.realm,
                              "add_custom_emoji_policy",
                              Realm.POLICY_MODERATORS_ONLY,
                              acting_user=None)
        do_change_user_role(othello, UserProfile.ROLE_MEMBER, acting_user=None)
        with get_test_image_file("img.png") as fp1:
            emoji_data = {"f1": fp1}
            result = self.client_post("/json/realm/emoji/my_emoji_2",
                                      info=emoji_data)
        self.assert_json_error(result, "Insufficient permission")

        do_change_user_role(othello,
                            UserProfile.ROLE_MODERATOR,
                            acting_user=None)
        with get_test_image_file("img.png") as fp1:
            emoji_data = {"f1": fp1}
            result = self.client_post("/json/realm/emoji/my_emoji_2",
                                      info=emoji_data)
        self.assert_json_success(result)

        do_set_realm_property(
            othello.realm,
            "add_custom_emoji_policy",
            Realm.POLICY_FULL_MEMBERS_ONLY,
            acting_user=None,
        )
        do_set_realm_property(othello.realm,
                              "waiting_period_threshold",
                              100000,
                              acting_user=None)
        do_change_user_role(othello, UserProfile.ROLE_MEMBER, acting_user=None)

        with get_test_image_file("img.png") as fp1:
            emoji_data = {"f1": fp1}
            result = self.client_post("/json/realm/emoji/my_emoji_3",
                                      info=emoji_data)
        self.assert_json_error(result, "Insufficient permission")

        do_set_realm_property(othello.realm,
                              "waiting_period_threshold",
                              0,
                              acting_user=None)
        with get_test_image_file("img.png") as fp1:
            emoji_data = {"f1": fp1}
            result = self.client_post("/json/realm/emoji/my_emoji_3",
                                      info=emoji_data)
        self.assert_json_success(result)

        do_set_realm_property(othello.realm,
                              "add_custom_emoji_policy",
                              Realm.POLICY_MEMBERS_ONLY,
                              acting_user=None)
        do_change_user_role(othello, UserProfile.ROLE_GUEST, acting_user=None)
        with get_test_image_file("img.png") as fp1:
            emoji_data = {"f1": fp1}
            result = self.client_post("/json/realm/emoji/my_emoji_4",
                                      info=emoji_data)
        self.assert_json_error(result, "Not allowed for guest users")

        do_change_user_role(othello, UserProfile.ROLE_MEMBER, acting_user=None)
        with get_test_image_file("img.png") as fp1:
            emoji_data = {"f1": fp1}
            result = self.client_post("/json/realm/emoji/my_emoji_4",
                                      info=emoji_data)
        self.assert_json_success(result)
示例#58
0
 def test_realm_icon_upload_file_size_error(self) -> None:
     self.login(self.example_email("iago"))
     with get_test_image_file(self.correct_files[0][0]) as fp:
         with self.settings(MAX_ICON_FILE_SIZE=0):
             result = self.client_post("/json/realm/icon", {'file': fp})
     self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MB")
示例#59
0
 def test_missing_name_exception(self) -> None:
     self.login('iago')
     with get_test_image_file('img.png') as fp1:
         emoji_data = {'f1': fp1}
         result = self.client_post('/json/realm/emoji/', info=emoji_data)
     self.assert_json_error(result, 'Emoji name is missing')