def validate_allowed_extension(filename):
    """Check file extension"""
    _, extension = os.path.splitext(filename)
    if extension.lower() not in ALLOWED_EXTENSIONS:
        raise OMPSUploadedFileError(
            f'Uploaded file extension "{extension}" is not any of {ALLOWED_EXTENSIONS}'
        )
def _extract_zip_file(
    filepath, target_dir,
    max_uncompressed_size=DEFAULT_ZIPFILE_MAX_UNCOMPRESSED_SIZE
):
    """Extract zip file into target directory

    :param filepath: path to zip archive file
    :param target_dir: directory where extracted files will be stored
    :param max_uncompressed_size: size in Bytes how big data can be accepted
        after uncompressing
    """
    try:
        archive = zipfile.ZipFile(filepath)
    except zipfile.BadZipFile as e:
        raise OMPSUploadedFileError(str(e))

    if logger.isEnabledFor(logging.DEBUG):
        # log content of zipfile
        logger.debug(
            'Content of zip archive:\n%s',
            '\n'.join(
                "name={zi.filename}, compress_size={zi.compress_size}, "
                "file_size={zi.file_size}".format(zi=zipinfo)
                for zipinfo in archive.filelist
            )
        )

    uncompressed_size = sum(zi.file_size for zi in archive.filelist)
    if uncompressed_size > max_uncompressed_size:
        raise OMPSUploadedFileError(
            "Uncompressed archive is larger than limit "
            "({}B>{}B)".format(
                uncompressed_size, max_uncompressed_size
            ))

    try:
        bad_file = archive.testzip()
    except RuntimeError as e:
        # trying to open an encrypted zip file without a password
        raise OMPSUploadedFileError(str(e))

    if bad_file is not None:
        raise OMPSUploadedFileError(
            f"CRC check failed for file {bad_file} in archive"
        )
    archive.extractall(target_dir)
    archive.close()