feat(lark): 支持可信 OnCall 拉群后自动开放当前群对话权限 - #1034
Conversation
|
感谢投入!这个方向(可信 OnCall 拉群 → 自动开放本群对话,且只给 talk 不给 operate)是合理的,落盘走 1)(建议合前修)
也就是说:一次自动授权会让这个 bot 在所有其它群失去对话能力,且包括 owner 在内没有人能再跑 顺带两处同一判据的第二实现没跟上,建议一起对齐:
2)(建议合前修)owner 没有办法撤销自动授权
3) 你写这个 PR 时的 base( 4) 与既有机制的重叠(不阻塞,想听你的想法)
5) 小项
关于测试:我用反向变异验了一下现有覆盖——把 基线我这边是干净的:干净 HOME 下 以上是自动评审的初步意见,可能有误判,也不代表最终结论 —— 最终以维护者审阅为准。如果哪条你觉得判断不对,欢迎直接反驳。 |
|
补充几条(交叉复审后的增量,同样都是实测复现),以及对上一条评论里 ① 的一个更好的修法: ① 的推荐修法:把 我上一条只报了问题没给方案,这里补上。你把它加进总闸的动机应该是怕 fail-open,但这一行其实是不需要的,而且正是它造成了那个副作用:
我把这行删掉后跑了四象限验证:
即原则是「自动事件不应翻转全局安全姿态」。这一行改动就能修掉 ①,且不影响这个特性本身要达成的效果。 ②a 新增: 当一个群同时在 ②b 新增: 自动授权群里的 talk 来自「群成员身份」而不是 ②c 新增(小,但方向偏不安全侧):
这里做个校准,避免让你多背责任:同样的形状在 master 的 另外上一条评论里 ③( 关于 ① 的严重性,我们也复核了触发面:dashboard onboarding(明确「绝不产出空 allowedUsers 的可启动 bot」)、交互式 setup( 以上依然是自动评审的初步意见,可能有误判,最终以维护者审阅为准。 |
6c6a687 to
f84be97
Compare
|
谢谢更新, 三条修复的实测结果① 总闸 —— 已修,且报警器也补上了 把
我们上一轮特别担心「缺陷修了但报警器还是坏的」(那行原本零覆盖)——这次没有发生:把那行加回去(等于把缺陷复原),测试立刻红一条,红的是 ② 我们原本只建议在调用方多清一次,你改的是 原子性我们也走了一遍 ③ 事件处理器 —— 已合并,不是二选一 现在只注册一次, 一条非阻断建议:给「不 mock」的那份测试补一条用例我们做了一个分文件的检查,结果值得告诉你:
也就是说,① 这条缺陷的报警器完全长在 mock 那一侧。我们顺手把 mock 与真 store 的内存侧写抽出来跑了同一串操作序列(重复 add、删不存在的、删到空、删空后再 add),7/7 逐步一致,所以当下是可靠的、不影响这次的结论。 但它的可靠性依赖「这份手抄的 mock 与真实现保持同步」,而这件事没有任何机制维护 —— 以后真 store 改了内存侧语义(比如去重、排序、或改成不删空字段),mock 不会跟着变,测试照绿,报警器就悄悄失效了。 建议:在 另外要更正我们上一轮的一条意见上一轮我们说「还有两处权限判断没跟上( 因为 ① 的正确修法是把这份名单从总闸里拿掉,而那两处正是同一个总闸的另外两个实现。如果「对齐」了,等于把 ① 的缺陷在卡片路径上重新引入一遍(无 owner 的 bot 自动授权后,所有卡片按钮会全部失效)。修复方向反转之后,我们基于旧方向提的对齐建议就不成立了,抱歉带来困扰。 还有一个待维护者定的方向问题(不是代码问题)我们注意到 而且 所以有个方向问题想请你和维护者一起定:这道门是否可以做成 以上仍是自动评审的意见,最终以维护者审阅为准。代码质量上我们这边已经没有阻断项了。 |
|
维护者已就上一条里的方向问题做了决定:采纳方向 B —— 请把这个能力收敛到现有 先说清楚:代码质量上我们已经没有阻断项了,上一轮三条都修得很干净。这次是产品/架构方向上的决定,所以还要请你再改一轮,辛苦。 为什么是 B
但有一个坎,麻烦你先评估再动手我们读了代码,B 有一个时机错配要解决,先说出来免得你踩:
所以不能简单地在
另外提醒一个约束: 还有一条建议一起做掉(原本非阻断)
原因是我们做了个分文件检查:把上一轮 ① 的缺陷复原后,只跑不 mock 的那份测试是全绿的(抓不到),只有 既然要再改一轮,顺手把这条补上比较划算。 小结
以上仍是自动评审的意见,方向决定来自维护者;具体实现方案以你和维护者商定为准。 |
|
更正上一条里我的一处不准确表述,免得你按错的描述去找代码: 我写「路径② 在 export async function autoBindOncallFromDefault(
larkAppId: string,
chatId: string,
workingDir: string,
): Promise<…>operator 是在调用点的作用域里才有的( 另外补两条我们核实过的细节,对你评估方案有用: 1)如果你想走第三种方案「可信拉群 → 只开 talk、不绑 workingDir」,摩擦比表面更大。 现在 .filter((c: any) => c && typeof c.chatId === 'string' && typeof c.workingDir === 'string')也就是条目必须带 所以如果你因为「不想绑工作目录」而认为 B 不合适、倾向保留独立实现或提第三种方案,这个理由是站得住的,我们不会视为回避 —— 请直接把它写在 PR 描述或回复里,我们会带着这条重新和维护者确认方向。不必为了迁就 B 去改存量 schema。 2)行号更正: 结论不变:方向 B 是维护者的决定,但先评估、评估后觉得不合适可以反馈,比硬套更重要。 |
|
再更正一次我上一条的「行号更正」—— 抱歉,上一条给你的行号是按 准确的定位(用代码片段 + 基线标注,避免再错): 1) defaultOncall = { enabled: enabled && !!workingDir, workingDir, since };
master 在你的 rebase 基点之后又进了约 6 行改动,所以同一句漂移了。 2) export async function ensureDefaultOncallBound(
larkAppId: string,
chatId: string,
chatType: 'group' | 'p2p',
): Promise<OncallChat | undefined>3) .filter((c: any) => c && typeof c.chatId === 'string' && typeof c.workingDir === 'string')以后我们引用位置会统一用「代码片段 +(必要时) 其余结论都不变:方向 B 是维护者的决定,但请先评估那两个坎(operator 时机错配、 |
|
这个 PR 下面已经积了 6 条评论,其中最后三条是我在自我更正,读起来确实乱。这条把当前仍然有效的事项汇总成一份,作为唯一口径,前面几条如有冲突以本条为准(不含新内容,只做收敛)。 已完成,无需再动v2(
代码层面我们没有阻断意见。 待你处理(按优先级)1. 先评估方向 B 的可行性,再决定动不动手(维护者决定的方向,但评估结论可以反馈) 把这个能力收敛到现有
2. 补一条测试(建议,非阻断) 在 我方已作废的意见(不用管)
定位信息(以你的分支
|
改动说明
BotConfig,新增可信拉群 operator 与自动群聊授权配置,并在解析时 trim、去空、去重。rmwBotEntry()原子持久化autoOncallChats,同时热更新内存配置。im.chat.member.bot.added_v1:仅可信 operator 拉群时为当前 bot × 当前 chat 开放对话。im.chat.member.bot.deleted_v1:bot 退群时仅清理自动来源授权,保留人工allowedChatGroups。canTalk白名单判断,并补充 Store 与事件分发测试。安全边界
open_id精确匹配。canTalk,不开放canOperate;/restart、/grant、/cd等管理能力仍受原权限控制。验证
pnpm vitest run --project unit test/auto-oncall-store.test.ts test/event-dispatcher.test.tspnpm build通过。autoOncallChats/auto-oncall逻辑。本 PR 不包含真实 ByteOncall
open_id。