diff --git a/tests/test_app.py b/tests/test_app.py index 34932ce..8c32eb7 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -174,6 +174,33 @@ def test_sysctl_audit_rejects_unknown_host_without_ssh(monkeypatch): assert response.status_code == 404 +def test_host_forensics_is_read_only_and_uses_inventory(monkeypatch): + payload = {"docker_binary": {"rc": 0, "stdout": "/usr/bin/docker", "stderr": ""}} + calls = [] + monkeypatch.setattr(app, "_find_inventory_host", lambda name: {"name": name, "user": "root", "ip": "10.5.85.13"}) + monkeypatch.setattr(app, "_ssh", lambda host, command, timeout=600: (calls.append((host, command, timeout)) or (0, __import__("json").dumps(payload), ""))) + with TestClient(app.app) as client: + response = client.get("/system/forensics/node3?since_hours=24", headers={"Authorization": "Bearer test-token"}) + assert response.status_code == 200 + assert response.json()["checks"] == payload + assert calls[0][0] == "root@10.5.85.13" + assert calls[0][2] == 60 + assert "base64.b64decode" in calls[0][1] + command = app._host_forensics_command(24) + for destructive in ("systemctl restart", "systemctl stop", "systemctl disable", "docker rm", "docker system prune", "iptables -F", "rm -rf"): + assert destructive not in command + + +def test_host_forensics_rejects_unknown_host_and_invalid_window(monkeypatch): + monkeypatch.setattr(app, "_find_inventory_host", lambda _name: None) + monkeypatch.setattr(app, "_ssh", lambda *_args, **_kwargs: (_ for _ in ()).throw(AssertionError("must not SSH"))) + with TestClient(app.app) as client: + missing = client.get("/system/forensics/not-there", headers={"Authorization": "Bearer test-token"}) + bad_window = client.get("/system/forensics/node3?since_hours=999", headers={"Authorization": "Bearer test-token"}) + assert missing.status_code == 404 + assert bad_window.status_code == 422 + + def test_invalid_log_target_is_rejected_before_ssh(): with TestClient(app.app) as client: response = client.get(