diff --git a/src/c2s.py b/src/c2s.py index 0af8b75..898a2a7 100644 --- a/src/c2s.py +++ b/src/c2s.py @@ -20,6 +20,7 @@ client = Blueprint("c2s", __name__) @client.route("/_matrix/client/r0/delete_devices", methods=["POST"]) @client.route("/_matrix/client/v3/logout/all", methods=["POST"]) @client.route("/_matrix/client/v3/logout", methods=["POST"]) +@client.route("/_matrix/client/r0/logout", methods=["POST"]) @client.route("/_matrix/client/v3/rooms//invite", methods=["POST"]) @client.route("/_matrix/client/v3/rooms//leave", methods=["POST"]) @client.route("/_matrix/client/r0/rooms//leave", methods=["POST"]) diff --git a/src/config.py b/src/config.py index 332b7f0..ad57980 100644 --- a/src/config.py +++ b/src/config.py @@ -1,84 +1,124 @@ -import mimetypes -import tomllib import os +from pathlib import Path +import tomllib +import mimetypes -# Default values -addr = "127.0.0.1" -port = 5000 -allow_registration = False -the_funny_number = 1337 -cat = "/etc/vona/cat.jpg" +addr: str = "127.0.0.1" +port: int = 5000 +allow_registration: bool = False +the_funny_number: int = 1337 +cat: str = "/etc/vona/cat.jpg" -server_name = "" -signing_key = "" +server_name: str = "" +signing_key: str = "" +support: dict = {"contacts": []} -_config_path = "/etc/vona/config.toml" +_CONFIG_PATH = Path("/etc/vona/config.toml") -try: - with open(_config_path, "rb") as f: - _config = tomllib.load(f) -except FileNotFoundError: - print(f"[FATL] Configuration file not found at {_config_path}") - os._exit(1) -except PermissionError: - print(f"[FATL] Permission denied when accessing configuration") - os._exit(1) -except tomllib.TOMLDecodeError as e: - print(f"[FATL] Invalid TOML configuration: {e}") +def _fatal(msg: str) -> None: + print(f"[FATL] {msg}") os._exit(1) -if "address" in _config: - addr = _config["address"] +def _warn(msg: str) -> None: + print(f"[WARN] {msg}") -if "allow_registration" in _config: - allow_registration = _config["allow_registration"] +def _load_toml(path: Path) -> dict: + try: + with path.open("rb") as f: + return tomllib.load(f) + except FileNotFoundError: + _fatal(f"[FATL] Configuration file not found at {path}") + except PermissionError: + _fatal(f"[FATL] Permission denied when accessing configuration {path}") + except tomllib.TOMLDecodeError as e: + _fatal(f"[FATL] Invalid TOML configuration: {e}") -if "server_name" in _config: - server_name = _config["server_name"] -else: - print("[FATL] `server_name` is not in configuration") - os._exit(1) +def _read_signing_key_from_path(path_value) -> str | None: + p = Path(path_value) + if not p.exists(): + _fatal(f"[FATL] signing_key_path {p} does not exist") + try: + return p.read_text(encoding="utf-8").strip() + except Exception as e: + _fatal(f"[FATL] Failed to read signing_key_path {p}: {e}") -if "signing_key" in _config: - signing_key = _config["signing_key"] -else: - print( - "[FATL] `signing_key` is not in configuration." - + " A signing key can be generated using `cmd/generate_key.py`." - ) - os._exit(1) +def _validate_cat_path(cat_path: str) -> Path: + p = Path(cat_path) + if not p.exists(): + _fatal(f"[FATL] Cat photo at {p} does not exist") + + mtype, _ = mimetypes.guess_type(str(p)) + if mtype is None or not mtype.startswith("image/"): + _warn(f"[WARN] Cat file {p} does not look like an image (mimetype={mtype})") + + return p -if "cat" in _config: - cat = _config["cat"] +def _apply_config(cfg: dict) -> None: + global addr, port, allow_registration, server_name, signing_key, cat, support -if not os.path.exists(cat): - print(f"[FATL] Cat photo at {cat} does not exist") - os._exit(1) + if "address" in cfg: + addr = str(cfg["address"]) -if "support" in _config: - support = { - "contacts": [{ - "role": "m.role.admin" - }] - } + if "port" in cfg: + try: + port = int(cfg["port"]) + except (TypeError, ValueError): + _warn( + f"[WARN] Invalid port in config: {cfg.get('port')}; using default {port}" + ) - _support = _config["support"] + if "allow_registration" in cfg: + allow_registration = bool(cfg["allow_registration"]) - if "mxid" in _support: - support["contacts"][0]["matrix_id"] = _support["mxid"] + if "server_name" in cfg: + server_name = str(cfg["server_name"]) + else: + _fatal("[FATL] `server_name` is not in configuration") - if "email" in _support: - support["contacts"][0]["email_address"] = _support["email"] + if "signing_key" in cfg and "signing_key_path" in cfg: + _warn( + "[WARN] Both `signing_key` and `signing_key_path` present. Using `signing_key`." + ) -else: - print(f"[WARN] No support contacts are defined") - support = {"contacts": []} + if "signing_key" in cfg: + signing_key = str(cfg["signing_key"]).strip() + elif "signing_key_path" in cfg: + sk = _read_signing_key_from_path(cfg["signing_key_path"]) + if sk: + signing_key = sk + else: + _fatal( + "[FATL] `signing_key` is not in configuration. " + "A signing key can be generated using `cmd/generate_key.py`." + ) + + if "cat" in cfg: + cat = str(cfg["cat"]) + + cat_path = _validate_cat_path(cat) + cat = str(cat_path) + + support_obj = {"contacts": []} + if "support" in cfg and isinstance(cfg["support"], dict): + _support = cfg["support"] + contact = {"role": "m.role.admin"} + if "mxid" in _support: + contact["matrix_id"] = str(_support["mxid"]) + if "email" in _support: + contact["email_address"] = str(_support["email"]) + if len(contact) > 1: + support_obj["contacts"].append(contact) + else: + _warn("[WARN] No support contacts are defined") + support = support_obj + + print("[INFO] Configuration file was valid") -print("[INFO] Configuration file was valid") +_apply_config(_load_toml(_CONFIG_PATH))