组织权限与多人协作(2026-10-20)¶
历史记录 / Historical record:本文保留当时的计划、研究或验收证据,不代表 0.11 当前能力全集。现行说明见 文档入口;英文入口见 English overview。
用户要求组织成员、权限、项目与公告真正可协作,修复本机清单冒充云端状态,以及移除/降级不撤权的问题。
架构决定¶
使用现有清华 GitLab 私有群组及独立私有元数据项目,不部署新后端。现有组织通过「启用多人协作」显式迁移;已存项目、公告上传,未绑定 GitLab 账号的历史名单保留为待绑定资料。接收组织口令只定位组织,不授予权限,接收者必须已获得 GitLab 群组授权。
- 成员身份和角色以 GitLab 当前登录用户和群组成员 API 为准;本地
onethu.orgs.v1仅保存缓存与连接引用。 onethu-admin/organization.json保存组织资料、成员的云盘邮箱绑定、关联资源及未完成的权限操作。服务器保护分支只允许 Maintainer 级以上写入;OneTHU 的受管群组只接受 Owner 50、Developer 30、Reporter 20,不接受 Maintainer 40 或额外元数据项目授权,确保只有 Owner 达到管理分支的写门槛。onethu-content/collaboration.json保存项目、公告;服务器保护分支允许 Developer 及 Owner 写,Reporter 只读。- 每次读回检查私有性、项目所属群组、额外直接/共享群组授权、分支保护(包括通配规则、指定用户/群组/deploy key 例外)。异常时拒绝写入,不能只相信缓存里的负责人标记。
- 组织页进入、重新聚焦及可见时每 30 秒读取服务器;数据修改后立即读回。
并发与故障¶
提交携带 GitLab repository files API 的 last_commit_id。编辑还比较原始对象,避免把其他人的修改或删除覆盖掉;冲突保留输入,提示用户刷新、比较、重新编辑。初始化重试发现远端已有合法文档时仅校验归属并读回,不用本地旧资料覆盖。群组与元数据项目路径由组织 ID 稳定派生;创建响应丢失后先按路径查回,同页初始化复用同一个进行中的请求,避免双击创建重复资源。
权限变更先写入受保护配置文件中的操作记录,再执行服务端成员及资源更新,最后回读确认并清除操作记录。失败保留详情和「重试未完成的权限变更」,不会把部分成功显示为全部完成。
- 操作前审计云盘资料库:操作者必须是所有者;存在独立群组、全员、子目录共享或公开链接等旁路时阻止权限变更,提示负责人先处理,避免撤销账号共享却仍能访问。
- 关联 GitLab 仓库必须位于本组织的私有群组内,且没有额外共享群组或未知直接成员;拒绝 public/internal 或外部命名空间仓库。组织建仓只提供私有仓库,资料库只复制需要登录的成员入口,不生成公开链接。
- 迁移已有资料库/仓库也要完成同样审计和权限核对,才保存
permissionsVerified;未完成显示具体错误,不冒充可协作。 - 新关联先检查成员云盘邮箱和资源 ACL,再保存权限操作。已有未完成操作允许补/修正成员邮箱或解除资源关联,保留所有曾尝试的邮箱以撤回响应丢失留下的授权;禁止趁重试另改角色或添加成员。
- 增加/角色变更:GitLab 群组、关联仓库及云盘资料库逐项核对。
- 移除:撤回群组和关联资源访问;存在其他继承授权时明确报错,不谎称已失去访问。
- 换云盘邮箱:先撤旧邮箱,再给新邮箱授权;任一撤权失败时继续尝试其他已审计资源的独立撤权/降权,随后停止全部新增授权。前置审计失败则整个操作不产生权限变更。
- 资料库所有者拥有固有权限,降为只读/移除前必须先转移所有权。
- 解除资源关联清理本组织管理的直接授权;资源本身及其固有所有权/群组继承关系保留。
- 至少保留一位服务端 Owner;不让操作者自行降级/移除后留下无法完成的操作记录。
跨 GitLab 与 Seafile 没有分布式事务。因此这里采用可恢复的操作记录和幂等期望状态核对,不声称原子事务。其他管理员若直接在 GitLab/云盘操作,界面刷新后会反映实际权限或明确指出冲突。
验证与真实边界¶
node --import ./tools/ts-resolve-register.mjs tools/org-collaboration-test.mjs:38 条可执行协议测试,含撤权、降级、换邮箱、网络失败重试、幂等、服务端拒绝、继承权限、CAS对象冲突。服务端为内存模拟。node tools/org-collaboration-browser-test.mjs:25 条断言,两个独立浏览器上下文,模拟服务端执行 ACL/CAS,运行实际orgSync,验证迁移、多人读写、拒绝越权、并发冲突、降级/移除以及重载,并覆盖缺邮箱迁移恢复、已尝试邮箱清理、无效资源预检与初始化响应丢失恢复。tools/lib/fake-org.mjs是仅测试用 GitLab 服务模拟,不接触真实账号或资源。node tools/org-collaboration-live.mjs --run-isolated:需要GITLAB_TOKEN;可选GITLAB_SECOND_TOKEN。只新建独立、唯一名称的私有测试群组,验证后请求删除;不碰已有资源,不输出或保存令牌。- 当前没有配置可用 GitLab API 测试令牌,用户也暂无第二账号。因此真实 GitLab 实例的写接口、双账号授权/撤回仍待运行 live 测试,不能以模拟绿灯代替。
API 依据:Repository files、Protected branches、Group members。
本轮浏览器回归还确认:组织页面 29 条、名片/通讯录 23 条、体验模式 83 条均完成且进程 exit 0。所有组织浏览器数据均为隔离夹具,不代表真实双账号联调。