""" app/config.py ============= Central configuration and the path-jail helper used by every other module. All tuneable values can be overridden via environment variables: MEDIA_ROOT Root directory the application may read/write (default: /media) DB_PATH Path to the SQLite database file (default: /videopress.db) PORT TCP port Gunicorn listens on (default: 8080) LOG_LEVEL Gunicorn log verbosity (default: info) """ import os from pathlib import Path # --------------------------------------------------------------------------- # Paths # --------------------------------------------------------------------------- PACKAGE_DIR = Path(__file__).resolve().parent # …/app/ BASE_DIR = PACKAGE_DIR.parent # …/videocompressor/ # Every file-system operation in the application is restricted to MEDIA_ROOT. MEDIA_ROOT = Path(os.environ.get('MEDIA_ROOT', '/media')).resolve() # --------------------------------------------------------------------------- # Path-jail helper # --------------------------------------------------------------------------- def safe_path(raw: str) -> Path: """ Resolve *raw* to an absolute path and assert it is inside MEDIA_ROOT. Returns the resolved Path on success. Raises PermissionError if the path would escape MEDIA_ROOT (including symlink traversal and ../../ attacks). """ try: resolved = Path(raw).resolve() except Exception: raise PermissionError(f"Invalid path: {raw!r}") root_str = str(MEDIA_ROOT) path_str = str(resolved) if path_str != root_str and not path_str.startswith(root_str + os.sep): raise PermissionError( f"Access denied: '{resolved}' is outside the allowed " f"media root ({MEDIA_ROOT})." ) return resolved