is_profile_gate_env matched any name containing _ALLOWED_ / _ALLOW_ALL_ / ... so an operator's own DEMO_ALLOWED_SENDER (script data, not a Hermes authorization gate) was deleted from every routed child env built with strip_launch_profile=True, breaking no_agent cron scripts under the host gateway. The owner prefix now has to be a platform: built-in Platform values, bundled platform plugins (directory names and manifest aliases), runtime-registered plugin adapters, plus GATEWAY_ (pairing) and QQ_ (qqbot). Every gate the adapters read still strips; operator variables survive. Fixes #119539
44 lines
2.2 KiB
Python
44 lines
2.2 KiB
Python
"""A profile gate is a PLATFORM prefix plus a gate-shaped suffix; an operator's own variable that
|
|
merely contains ``_ALLOWED_`` is script data and must survive the routed-child strip (#119539)."""
|
|
|
|
import os
|
|
|
|
from tools.environments.local import build_subprocess_env
|
|
from tools.environments.local_env_policy import is_profile_gate_env
|
|
|
|
|
|
def test_operator_allowlist_shaped_vars_are_not_gates_but_platform_gates_are():
|
|
# Same suffix shape on both sides — only the owner prefix decides.
|
|
assert not is_profile_gate_env("DEMO_ALLOWED_SENDER")
|
|
assert not is_profile_gate_env("ACCESS_ALLOWED_CALLBACK_ACE_TYPE")
|
|
assert not is_profile_gate_env("HERMES_MEDIA_ALLOW_DIRS")
|
|
for gate in ("DISCORD_ALLOWED_CHANNELS", "TELEGRAM_GROUP_ALLOWED_CHATS", "GATEWAY_ALLOW_ALL_USERS",
|
|
"WHATSAPP_GROUP_ALLOW_FROM", "QQ_GROUP_ALLOWED_USERS", "IRC_ALLOW_ALL_USERS"):
|
|
assert is_profile_gate_env(gate), gate
|
|
|
|
|
|
def test_routed_no_agent_script_env_keeps_operator_allowlist_and_drops_platform_gate(tmp_path, monkeypatch):
|
|
"""The cron ``no_agent`` spawn seam: a child built for ANOTHER profile drops Hermes gates but
|
|
keeps the operator's script data, whatever its name looks like."""
|
|
from agent.secret_scope import build_profile_secret_scope, reset_secret_scope, set_secret_scope
|
|
from hermes_constants import reset_hermes_home_override, set_hermes_home_override
|
|
|
|
launch = tmp_path / ".hermes"
|
|
other = launch / "profiles" / "other"
|
|
other.mkdir(parents=True)
|
|
(other / ".env").write_text("OTHER_MARKER=1\n", encoding="utf-8")
|
|
monkeypatch.setenv("HERMES_HOME", str(launch))
|
|
monkeypatch.setenv("DEMO_ALLOWED_SENDER", "someone@example.com")
|
|
monkeypatch.setenv("DISCORD_ALLOWED_CHANNELS", "111")
|
|
|
|
ht = set_hermes_home_override(str(other))
|
|
st = set_secret_scope(build_profile_secret_scope(other), profile_home=str(other))
|
|
try:
|
|
env = build_subprocess_env(strip_launch_profile=True)
|
|
finally:
|
|
reset_secret_scope(st)
|
|
reset_hermes_home_override(ht)
|
|
assert env.get("DEMO_ALLOWED_SENDER") == "someone@example.com"
|
|
assert "DISCORD_ALLOWED_CHANNELS" not in env
|
|
assert os.environ["DISCORD_ALLOWED_CHANNELS"] == "111" # the strip never mutates the process env
|