← Back to team overview

widelands-dev team mailing list archive

Re: [Merge] lp:~widelands-dev/widelands-website/pybb_attachments into lp:widelands-website

 

1 tiny nit.

I also wonder whether we should disallow map files - it might come in handy if somebody wants some feedback before publishing to the maps section.

Diff comments:

> 
> === modified file 'pybb/util.py'
> --- pybb/util.py	2019-04-11 15:20:33 +0000
> +++ pybb/util.py	2019-08-15 08:32:18 +0000
> @@ -173,3 +180,144 @@
>      text = text.replace('"', '"')
>      text = text.replace(''', '\'')
>      return text
> +
> +
> +def validate_file(attachment):
> +
> +    tmp_file_path = attachment.temporary_file_path()
> +
> +    # Helper functions
> +    def _split_mime(mime_type):
> +        main, sub = mime_type.split('/', maxsplit=1)
> +        return {'maintype': main, 'subtype': sub}
> +
> +    def _is_image():
> +        # Use PIL to determine if it is a valid image file
> +        # works not for corrupted jpg
> +        try:
> +            with Image.open(tmp_file_path) as im:
> +                im.verify()
> +        except:
> +            return False
> +        return True
> +
> +    def _is_zip():
> +        try:
> +            zip_obj = zipfile.ZipFile(tmp_file_path)
> +        except zipfile.BadZipfile:
> +            return None
> +        return zip_obj
> +
> +    def _zip_contains(zip_parts):
> +        # Check if each entry in zip_parts is inside the attachment
> +        zip_obj = _is_zip()
> +        if zip_obj:
> +            try:
> +                for obj in zip_parts:
> +                    zip_obj.getinfo(obj)
> +            except KeyError:
> +                return False
> +        return True
> +
> +
> +    # Main part of file checks
> +    # File size
> +    if attachment.size > pybb_settings.ATTACHMENT_SIZE_LIMIT:
> +        raise ValidationError(
> +            'Attachment is too big. We allow max %(size)s Mb',

Megabit or megabyte?

> +            params = {
> +                'size': pybb_settings.ATTACHMENT_SIZE_LIMIT/1024/1024,
> +            }
> +            )
> +
> +    # Checks by file extension
> +    splitted_fn = attachment.name.rsplit('.', maxsplit=2)
> +    if len(splitted_fn) == 1:
> +        raise ValidationError(
> +            'We do not allow uploading files without an extension.'
> +            )
> +
> +    ext = splitted_fn[-1]
> +    if not ext in settings.ALLOWED_EXTENSIONS:
> +        raise ValidationError(
> +            'This type of file is not allowed.'
> +            )
> +
> +    # Widelands map file
> +    if ext == 'wmf':
> +        raise ValidationError(
> +            'This seems to be a widelands map file. Please upload \
> +            it at our maps section.'
> +        )
> +
> +    # Widelands savegame (*.wgf) and widelands replay (*.wrpl.wgf)
> +    # are not the same.
> +    if ext == 'wgf' and not splitted_fn[-2] == 'wrpl':
> +        if not _zip_contains(settings.WGF_CONTENT_CHECK):
> +            raise ValidationError(
> +                'This is not a valid widelands savegame.'
> +            )
> +
> +    # Widelands replay
> +    if ext == 'wrpl':
> +        raise ValidationError(
> +            'This file is part of a replay. Please zip it together with \
> +            the corresponding .wrpl.wgf file and upload again.'
> +        )
> +
> +    if ext == 'zip':
> +        if _is_zip() == None:
> +            raise ValidationError(
> +                'This is not a valid zip file.'
> +            )
> +
> +    # Widelands AI configuration
> +    if ext == 'wai':
> +        wai = configparser.ConfigParser()
> +        try:
> +            wai.read(tmp_file_path)
> +            wai_sections = wai.sections()
> +            if len(settings.ALLOWED_WAI_SECTIONS) == len(wai_sections):
> +                for section in settings.ALLOWED_WAI_SECTIONS:
> +                    if section not in wai_sections:
> +                        raise
> +            else:
> +                raise
> +        except:
> +            raise ValidationError(
> +                'This not a valid wai file.'
> +                )
> +
> +    # Checks by MimeType
> +    # Get MIME-Type from python-magic
> +    magic_mime = magic.from_file(tmp_file_path, mime=True)
> +    magic_mime = _split_mime(magic_mime)
> +    send_mime = _split_mime(attachment.content_type)
> +
> +    # Check for valid image file. Use te mime-type provided by python-magic,
> +    # because for a renamed image the wrong mime-type is send by the browser.
> +    if magic_mime['maintype'] == 'image':
> +        if not _is_image():
> +            raise ValidationError(
> +                'This is not a valid image: %(file)s',
> +                params={'file': attachment.name}
> +            )
> +
> +    # Compare Mime type send by browser and Mime type from python-magic.
> +    # We only compare the main type (the first part) because the second
> +    # part may not be recoginzed correctly. E.g. for .lua the submitted
> +    # type is 'text/x-lua' but 'x-lua' is not official at all. See:
> +    # https://www.iana.org/assignments/media-types/media-types.xhtml
> +    # Unrecoginzed extension are always send with mime type
> +    # 'application/octet-stream'. Skip if we know them. 
> +    if not ext in settings.SKIP_MIME_EXTENSIONS:
> +        if not magic_mime['maintype'] == send_mime['maintype']:
> +            raise ValidationError(
> +                'The file %(file)s looks like %(send_mime)s, \
> +                but we think it is %(magic_mime)s',
> +                params={
> +                    'file': attachment.name,
> +                    'send_mime': send_mime['maintype'],
> +                    'magic_mime': magic_mime['maintype'],
> +                    },
> +            )


-- 
https://code.launchpad.net/~widelands-dev/widelands-website/pybb_attachments/+merge/370342
Your team Widelands Developers is subscribed to branch lp:widelands-website.


References