import json import logging import os import sys from pathlib import Path from typing import Callable, Optional, TypeVar T = TypeVar("T") logger = logging.getLogger(__name__) PROTECTED_KEYS = [ "APPNAME", "LOG_LEVEL", "PATH_EXCLUSION_CONST", "MIN_FILES_FOR_PATH", "VT_THREAT_TOLERANCE", "POLICY_MAP_ENF_AUD" ] _protected_config = {} def get_system_config_path() -> Path: # Check inside bundled EXE directory first bundled_dir = Path(getattr(sys, '_MEIPASS', '')) bundled_path = bundled_dir / "system_config.json" if bundled_path.exists(): return bundled_path # Fallback to external location return Path(__file__).parent.parent / "system_config.json" def load_protected_config() -> dict: global _protected_config try: with open(get_system_config_path(), "r") as f: system_config = json.load(f) except FileNotFoundError: logging.warning("⚠️ system_config.json not found. Using built-in defaults.") system_config = { "APPNAME": "AirlockTools", "PATH_EXCLUSION_CONST": 4, "MIN_FILES_FOR_PATH": 4, "VT_THREAT_TOLERANCE": 4, "POLICY_MAP_ENF_AUD": { "enforced_id": "audit_id" } } _protected_config = {key: system_config[key] for key in PROTECTED_KEYS} return _protected_config def get_protected_value(key: str, cast_type: Callable[[str], T] = str, default: Optional[T] = None) -> Optional[T]: value = _protected_config.get(key) if value is None: logging.warning(f"Protected config key '{key}' not found.") return default try: if isinstance(value, str): value = value.strip("'\"") return cast_type(value) except (ValueError, TypeError): logging.warning(f"Invalid value for protected key '{key}': {value}. Expected type {cast_type.__name__}.") return default def get_protected_json(key: str, default: str = "{}") -> dict: raw = _protected_config.get(key, default) if isinstance(raw, dict): return raw try: return json.loads(raw) except json.JSONDecodeError: try: escaped = raw.encode('unicode_escape').decode('utf-8') return json.loads(escaped) except Exception as e: logging.error(f"Failed to parse protected JSON key '{key}': {e}") return json.loads(default) def load_env_json(key: str, default: str): raw = os.getenv(key, default) try: return json.loads(raw) except json.JSONDecodeError: try: escaped = raw.encode('unicode_escape').decode('utf-8') return json.loads(escaped) except Exception as e: logging.error(f"Failed to parse {key}: {e}") return json.loads(default) def load_env(key: str, cast_type: Callable[[str], T] = str, default: Optional[T] = None) -> Optional[T]: """ Safely retrieves an environment variable and casts it to the desired type. Parameters: key (str): The name of the environment variable. cast_type (Callable[[str], T], optional): Function to cast the value. Defaults to str. default (Optional[T], optional): Default value if the variable is not set or invalid. Returns: Optional[T]: The casted value or the default. """ value = os.getenv(key) if value is None: logger.warning(f"Environment variable '{key}' not set.") return default try: value = value.strip("'\"") # Strip surrounding quotes return cast_type(value) except (ValueError, TypeError): logger.warning(f"Invalid value for env var '{key}': {value}. Expected type {cast_type.__name__}.") return default