Merge pull request #44534 from NousResearch/bb/approval-allow-permanent
fix(approval): carry allow_permanent to TUI + desktop approval prompts
This commit is contained in:
@@ -285,3 +285,65 @@ class TestProgrammingErrorsPropagateFromWrapper:
|
||||
os.environ["HERMES_INTERACTIVE"] = "1"
|
||||
with pytest.raises(AttributeError, match="bug in wrapper"):
|
||||
check_all_command_guards("echo hello", "local")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Gateway (TUI / desktop) approval notify payload carries allow_permanent
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestGatewayApprovalAllowPermanent:
|
||||
"""The gateway emits the approval prompt to the renderer via the notify
|
||||
payload (TUI/desktop both consume it). It must carry ``allow_permanent``
|
||||
so the UI doesn't offer a permanent allow the backend would silently
|
||||
downgrade to session scope for tirith content-security findings.
|
||||
"""
|
||||
|
||||
def _capture_gateway_payload(self, command, session_key):
|
||||
"""Run the gateway approval path, denying inline, and return the
|
||||
single notify payload the renderer would have received."""
|
||||
from tools.approval import (
|
||||
register_gateway_notify,
|
||||
resolve_gateway_approval,
|
||||
unregister_gateway_notify,
|
||||
)
|
||||
|
||||
captured = []
|
||||
|
||||
def notify(data):
|
||||
captured.append(dict(data))
|
||||
# The notify fires synchronously before _await_gateway_decision
|
||||
# blocks, so resolving here releases the wait without a thread.
|
||||
resolve_gateway_approval(session_key, "deny")
|
||||
|
||||
register_gateway_notify(session_key, notify)
|
||||
token = set_current_session_key(session_key)
|
||||
os.environ["HERMES_GATEWAY_SESSION"] = "1"
|
||||
os.environ["HERMES_EXEC_ASK"] = "1"
|
||||
os.environ["HERMES_SESSION_KEY"] = session_key
|
||||
try:
|
||||
check_all_command_guards(command, "local")
|
||||
finally:
|
||||
os.environ.pop("HERMES_GATEWAY_SESSION", None)
|
||||
os.environ.pop("HERMES_EXEC_ASK", None)
|
||||
os.environ.pop("HERMES_SESSION_KEY", None)
|
||||
reset_current_session_key(token)
|
||||
unregister_gateway_notify(session_key)
|
||||
|
||||
assert len(captured) == 1
|
||||
return captured[0]
|
||||
|
||||
def test_dangerous_only_allows_permanent(self):
|
||||
"""No tirith warning → permanent allow is offered."""
|
||||
payload = self._capture_gateway_payload("rm -rf /important", "gw-allow-perm")
|
||||
assert payload["command"] == "rm -rf /important"
|
||||
assert payload["allow_permanent"] is True
|
||||
|
||||
@patch(_TIRITH_PATCH,
|
||||
return_value=_tirith_result("warn",
|
||||
[{"rule_id": "shortened_url"}],
|
||||
"shortened URL detected"))
|
||||
def test_tirith_warning_disallows_permanent(self, mock_tirith):
|
||||
"""tirith content-security warning → permanent allow is withheld so the
|
||||
renderer hides "Always allow"."""
|
||||
payload = self._capture_gateway_payload("curl https://bit.ly/abc", "gw-no-perm")
|
||||
assert payload["allow_permanent"] is False
|
||||
|
||||
Reference in New Issue
Block a user