refactor: unify project structure, improve security, and enhance deployment
- Fix WireGuard private key leak in API responses and config updates - Update systemd service to serve from repo root with adjusted sandbox - Add CLI flags, idempotency, and dev mode to install.sh - Extract common utilities to lib/common.py and webui/api/common.py - Migrate frontend to htmx for simpler, more maintainable UI - Update docs to reflect current architecture and deployment model - Vendor htmx dependencies per project requirements
This commit is contained in:
+42
-5
@@ -127,10 +127,12 @@ class TestFirewallRichRules:
|
||||
assert resp.status_code == 400
|
||||
|
||||
@patch("webui.api.firewall.get_rich_rules")
|
||||
@patch("webui.api.firewall.config_get")
|
||||
@patch("webui.api.firewall.get_config")
|
||||
def test_list(self, mock_cfg, mock_list, client):
|
||||
mock_list.return_value = ["rule1"]
|
||||
mock_cfg.return_value = {"zones": {"public": {"rich_rules": [{"id": "a1", "rule": "rule1"}]}}}
|
||||
mock_cfg.return_value = {
|
||||
"zones": {"public": {"rich_rules": [{"id": "a1", "rule": "rule1"}]}}
|
||||
}
|
||||
resp = client.get("/api/firewall/rich-rules/public")
|
||||
assert resp.status_code == 200
|
||||
data = resp.get_json()
|
||||
@@ -250,7 +252,7 @@ class TestDhcpApply:
|
||||
|
||||
|
||||
class TestDhcpStatus:
|
||||
@patch("lib.dnsmasq.get_status")
|
||||
@patch("webui.api.dhcp.dnsmasq_status")
|
||||
def test_success(self, mock_status, client):
|
||||
mock_status.return_value = {"service_active": True}
|
||||
resp = client.get("/api/dhcp/status")
|
||||
@@ -469,6 +471,38 @@ class TestWireguardConfig:
|
||||
resp = client.post("/api/wireguard/config", json={"peers": {}})
|
||||
assert resp.status_code == 200
|
||||
|
||||
@patch("webui.api.wireguard.save_config")
|
||||
@patch("webui.api.wireguard.get_config")
|
||||
def test_post_strips_private_key(self, mock_get, mock_save, client):
|
||||
mock_get.return_value = {
|
||||
"interface": {"name": "wg0", "private_key": "existing"},
|
||||
"peers": {},
|
||||
}
|
||||
mock_save.return_value = None
|
||||
resp = client.post(
|
||||
"/api/wireguard/config",
|
||||
json={"interface": {"name": "wg0", "private_key": "secret"}, "peers": {}},
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
saved = mock_save.call_args[0][0]
|
||||
assert saved["interface"]["private_key"] == "existing"
|
||||
|
||||
@patch("webui.api.wireguard.save_config")
|
||||
@patch("webui.api.wireguard.get_config")
|
||||
def test_patch_strips_private_key(self, mock_get, mock_save, client):
|
||||
mock_get.return_value = {
|
||||
"interface": {"name": "wg0", "private_key": "existing"},
|
||||
"peers": {},
|
||||
}
|
||||
mock_save.return_value = None
|
||||
resp = client.patch(
|
||||
"/api/wireguard/config",
|
||||
json={"interface": {"name": "wg1", "private_key": "injected"}},
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
saved = mock_save.call_args[0][0]
|
||||
assert saved.get("interface", {}).get("private_key") == "existing"
|
||||
|
||||
|
||||
class TestWireguardPeers:
|
||||
@patch("webui.api.wireguard.get_peers")
|
||||
@@ -479,7 +513,10 @@ class TestWireguardPeers:
|
||||
|
||||
@patch("webui.api.wireguard.add_peer")
|
||||
def test_add(self, mock_add, client):
|
||||
mock_add.return_value = {"name": "client1", "public_key": "pub", "private_key": "priv"}
|
||||
mock_add.return_value = {
|
||||
"name": "client1",
|
||||
"public_key": "pub",
|
||||
}
|
||||
resp = client.post(
|
||||
"/api/wireguard/peers",
|
||||
json={"name": "client1"},
|
||||
@@ -574,4 +611,4 @@ class TestResponseHelpers:
|
||||
data = resp.get_json()
|
||||
assert "error" in data
|
||||
assert "ok" in data
|
||||
assert data["ok"] is False
|
||||
assert data["ok"] is False
|
||||
|
||||
Reference in New Issue
Block a user