Remove deprecated MCP and gateway aliases
This commit is contained in:
@@ -72,8 +72,16 @@ def run():
|
||||
assert "secret_b64" not in str(mod.VAULT_SECRETS)
|
||||
|
||||
tools = {tool["name"]: tool for tool in mod.raw_tools()}
|
||||
assert "transient secret_b64" not in tools["nap_gateway_vault_setup_process"]["description"]
|
||||
assert "opaque client-wrapped key bundle records" in tools["nap_gateway_vault_setup_process"]["description"]
|
||||
assert "nap_gateway_vault_ls" in tools
|
||||
assert "nap_gateway_vault_process" in tools
|
||||
assert "nap_gateway_vault_" + "setup_ls" not in tools
|
||||
assert "nap_gateway_vault_" + "setup_process" not in tools
|
||||
assert not [name for name in tools if name.startswith("napseer_")]
|
||||
assert not [
|
||||
tool for tool in mod.tools() if tool.get("napseer", {}).get("replaces")
|
||||
]
|
||||
assert "transient secret_b64" not in tools["nap_gateway_vault_process"]["description"]
|
||||
assert "opaque client-wrapped key bundle records" in tools["nap_gateway_vault_process"]["description"]
|
||||
assert "transient secret_b64" not in tools["nap_gateway_vault_secret_rotate"]["description"]
|
||||
assert "opaque client-wrapped key bundle record" in tools["nap_gateway_vault_secret_rotate"]["description"]
|
||||
|
||||
@@ -165,7 +173,19 @@ def run():
|
||||
assert calls[0][0] == "POST"
|
||||
assert calls[0][1] == f"/v1/projects/{PROJECT_ID}/vault/secrets/chat/rotate"
|
||||
assert calls[0][5] == "encryption"
|
||||
assert set(calls[0][2]) == {"wrapped_key_bundle"}
|
||||
assert set(calls[0][2]) == {
|
||||
"previous_wrapping_epoch",
|
||||
"previous_bundle_version",
|
||||
"previous_data_key_epoch",
|
||||
"previous_aad_hash",
|
||||
"previous_ciphertext_sha256",
|
||||
"wrapped_key_bundle",
|
||||
}
|
||||
assert calls[0][2]["previous_wrapping_epoch"] == 1
|
||||
assert calls[0][2]["previous_bundle_version"] == 1
|
||||
assert calls[0][2]["previous_data_key_epoch"] == 1
|
||||
assert calls[0][2]["previous_aad_hash"] == active_bundle["aad_hash"]
|
||||
assert calls[0][2]["previous_ciphertext_sha256"] == active_bundle["ciphertext_sha256"]
|
||||
assert_wrapped_record(mod, calls[0][2]["wrapped_key_bundle"], "chat", data_key_epoch=2)
|
||||
assert "secret_b64" not in str(calls[0][2])
|
||||
assert mod.VAULT_SECRETS == local_before
|
||||
|
||||
@@ -255,10 +255,53 @@ def run():
|
||||
moved["full_path"] = "/renamed/alpha"
|
||||
moved["folder_path"] = "/renamed"
|
||||
mod.request_json = lambda method, path, payload=None, **kwargs: {"items": [moved]}
|
||||
listed = mod.list_project_nodes({"limit": 10})
|
||||
listed = mod.list_project_nodes({"limit": 10, "include_content": True})
|
||||
assert listed["items"][0]["content_text"] == "secret needle"
|
||||
assert listed["items"][0]["metadata"] == {"private": "secret metadata"}
|
||||
|
||||
mod.request_json = lambda method, path, payload=None, **kwargs: {"items": [moved]}
|
||||
compact = mod.list_project_nodes({"limit": 10})
|
||||
assert compact["ok"] is True
|
||||
assert compact["view"] == "summary"
|
||||
assert "content_text" not in compact["items"][0]
|
||||
assert compact["items"][0]["preview"] == "secret needle"
|
||||
assert compact["items"][0]["metadata_summary"] == {}
|
||||
full = mod.list_project_nodes({"limit": 10, "view": "full"})
|
||||
assert full["items"][0]["content_text"] == "secret needle"
|
||||
|
||||
plan_base = {
|
||||
"project_id": "project-1",
|
||||
"folder_path": "/plans",
|
||||
"name": "plan",
|
||||
"type": "note",
|
||||
"tags": ["plan"],
|
||||
"links": [],
|
||||
"content_text": "plan body",
|
||||
"encryption_state": "legacy_plaintext",
|
||||
}
|
||||
active_nodes = [
|
||||
{**plan_base, "id": "active", "full_path": "/plans/active", "metadata": {"status": "planned"}},
|
||||
{**plan_base, "id": "done", "full_path": "/plans/done", "metadata": {"status": "completed"}},
|
||||
{**plan_base, "id": "archived", "full_path": "/plans/archived", "metadata": {"status": "planned"}, "archived_at": "2026-05-06T00:00:00Z"},
|
||||
]
|
||||
mod.request_json = lambda method, path, payload=None, **kwargs: {"items": active_nodes}
|
||||
active = mod.list_project_nodes({"folder_path": "/plans", "active_only": True})
|
||||
assert [item["full_path"] for item in active["items"]] == ["/plans/active"]
|
||||
status_filtered = mod.list_project_nodes({"folder_path": "/plans", "status": ["completed"], "view": "paths"})
|
||||
assert status_filtered["items"] == [{"full_path": "/plans/done", "type": "note", "status": "completed"}]
|
||||
|
||||
def search_response(method, path, payload=None, **kwargs):
|
||||
assert "q=" in path
|
||||
return {"items": [dict(moved)]}
|
||||
|
||||
mod.request_json = search_response
|
||||
found = mod.list_project_nodes({"q": "secret needle", "limit": 5})
|
||||
assert "query_analysis" not in found
|
||||
assert "diagnostics" not in found
|
||||
verbose_found = mod.list_project_nodes({"q": "secret needle", "limit": 5, "verbose": True})
|
||||
assert "query_analysis" in verbose_found
|
||||
assert "diagnostics" in verbose_found
|
||||
|
||||
legacy_moved = encrypted_node(mod, full_path="/notes/legacy", content="old")
|
||||
legacy_moved["encrypted_content_envelope"].pop("aad_subject")
|
||||
legacy_moved["full_path"] = "/renamed/legacy"
|
||||
|
||||
@@ -33,8 +33,12 @@ def run():
|
||||
assert mod.handle_gateway(["vault", "rotate-secret", "--kind", "chat"]) == 0
|
||||
assert calls[-1] == ("gateway", ["vault", "rotate-secret", "--kind", "chat"])
|
||||
|
||||
assert mod.handle_gateway(["vault-setup", "list"]) == 0
|
||||
assert calls[-1] == ("gateway", ["vault-setup", "list"])
|
||||
try:
|
||||
mod.handle_gateway(["vault-setup", "list"])
|
||||
except RuntimeError as exc:
|
||||
assert "unknown gateway command" in str(exc)
|
||||
else:
|
||||
raise AssertionError("deprecated gateway vault-setup alias must not route")
|
||||
|
||||
assert mod.handle_gateway(["terminal", "list"]) == 0
|
||||
assert calls[-1] == ("gateway", ["terminal", "list"])
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Smoke-test project encryption enable payload generation."""
|
||||
"""Smoke-test project encryption enable fail-closed behavior."""
|
||||
|
||||
import base64
|
||||
import importlib.util
|
||||
import pathlib
|
||||
import sys
|
||||
@@ -17,6 +16,18 @@ def load_module():
|
||||
return module
|
||||
|
||||
|
||||
def assert_raises_hashicorp_closed(fn):
|
||||
try:
|
||||
fn()
|
||||
except RuntimeError as exc:
|
||||
message = str(exc)
|
||||
assert "HashiCorp" in message
|
||||
assert "disabled" in message
|
||||
assert "setup-request" in message
|
||||
else:
|
||||
raise AssertionError("CLI direct project encryption enable must fail closed")
|
||||
|
||||
|
||||
def run():
|
||||
mod = load_module()
|
||||
calls = []
|
||||
@@ -25,34 +36,28 @@ def run():
|
||||
mod.AUTH = {"agent_id": "agent-1"}
|
||||
mod.request_project_write = lambda method, path, body, project_id, purpose, scope_type="project": calls.append(
|
||||
(method, path, body, project_id, purpose, scope_type)
|
||||
) or {"state": "encrypted", "active_project_key_version": {"version": 1}}
|
||||
) or {"state": "plaintext"}
|
||||
mod.create_project_with_state = lambda args: ({"id": "project-1"}, "created", "created")
|
||||
mod.save_auth = lambda payload: None
|
||||
|
||||
result = mod.project_encryption_transition({"state": "encrypted", "passphrase": "pw"})
|
||||
assert result["status"] == "updated"
|
||||
assert calls, "encryption enable should call backend"
|
||||
method, path, body, project_id, purpose, scope_type = calls[0]
|
||||
assert method == "POST"
|
||||
assert path == "/v1/projects/project-1/encryption/enable"
|
||||
assert project_id == "project-1"
|
||||
assert scope_type == "encryption"
|
||||
assert body["state"] == "encrypted"
|
||||
wrapped = body["wrapped_project_key"]
|
||||
assert wrapped["credential_id"] == "local-passphrase:agent-1"
|
||||
assert wrapped["wrap_alg"] == "AES-GCM-256"
|
||||
assert wrapped["kdf_alg"] == "PBKDF2-SHA256"
|
||||
assert wrapped["kdf_params"]["source"] == "local_passphrase"
|
||||
assert wrapped["kdf_params"]["iterations"] == mod.PROJECT_KEY_KDF_ITERATIONS
|
||||
assert len(base64.b64decode(wrapped["salt_b64"])) == 16
|
||||
assert len(base64.b64decode(wrapped["kdf_params"]["nonce_b64"])) == 12
|
||||
assert len(base64.b64decode(wrapped["wrapped_project_key_b64"])) == 48
|
||||
assert_raises_hashicorp_closed(lambda: mod.project_encryption_transition({"state": "encrypted", "passphrase": "pw"}))
|
||||
assert calls == []
|
||||
|
||||
assert_raises_hashicorp_closed(lambda: mod.bootstrap_project({"encryption": "encrypted", "passphrase": "pw"}))
|
||||
assert calls == []
|
||||
|
||||
calls.clear()
|
||||
result = mod.project_encryption_transition({"state": "plaintext"})
|
||||
assert result["status"] == "updated"
|
||||
assert "wrapped_project_key" not in calls[0][2]
|
||||
assert calls, "plaintext transition should still call backend"
|
||||
method, path, body, project_id, purpose, scope_type = calls[0]
|
||||
assert method == "POST"
|
||||
assert path == "/v1/projects/project-1/encryption/disable"
|
||||
assert project_id == "project-1"
|
||||
assert scope_type == "encryption"
|
||||
assert body == {"state": "plaintext"}
|
||||
assert "wrapped" not in str(body)
|
||||
|
||||
print("ok: project encryption enable payload smoke passed")
|
||||
print("ok: project encryption enable fail-closed smoke passed")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user