mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
fix(gateway): bridge nested DingTalk allowed_users into auth env
The DingTalk docs offer gateway.platforms.dingtalk.extra.allowed_users
as the config.yaml alternative to DINGTALK_ALLOWED_USERS. The adapter
honors it (_load_allowed_users reads PlatformConfig.extra), but gateway
authorization (_is_user_authorized in gateway/authz_mixin.py) only
consults the env var, and load_gateway_config() bridged the allowlist
to the env var only from a top-level dingtalk: block. A nested-only
allowlist therefore passed the adapter and was then denied at the
gateway - listed users fell through to pairing/default-deny in DMs.
Extend the DingTalk YAML->env bridge to fall back to the merged nested
platform config (gateway.platforms / platforms), mirroring the existing
platforms.discord.extra.allow_from precedent. Precedence is unchanged:
an explicit DINGTALK_ALLOWED_USERS env var still wins, then the
top-level dingtalk: block, then the nested extra.
Also correct the docs' claim that the two allowlists are "merged" when
both are set - that behavior never existed (the doc line came from a
docs-only sweep); the effective result is the intersection of the two
gates, so the docs now recommend configuring one or the other.
Repro (before): config.yaml containing only the nested allowlist ->
adapter._is_user_allowed("user-id-1") is True but
runner._is_user_authorized(...) is False. After: both True; unlisted
users are still denied.
This commit is contained in:
parent
330b224525
commit
222772ad61
4 changed files with 185 additions and 2 deletions
|
|
@ -1660,6 +1660,31 @@ def _apply_yaml_config(yaml_cfg: dict, dingtalk_cfg: dict) -> dict | None:
|
|||
ac = ",".join(str(v) for v in ac)
|
||||
os.environ["DINGTALK_ALLOWED_CHATS"] = str(ac)
|
||||
allowed = dingtalk_cfg.get("allowed_users")
|
||||
if allowed is None:
|
||||
# Fall back to the documented nested paths (#44928). The docs
|
||||
# (website/docs/user-guide/messaging/dingtalk.md) configure the
|
||||
# allowlist at gateway.platforms.dingtalk.extra.allowed_users; the
|
||||
# adapter reads it from PlatformConfig.extra, but gateway
|
||||
# authorization (_is_user_authorized in gateway/authz_mixin.py)
|
||||
# only consults DINGTALK_ALLOWED_USERS — without this bridge a
|
||||
# nested-only allowlist passes the adapter and is then denied at
|
||||
# the gateway. Check this block's own extra first (the dispatch
|
||||
# loop passes the platforms block here when no top-level
|
||||
# ``dingtalk:`` section exists), then both nested containers.
|
||||
_extra = dingtalk_cfg.get("extra")
|
||||
if isinstance(_extra, dict):
|
||||
allowed = _extra.get("allowed_users")
|
||||
if allowed is None:
|
||||
_gw = yaml_cfg.get("gateway")
|
||||
_gw_platforms = _gw.get("platforms") if isinstance(_gw, dict) else None
|
||||
for _container in (_gw_platforms, yaml_cfg.get("platforms")):
|
||||
if not isinstance(_container, dict):
|
||||
continue
|
||||
_dt = _container.get("dingtalk")
|
||||
_dt_extra = _dt.get("extra") if isinstance(_dt, dict) else None
|
||||
if isinstance(_dt_extra, dict) and _dt_extra.get("allowed_users") is not None:
|
||||
allowed = _dt_extra.get("allowed_users")
|
||||
break
|
||||
if allowed is not None and not os.getenv("DINGTALK_ALLOWED_USERS"):
|
||||
if isinstance(allowed, list):
|
||||
allowed = ",".join(str(v) for v in allowed)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue