fix(gateway): honor QQ_GROUP_ALLOWED_USERS in runner auth

This commit is contained in:
dieutx
2026-04-15 20:06:35 +07:00
committed by Teknium
parent 590c9964e1
commit 995177d542
2 changed files with 57 additions and 1 deletions

View File

@@ -2618,6 +2618,9 @@ class GatewayRunner:
Platform.BLUEBUBBLES: "BLUEBUBBLES_ALLOWED_USERS",
Platform.QQBOT: "QQ_ALLOWED_USERS",
}
platform_group_env_map = {
Platform.QQBOT: "QQ_GROUP_ALLOWED_USERS",
}
platform_allow_all_map = {
Platform.TELEGRAM: "TELEGRAM_ALLOW_ALL_USERS",
Platform.DISCORD: "DISCORD_ALLOW_ALL_USERS",
@@ -2649,12 +2652,23 @@ class GatewayRunner:
# Check platform-specific and global allowlists
platform_allowlist = os.getenv(platform_env_map.get(source.platform, ""), "").strip()
group_allowlist = ""
if source.chat_type == "group":
group_allowlist = os.getenv(platform_group_env_map.get(source.platform, ""), "").strip()
global_allowlist = os.getenv("GATEWAY_ALLOWED_USERS", "").strip()
if not platform_allowlist and not global_allowlist:
if not platform_allowlist and not group_allowlist and not global_allowlist:
# No allowlists configured -- check global allow-all flag
return os.getenv("GATEWAY_ALLOW_ALL_USERS", "").lower() in ("true", "1", "yes")
# Some platforms authorize group traffic by chat ID rather than sender ID.
if group_allowlist and source.chat_type == "group" and source.chat_id:
allowed_group_ids = {
chat_id.strip() for chat_id in group_allowlist.split(",") if chat_id.strip()
}
if "*" in allowed_group_ids or source.chat_id in allowed_group_ids:
return True
# Check if user is in any allowlist
allowed_ids = set()
if platform_allowlist:

View File

@@ -21,6 +21,7 @@ def _clear_auth_env(monkeypatch) -> None:
"MATTERMOST_ALLOWED_USERS",
"MATRIX_ALLOWED_USERS",
"DINGTALK_ALLOWED_USERS", "FEISHU_ALLOWED_USERS", "WECOM_ALLOWED_USERS",
"QQ_ALLOWED_USERS", "QQ_GROUP_ALLOWED_USERS",
"GATEWAY_ALLOWED_USERS",
"TELEGRAM_ALLOW_ALL_USERS",
"DISCORD_ALLOW_ALL_USERS",
@@ -32,6 +33,7 @@ def _clear_auth_env(monkeypatch) -> None:
"MATTERMOST_ALLOW_ALL_USERS",
"MATRIX_ALLOW_ALL_USERS",
"DINGTALK_ALLOW_ALL_USERS", "FEISHU_ALLOW_ALL_USERS", "WECOM_ALLOW_ALL_USERS",
"QQ_ALLOW_ALL_USERS",
"GATEWAY_ALLOW_ALL_USERS",
):
monkeypatch.delenv(key, raising=False)
@@ -130,6 +132,46 @@ def test_star_wildcard_works_for_any_platform(monkeypatch):
assert runner._is_user_authorized(source) is True
def test_qq_group_allowlist_authorizes_group_chat_without_user_allowlist(monkeypatch):
_clear_auth_env(monkeypatch)
monkeypatch.setenv("QQ_GROUP_ALLOWED_USERS", "group-openid-1")
runner, _adapter = _make_runner(
Platform.QQBOT,
GatewayConfig(platforms={Platform.QQBOT: PlatformConfig(enabled=True)}),
)
source = SessionSource(
platform=Platform.QQBOT,
user_id="member-openid-999",
chat_id="group-openid-1",
user_name="tester",
chat_type="group",
)
assert runner._is_user_authorized(source) is True
def test_qq_group_allowlist_does_not_authorize_other_groups(monkeypatch):
_clear_auth_env(monkeypatch)
monkeypatch.setenv("QQ_GROUP_ALLOWED_USERS", "group-openid-1")
runner, _adapter = _make_runner(
Platform.QQBOT,
GatewayConfig(platforms={Platform.QQBOT: PlatformConfig(enabled=True)}),
)
source = SessionSource(
platform=Platform.QQBOT,
user_id="member-openid-999",
chat_id="group-openid-2",
user_name="tester",
chat_type="group",
)
assert runner._is_user_authorized(source) is False
@pytest.mark.asyncio
async def test_unauthorized_dm_pairs_by_default(monkeypatch):
_clear_auth_env(monkeypatch)