From 6990607c5c920a57b750c6d441e357baa6b71f59 Mon Sep 17 00:00:00 2001 From: Dongze Yang <50231148+ydzat@users.noreply.github.com> Date: Tue, 27 Oct 2026 13:18:51 +0100 Subject: [PATCH] Merge pull request #2743 from ydzat/fix/normalize-access-control-ids fix(pipeline): normalize IDs in wildcard access control --- src/langbot/pkg/pipeline/bansess/bansess.py | 2 +- tests/unit_tests/pipeline/test_bansess.py | 24 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/langbot/pkg/pipeline/bansess/bansess.py b/src/langbot/pkg/pipeline/bansess/bansess.py index a1cad2b1d..6ed3631e4 100644 --- a/src/langbot/pkg/pipeline/bansess/bansess.py +++ b/src/langbot/pkg/pipeline/bansess/bansess.py @@ -31,7 +31,7 @@ class BanSessionCheckStage(stage.PipelineStage): found = True break # 使用 *_id 来表示加白/拉黑某用户的私聊和群聊场景 - if sess.startswith('*_') and (sess[2:] == query.launcher_id or sess[2:] == query.sender_id): + if sess.startswith('*_') and (sess[2:] == str(query.launcher_id) or sess[2:] == str(query.sender_id)): found = True break diff --git a/tests/unit_tests/pipeline/test_bansess.py b/tests/unit_tests/pipeline/test_bansess.py index 394fb8bc1..8a369e10e 100644 --- a/tests/unit_tests/pipeline/test_bansess.py +++ b/tests/unit_tests/pipeline/test_bansess.py @@ -136,3 +136,27 @@ async def test_user_id_wildcard(mock_app, sample_query): result = await stage.process(sample_query, 'BanSessionCheckStage') assert result.result_type == entities.ResultType.CONTINUE + + +@pytest.mark.asyncio +@pytest.mark.parametrize('mode', ['whitelist', 'blacklist']) +@pytest.mark.parametrize('launcher_type', [provider_session.LauncherTypes.PERSON, provider_session.LauncherTypes.GROUP]) +@pytest.mark.parametrize('id_type', [int, str]) +@pytest.mark.parametrize('matching_field', ['sender_id', 'launcher_id', None]) +async def test_user_id_wildcard_normalizes_ids(mock_app, sample_query, mode, launcher_type, id_type, matching_field): + """Wildcard IDs match numeric platform IDs without allowing unrelated users.""" + bansess, entities = get_modules() + sample_query.launcher_type = launcher_type + sample_query.launcher_id = id_type(11111) + sample_query.sender_id = id_type(22222) + if matching_field is not None: + setattr(sample_query, matching_field, id_type(67890)) + sample_query.pipeline_config = {'trigger': {'access-control': {'mode': mode, mode: ['*_67890']}}} + + stage = bansess.BanSessionCheckStage(mock_app) + await stage.initialize(sample_query.pipeline_config) + result = await stage.process(sample_query, 'BanSessionCheckStage') + + should_continue = (matching_field is not None) if mode == 'whitelist' else (matching_field is None) + expected = entities.ResultType.CONTINUE if should_continue else entities.ResultType.INTERRUPT + assert result.result_type == expected