Files
MailUI4Agents/server/internal/repo/workspace_scope_test.go
JianFeeeee a5fc86bc1a fix(addressing)!: 寻址不按工作区筛 + 联系人地址不再从垃圾 from_workspace 拼
用户:「任意 agent 的寻址是任意的,而不是按工作区区分,去落实吧」。

① 拆掉两处"按工作区收窄"(那是我把**寻址**当成了**权限**):
   · AgentListContacts 不再走 ListContactsInWorkspace ⇒ 列表 = 我参与过的会话(事实,不是授权);
   · AgentSuggestAddress 的会话候选不再走 SuggestSessionCandidatesInWorkspace。
   两个 InWorkspace 变体(连同钉旧口径的用例)一并删除,避免死代码。
   生产实测:pi 的联系人从"只剩同工作区"变成 5 条,横跨 TrueAgent/agentmail/其它工作区。
   agentScope 仍调用(校验 session_id 格式 + 未声明时告警),只是它的工作区不再当过滤器。

② 联系人地址的 path 取自**会话**,不再取第一封邮件的 from_workspace:
   `COALESCE(NULLIF(s.workspace,''), NULLIF(m.to_workspace,''), '')`。
   那条老路把地址拼成 `zcode@zcode.<别名>` —— 正是用户预言的"感染":一个可被复制出去的
   错误地址。from_workspace 与"对方在哪"无关,只用 to_*。

③ **清除感染源(数据)**:658 行 from_workspace = from_name(pi 406 / dsh 137 / zcode 89 /
   homeagent 17 / opencode 9)已清空。带去重前备份(/root/gotmp/agentmail-pre-fromws-purge-*.db)
   与回滚脚本,回滚**在副本库上真跑过**(恢复 658 行)才敢落地。
2026-09-15 10:07:18 +08:00

64 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package repo
import (
"context"
"testing"
"github.com/google/uuid"
)
/*
工作区维度:一个 Agent 同时服务**所有**工作区,所以"参与过"不等于"该看"。
# 用户报的缺陷
「agentmail 工作区的邮件会话被 trueagent 工作区的 agent 看到了,还需要我亲自去解释。」
根因不是某处漏了一个 WHERE,而是**隔离单位选的是 Agent**:
- `AgentCanAccessSession(agentName, sid)` 判的是「这个 Agent 名出现在这条会话的
from/to/cc 里」;
- 而 Agent 注册时 `workspaces` 是空的(B-1.2:cwd 由每封邮件的 `to_workspace`
决定),于是同一个 agent `pi` 既"参与过" agentmail 的会话、也"参与过"
TrueAgent 的会话 —— 两个工作区之间没有任何边界。
现场证据:`mail_reads` 里 2026-09-14 08:11–09:19 有 8 次"同一瞬间读了多个不同工作区
的会话"(最典型 08:23:59 一次跨 agentmail / TrueAgent / webui4frpc 三条会话),
而那正是按 Agent 整表读的特征。更要紧的是 `mail_reads` 只记 `reader_name`,
**没有"读的人当时在哪个工作区"这一列** —— 这类越界读在数据上与正常读无法区分。
# 判据两侧都验
只验"跨工作区被拒"是不够的:把函数写成永远拒绝也能过。所以同时验
- 同工作区必须放行(否则等于把所有 Agent 都锁死);
- 未声明 scope 时的旧语义(迁移期妥协,必须明确写下来,不能靠"没人测"存在);
- 拒绝的**原因**要分得清(没参与过 vs 跨工作区)—— 否则调用方无法自查;
- 列表类接口的反向对照:不带收窄时两条会话都在(证明收窄真的在起作用)。
*/
func sessionIn(t *testing.T, agent, ws, title string) uuid.UUID {
t.Helper()
id, err := CreateSession(context.Background(), nil, "human", title, ws)
if err != nil {
t.Fatalf("create session(%s): %v", title, err)
}
seedMailInSession(t, id, agent)
return id
}
func TestListContactsWithEmptyScopeStillWorks(t *testing.T) {
setupTestDB(t)
ctx := context.Background()
sessionIn(t, "pi", "/home/program/agentmail", "随便一条线索")
all, err := ListContactsFor(ctx, "", false)
if err != nil {
t.Fatalf("scope 为空(管理员看全部)不该报错:%v", err)
}
if len(all) != 1 {
t.Fatalf("应当列出 1 条(实际 %d 条)", len(all))
}
}