import base64 import os from dataclasses import dataclass from pathlib import Path from .constants import FLAG_OFF, FLAG_ON ENV_CONFIG_DIR = "CHECKBOT_CONFIG_DIR" ENV_DB_PATH = "CHECKBOT_DB" ENV_BIND_HOST = "CHECKBOT_BIND_HOST" ENV_BIND_PORT = "CHECKBOT_BIND_PORT" ENV_SECURE_COOKIES = "CHECKBOT_SECURE_COOKIES" ENV_LOG_LEVEL = "CHECKBOT_LOG_LEVEL" DEFAULT_CONFIG_DIR = "/etc/checkbot" DEFAULT_DB_PATH = "/var/lib/checkbot/checkbot.db" DEFAULT_BIND_HOST = "127.0.0.1" DEFAULT_BIND_PORT = "8080" DEFAULT_LOG_LEVEL = "INFO" MASTER_KEY_FILE = "master.key" MASTER_KEY_LEN = 32 SESSION_SECRET_FILE = "session.secret" SESSION_SECRET_MIN_LEN = 32 @dataclass(frozen=True) class FileConfig: config_dir: Path db_path: Path bind_host: str bind_port: int secure_cookies: bool = True log_level: str = DEFAULT_LOG_LEVEL def load_file_config() -> FileConfig: return FileConfig( config_dir=Path(os.environ.get(ENV_CONFIG_DIR, DEFAULT_CONFIG_DIR)), db_path=Path(os.environ.get(ENV_DB_PATH, DEFAULT_DB_PATH)), bind_host=os.environ.get(ENV_BIND_HOST, DEFAULT_BIND_HOST), bind_port=int(os.environ.get(ENV_BIND_PORT, DEFAULT_BIND_PORT)), secure_cookies=os.environ.get(ENV_SECURE_COOKIES, FLAG_ON) != FLAG_OFF, log_level=os.environ.get(ENV_LOG_LEVEL, DEFAULT_LOG_LEVEL), ) def load_master_key(path: Path) -> bytes: key = base64.b64decode(path.read_text().strip()) if len(key) != MASTER_KEY_LEN: raise ValueError(f"master key in {path} must be {MASTER_KEY_LEN} bytes") return key def load_session_secret(path: Path) -> str: secret = path.read_text().strip() if len(secret) < SESSION_SECRET_MIN_LEN: raise ValueError(f"session secret in {path} must have at least {SESSION_SECRET_MIN_LEN} characters") return secret