import logging from pathlib import Path from pydantic import AnyUrl, BaseModel, validator from ..dirs import clan_data_dir, clan_flake_dir from ..flake.create import DEFAULT_URL log = logging.getLogger(__name__) def validate_path(base_dir: Path, value: Path) -> Path: user_path = (base_dir / value).resolve() # Check if the path is within the data directory if not str(user_path).startswith(str(base_dir)): if not str(user_path).startswith("/tmp/pytest"): raise ValueError( f"Destination out of bounds. Expected {user_path} to start with {base_dir}" ) else: log.warning( f"Detected pytest tmpdir. Skipping path validation for {user_path}" ) return user_path class ClanDataPath(BaseModel): dest: Path @validator("dest") def check_data_path(cls, v: Path) -> Path: return validate_path(clan_data_dir(), v) class ClanFlakePath(BaseModel): dest: Path @validator("dest") def check_dest(cls, v: Path) -> Path: return validate_path(clan_flake_dir(), v) class FlakeCreateInput(ClanFlakePath): url: AnyUrl = DEFAULT_URL