mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 18:02:38 +02:00
146 lines
4.3 KiB
Python
146 lines
4.3 KiB
Python
import functools
|
|
import logging
|
|
import sys
|
|
from typing import Any, Callable, TypeVar, cast
|
|
|
|
import click
|
|
|
|
F = TypeVar("F", bound=Callable[..., Any])
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class DocumentFilenameException(Exception):
|
|
"""Exception for document-related filename errors."""
|
|
|
|
|
|
class AddedDuplicateDocumentException(DocumentFilenameException):
|
|
"""Exception for a document is added twice."""
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__("A document was added twice")
|
|
|
|
|
|
class InputFileNotFoundException(DocumentFilenameException):
|
|
"""Exception for when an input file does not exist."""
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__("Input file not found: make sure you typed it correctly.")
|
|
|
|
|
|
class InputFileNotReadableException(DocumentFilenameException):
|
|
"""Exception for when an input file exists but is not readable."""
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__("You don't have permission to open the input file.")
|
|
|
|
|
|
class NonPDFOutputFileException(DocumentFilenameException):
|
|
"""Exception for when the output file is not a PDF."""
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__("Safe PDF filename must end in '.pdf'")
|
|
|
|
|
|
class IllegalOutputFilenameException(DocumentFilenameException):
|
|
"""Exception for when the output file contains illegal characters."""
|
|
|
|
def __init__(self, char: str) -> None:
|
|
super().__init__(f"Illegal character: {char}")
|
|
|
|
|
|
class UnwriteableOutputDirException(DocumentFilenameException):
|
|
"""Exception for when the output file is not writeable."""
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__("Safe PDF filename is not writable")
|
|
|
|
|
|
class NotSetInputFilenameException(DocumentFilenameException):
|
|
"""Exception for when the output filename is set before having an
|
|
associated input file."""
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__("Input filename has not been set yet.")
|
|
|
|
|
|
class NotSetOutputFilenameException(DocumentFilenameException):
|
|
"""Exception for when the output filename is read before it has been set."""
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__("Output filename has not been set yet.")
|
|
|
|
|
|
class NonExistantOutputDirException(DocumentFilenameException):
|
|
"""Exception for when the output dir does not exist."""
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__("Output directory does not exist")
|
|
|
|
|
|
class OutputDirIsNotDirException(DocumentFilenameException):
|
|
"""Exception for when the specified output dir is not actually a dir."""
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__("Specified output directory is actually not a directory")
|
|
|
|
|
|
class UnwriteableArchiveDirException(DocumentFilenameException):
|
|
"""Exception for when the archive directory cannot be created."""
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__(
|
|
"Archive directory for storing unsafe documents cannot be created."
|
|
)
|
|
|
|
|
|
class SuffixNotApplicableException(DocumentFilenameException):
|
|
"""Exception for when the suffix cannot be applied to the output filename."""
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__("Cannot set a suffix after setting an output filename")
|
|
|
|
|
|
def handle_document_errors(func: F) -> F:
|
|
"""Decorator to log document-related errors and exit gracefully."""
|
|
|
|
@functools.wraps(func)
|
|
def wrapper(*args, **kwargs): # type: ignore
|
|
try:
|
|
return func(*args, **kwargs)
|
|
except DocumentFilenameException as e:
|
|
if getattr(sys, "dangerzone_dev", False):
|
|
# Show the full traceback only on dev environments.
|
|
msg = "An exception occured while validating a document"
|
|
log.exception(msg)
|
|
click.echo(str(e))
|
|
sys.exit(1)
|
|
|
|
return cast(F, wrapper)
|
|
|
|
|
|
#### Container-related errors
|
|
|
|
|
|
class ImageNotPresentException(Exception):
|
|
pass
|
|
|
|
|
|
class ImageInstallationException(Exception):
|
|
pass
|
|
|
|
|
|
class NoContainerTechException(Exception):
|
|
def __init__(self, container_tech: str) -> None:
|
|
super().__init__(f"{container_tech} is not installed")
|
|
|
|
|
|
class NotAvailableContainerTechException(Exception):
|
|
def __init__(self, container_tech: str, error: str) -> None:
|
|
self.error = error
|
|
self.container_tech = container_tech
|
|
super().__init__(f"{container_tech} is not available")
|
|
|
|
|
|
class UnsupportedContainerRuntime(Exception):
|
|
pass
|