diff --git a/openvpncertupdate.py b/openvpncertupdate.py index 910cf2e..fa5beb7 100644 --- a/openvpncertupdate.py +++ b/openvpncertupdate.py @@ -207,6 +207,56 @@ def copy_crl(pki_dir: str, dest_path: str) -> None: os.chmod(dest_path, 0o644) +# ============================================================ +# === METADATA === +# ============================================================ + +_METADATA_FILE = "openvpncertupdate-metadata.json" + + +def load_metadata(pki_dir: str) -> dict[str, str]: + p = os.path.join(pki_dir, _METADATA_FILE) + if not os.path.exists(p): + return {} + with open(p) as fh: + return json.load(fh) + + +def save_email(pki_dir: str, cn: str, email_addr: str) -> None: + data = load_metadata(pki_dir) + data[cn] = email_addr + with open(os.path.join(pki_dir, _METADATA_FILE), "w") as fh: + json.dump(data, fh, indent=2) + + +def get_email(pki_dir: str, cn: str) -> str: + return load_metadata(pki_dir).get(cn, "") + + +# ============================================================ +# === CONFIG === +# ============================================================ + + +def build_ovpn( + cn: str, + pki_dir: str, + template_path: str, + output_base_dir: str, + config_name: str, +) -> str: + """Concat template + inline file. Return absolute path to written .ovpn.""" + inline_path = os.path.join(pki_dir, "inline", "private", f"{cn}.inline") + template_content = Path(template_path).read_text() + inline_content = Path(inline_path).read_text() + today = date.today().strftime("%Y-%m-%d") + out_dir = Path(output_base_dir) / f"{cn}_{today}" + out_dir.mkdir(parents=True, exist_ok=True) + out_file = out_dir / config_name + out_file.write_text(template_content + "\n" + inline_content) + return str(out_file.resolve()) + + # (remaining sections added in later tasks) # ============================================================ diff --git a/tests/test_config_builder.py b/tests/test_config_builder.py new file mode 100644 index 0000000..22a60e1 --- /dev/null +++ b/tests/test_config_builder.py @@ -0,0 +1,28 @@ +import os +from pathlib import Path +from datetime import date +from openvpncertupdate import build_ovpn + +def setup_pki(tmp_path, cn, inline_content="X"): + pki = tmp_path / "pki" + private_dir = pki / "inline" / "private" + private_dir.mkdir(parents=True) + (private_dir / f"{cn}.inline").write_text(inline_content) + return str(pki) + +def test_creates_file_with_combined_content(tmp_path): + pki = setup_pki(tmp_path, "alice", "CERT") + tmpl = tmp_path / "t.ovpn" + tmpl.write_text("client\ndev tun\n") + result = build_ovpn("alice", pki, str(tmpl), str(tmp_path / "out"), "vpn.ovpn") + content = Path(result).read_text() + assert "client" in content + assert "CERT" in content + +def test_output_path_has_cn_and_date(tmp_path): + pki = setup_pki(tmp_path, "bob") + tmpl = tmp_path / "t.ovpn"; tmpl.write_text("") + today = date.today().strftime("%Y-%m-%d") + result = build_ovpn("bob", pki, str(tmpl), str(tmp_path / "out"), "vpn.ovpn") + assert f"bob_{today}" in result + assert result.endswith("vpn.ovpn") diff --git a/tests/test_metadata.py b/tests/test_metadata.py new file mode 100644 index 0000000..6925eb9 --- /dev/null +++ b/tests/test_metadata.py @@ -0,0 +1,16 @@ +from openvpncertupdate import load_metadata, save_email, get_email + +def test_load_empty(tmp_path): + assert load_metadata(str(tmp_path)) == {} + +def test_save_and_get(tmp_path): + save_email(str(tmp_path), "alice", "alice@example.com") + assert get_email(str(tmp_path), "alice") == "alice@example.com" + +def test_update_existing(tmp_path): + save_email(str(tmp_path), "alice", "old@example.com") + save_email(str(tmp_path), "alice", "new@example.com") + assert get_email(str(tmp_path), "alice") == "new@example.com" + +def test_missing_returns_empty(tmp_path): + assert get_email(str(tmp_path), "nobody") == ""