mirror of
https://github.com/NCBM/plyngent.git
synced 2026-07-23 05:55:16 +08:00
core/tools: timed human allow for denylisted commands
Denylist hits ask the user (default deny, timeout) instead of only hard rejecting when a policy hook is installed. Independent of YOLO soft-confirm; session grants skip re-prompt for the same basename. CLI installs the hook via install_cli_limit_hooks.
This commit is contained in:
@@ -43,12 +43,91 @@ def test_path_denylist(workspace: object) -> None:
|
||||
|
||||
def test_command_denylist(workspace: object) -> None:
|
||||
del workspace
|
||||
from plyngent.tools.workspace import (
|
||||
clear_policy_allowed_commands,
|
||||
set_policy_confirm_hook,
|
||||
)
|
||||
|
||||
set_policy_confirm_hook(None)
|
||||
clear_policy_allowed_commands()
|
||||
with pytest.raises(WorkspaceError, match="basename 'rm' is blocked"):
|
||||
check_command_allowed(["rm", "-rf", "/"])
|
||||
check_command_allowed(["echo", "ok"])
|
||||
set_command_denylist(None)
|
||||
|
||||
|
||||
def test_command_denylist_policy_confirm_allow(workspace: object) -> None:
|
||||
del workspace
|
||||
from plyngent.tools.workspace import (
|
||||
clear_policy_allowed_commands,
|
||||
set_policy_confirm_hook,
|
||||
)
|
||||
|
||||
calls: list[tuple[str, float]] = []
|
||||
|
||||
def hook(basename: str, argv: object, timeout: float) -> bool:
|
||||
del argv
|
||||
calls.append((basename, timeout))
|
||||
return basename == "sudo"
|
||||
|
||||
set_policy_confirm_hook(hook)
|
||||
clear_policy_allowed_commands()
|
||||
try:
|
||||
check_command_allowed(["sudo", "echo", "test"])
|
||||
assert calls == [("sudo", 30.0)]
|
||||
# Session grant: second call does not re-prompt.
|
||||
check_command_allowed(["sudo", "id"])
|
||||
assert len(calls) == 1
|
||||
finally:
|
||||
set_policy_confirm_hook(None)
|
||||
clear_policy_allowed_commands()
|
||||
|
||||
|
||||
def test_command_denylist_policy_confirm_deny(workspace: object) -> None:
|
||||
del workspace
|
||||
from plyngent.tools.workspace import (
|
||||
clear_policy_allowed_commands,
|
||||
set_policy_confirm_hook,
|
||||
)
|
||||
|
||||
set_policy_confirm_hook(lambda *_a: False)
|
||||
clear_policy_allowed_commands()
|
||||
try:
|
||||
with pytest.raises(WorkspaceError, match="declined or timed out"):
|
||||
check_command_allowed(["sudo", "echo", "x"])
|
||||
finally:
|
||||
set_policy_confirm_hook(None)
|
||||
clear_policy_allowed_commands()
|
||||
|
||||
|
||||
def test_command_denylist_policy_confirm_timeout_value(workspace: object) -> None:
|
||||
del workspace
|
||||
from plyngent.tools.workspace import (
|
||||
clear_policy_allowed_commands,
|
||||
set_policy_confirm_hook,
|
||||
set_policy_confirm_timeout,
|
||||
)
|
||||
|
||||
seen: list[float] = []
|
||||
|
||||
def hook(basename: str, argv: object, timeout: float) -> bool:
|
||||
del basename, argv
|
||||
seen.append(timeout)
|
||||
return False
|
||||
|
||||
set_policy_confirm_timeout(5.0)
|
||||
set_policy_confirm_hook(hook)
|
||||
clear_policy_allowed_commands()
|
||||
try:
|
||||
with pytest.raises(WorkspaceError):
|
||||
check_command_allowed(["rm", "x"])
|
||||
assert seen == [5.0]
|
||||
finally:
|
||||
set_policy_confirm_timeout(30.0)
|
||||
set_policy_confirm_hook(None)
|
||||
clear_policy_allowed_commands()
|
||||
|
||||
|
||||
def test_root_required() -> None:
|
||||
clear_workspace_root()
|
||||
with pytest.raises(WorkspaceError, match="not set"):
|
||||
|
||||
Reference in New Issue
Block a user