mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-05-20 00:22:31 +00:00
docs(pairing): address reviewer comments — comments, error msg, __all__ test
- Clarify SystemExit message for missing/null allowFrom (manager.py) - Document why Feishu passes content="" for unauthorized DMs - Document exact-match semantics in BaseChannel.is_allowed() - Document negligible collision probability in generate_code() - Add test_all_exports_are_importable for nanobot.pairing.__all__
This commit is contained in:
parent
ac9a2d0c25
commit
199a1bb8fa
@ -202,6 +202,7 @@ class BaseChannel(ABC):
|
|||||||
allow_list = getattr(self.config, "allow_from", []) or []
|
allow_list = getattr(self.config, "allow_from", []) or []
|
||||||
if "*" in allow_list:
|
if "*" in allow_list:
|
||||||
return True
|
return True
|
||||||
|
# allowFrom entries are opaque tokens — must match exactly.
|
||||||
if str(sender_id) in allow_list:
|
if str(sender_id) in allow_list:
|
||||||
return True
|
return True
|
||||||
if is_approved(self.name, str(sender_id)):
|
if is_approved(self.name, str(sender_id)):
|
||||||
|
|||||||
@ -1716,6 +1716,8 @@ class FeishuChannel(BaseChannel):
|
|||||||
# Group chats are silently ignored; DMs get a pairing code.
|
# Group chats are silently ignored; DMs get a pairing code.
|
||||||
if not self.is_allowed(sender_id):
|
if not self.is_allowed(sender_id):
|
||||||
if chat_type == "p2p":
|
if chat_type == "p2p":
|
||||||
|
# content="" because the pairing reply is generated by
|
||||||
|
# BaseChannel._handle_message, not from the original message.
|
||||||
await self._handle_message(
|
await self._handle_message(
|
||||||
sender_id=sender_id,
|
sender_id=sender_id,
|
||||||
chat_id=sender_id,
|
chat_id=sender_id,
|
||||||
|
|||||||
@ -145,7 +145,7 @@ class ChannelManager:
|
|||||||
allow = getattr(cfg, "allow_from", None)
|
allow = getattr(cfg, "allow_from", None)
|
||||||
if allow is None:
|
if allow is None:
|
||||||
raise SystemExit(
|
raise SystemExit(
|
||||||
f'Error: "{name}" is missing allowFrom. '
|
f'Error: "{name}" is missing or null allowFrom. '
|
||||||
f'Set ["*"] to allow everyone, or add specific user IDs.'
|
f'Set ["*"] to allow everyone, or add specific user IDs.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -82,6 +82,8 @@ def generate_code(
|
|||||||
with _LOCK:
|
with _LOCK:
|
||||||
data = _load()
|
data = _load()
|
||||||
_gc_pending(data)
|
_gc_pending(data)
|
||||||
|
# Collision probability is negligible (~1e-12 with 20 pending codes),
|
||||||
|
# so we skip an existence check for simplicity.
|
||||||
raw = "".join(secrets.choice(_ALPHABET) for _ in range(_CODE_LENGTH))
|
raw = "".join(secrets.choice(_ALPHABET) for _ in range(_CODE_LENGTH))
|
||||||
code = f"{raw[:4]}-{raw[4:]}"
|
code = f"{raw[:4]}-{raw[4:]}"
|
||||||
|
|
||||||
|
|||||||
@ -2,9 +2,18 @@ import time
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from nanobot.pairing import __all__ as pairing_all
|
||||||
from nanobot.pairing import store
|
from nanobot.pairing import store
|
||||||
|
|
||||||
|
|
||||||
|
def test_all_exports_are_importable():
|
||||||
|
"""Every name in __all__ must actually be importable from nanobot.pairing."""
|
||||||
|
import nanobot.pairing as pkg
|
||||||
|
|
||||||
|
for name in pairing_all:
|
||||||
|
assert hasattr(pkg, name), f"{name} is in __all__ but not exported"
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def _tmp_store(tmp_path, monkeypatch):
|
def _tmp_store(tmp_path, monkeypatch):
|
||||||
path = tmp_path / "pairing.json"
|
path = tmp_path / "pairing.json"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user