Files

107 lines
3.1 KiB
Python

# retoor <retoor@molodetz.nl>
import os
import re
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
EXPECTED_KEYS = [
"SECRET_KEY",
"PLAYWRIGHT_HEADLESS",
"PLAYWRIGHT_SLOW_MO",
"MOLODETZ_ADMIN_USERNAME",
"MOLODETZ_ADMIN_EMAIL",
"MOLODETZ_ADMIN_PASSWORD",
"MOLODETZ_PORT",
"MOLODETZ_TEST_PORT",
"MOLODETZ_SITE_URL",
"MOLODETZ_DATA_DIR",
"MOLODETZ_DATABASE_URL",
"MOLODETZ_INTERNAL_BASE_URL",
"MOLODETZ_DISABLE_SERVICES",
"MOLODETZ_DISABLE_RATE_LIMIT",
"MOLODETZ_RATE_LIMIT",
"MOLODETZ_WEB_WORKERS",
"MOLODETZ_TEMPLATE_AUTO_RELOAD",
"MOLODETZ_STATIC_VERSION",
"MOLODETZ_LOG_LEVEL",
"MOLODETZ_PRESENCE_TIMEOUT_SECONDS",
"MOLODETZ_PRESENCE_ONLINE_LIMIT",
"MOLODETZ_PRESENCE_TRACK_LIMIT",
"MOLODETZ_PRESENCE_ONLINE_MARGIN_SECONDS",
"MOLODETZ_OUTBOUND_PROXY_URL",
"MOLODETZ_RCLONE_BIN",
"MOLODETZ_RCLONE_CONFIG",
"MOLODETZ_BACKUP_OFFLOAD_REMOTE",
"MOLODETZ_SITEMAP_TTL",
"MOLODETZ_LANDING_TTL",
"MOLODETZ_UNREAD_TTL",
]
NONEMPTY_PATH_KEYS = [
"MOLODETZ_DATA_DIR",
"MOLODETZ_DATABASE_URL",
"MOLODETZ_INTERNAL_BASE_URL",
"MOLODETZ_RCLONE_BIN",
"MOLODETZ_RCLONE_CONFIG",
]
def read_example():
values = {}
for line in (ROOT / ".env.example").read_text().splitlines():
match = re.match(r"^([A-Z][A-Z0-9_]*)=(.*)$", line)
if match:
values[match.group(1)] = match.group(2)
return values
def test_env_example_lists_every_key():
values = read_example()
assert sorted(values) == sorted(EXPECTED_KEYS)
def test_env_example_keeps_path_values_nonempty():
values = read_example()
for key in NONEMPTY_PATH_KEYS:
assert values[key].strip() != ""
def test_config_reads_no_unknown_keys():
source = (ROOT / "molodetz" / "config.py").read_text()
prefixed = set(re.findall(r'_env(?:_int)?\("([A-Z_]+)"', source))
assert set(re.findall(r'os\.environ\.get\("([A-Z_]+)"', source)) <= {"SECRET_KEY", "PLAYWRIGHT_HEADLESS", "PLAYWRIGHT_SLOW_MO"}
assert {f"MOLODETZ_{name}" for name in prefixed} <= set(EXPECTED_KEYS)
def run_config_import(data_dir, database_url):
env = {**os.environ, "MOLODETZ_DATA_DIR": data_dir, "MOLODETZ_DATABASE_URL": database_url}
return subprocess.run(
[sys.executable, "-c", "from molodetz import config"],
cwd=ROOT,
env=env,
capture_output=True,
text=True,
)
def test_data_dir_outside_root_refused():
result = run_config_import("/tmp/evil", "sqlite:////tmp/evil/molodetz.db")
assert result.returncode != 0
assert "outside" in result.stderr
def test_data_dir_inside_root_allowed():
target = ROOT / "data" / ".tmp-guard-probe"
result = run_config_import(str(target), f"sqlite:///{target / 'molodetz.db'}")
assert result.returncode == 0
def test_database_url_outside_data_dir_refused():
target = ROOT / "data" / ".tmp-guard-probe"
result = run_config_import(str(target), "sqlite:////tmp/evil/molodetz.db")
assert result.returncode != 0
assert "outside" in result.stderr