Ejemplo n.º 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
Ejemplo n.º 2
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
Ejemplo n.º 3
0
    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])
Ejemplo n.º 4
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)
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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()
Ejemplo n.º 8
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)
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
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()
Ejemplo n.º 11
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)
Ejemplo n.º 12
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)
Ejemplo n.º 13
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)
Ejemplo n.º 14
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)
Ejemplo n.º 15
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)
Ejemplo n.º 16
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(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)