| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- import {
- AgentPermission,
- buildConfigJson,
- buildGrantCommands,
- canCommand,
- defaultPermission,
- Delegation,
- validatePermission,
- } from './agent-permission';
- /**
- * 容器权限配置 —— 纯函数层。
- *
- * 界面「配了什么」必须和「生成给容器的是什么」一致,
- * 所以生成与校验放在这里测,不依赖组件。
- */
- const OWNER = '@owner:fmode.cn';
- const GROUP = '!group1:fmode.cn';
- const d = (over: Partial<Delegation> = {}): Delegation => ({
- grantee: '@peer:fmode.cn',
- granteeName: '同事容器',
- groupId: GROUP,
- scope: ['read', 'execute'],
- expiresAt: new Date(Date.now() + 30 * 86400000).toISOString(),
- ...over,
- });
- const perm = (over: Partial<AgentPermission> = {}): AgentPermission => ({
- ...defaultPermission('agent-a'),
- ownerMxId: OWNER,
- delegations: [],
- ...over,
- });
- describe('默认配置', () => {
- it('默认不开放任何授权(安全基线)', () => {
- const p = defaultPermission('a');
- expect(p.delegations).toEqual([]);
- expect(p.allowAnyoneInGroups).toBeFalse();
- });
- });
- describe('buildConfigJson', () => {
- it('按《组长授权机制》§3.2 的结构输出', () => {
- const json = buildConfigJson(perm({ delegations: [d()] }));
- const parsed = JSON.parse(json);
- expect(parsed.workgroupDelegations.length).toBe(1);
- const item = parsed.workgroupDelegations[0];
- expect(item.delegateFrom).toBe('@peer:fmode.cn');
- expect(item.groupId).toBe(GROUP);
- expect(item.scope).toEqual(['read', 'execute']);
- // grantedBy 必须是主人,不能是别人
- expect(item.grantedBy).toBe(OWNER);
- });
- it('没有授权时输出空数组', () => {
- expect(JSON.parse(buildConfigJson(perm())).workgroupDelegations).toEqual([]);
- });
- it('缺省字段补空串而非 undefined(容器解析不炸)', () => {
- const json = buildConfigJson(perm({ delegations: [d({ groupId: undefined, expiresAt: undefined })] }));
- const item = JSON.parse(json).workgroupDelegations[0];
- expect(item.groupId).toBe('');
- expect(item.expiresAt).toBe('');
- });
- });
- describe('buildGrantCommands', () => {
- it('生成可复制的 fmode-delegate 命令', () => {
- const [cmd] = buildGrantCommands(perm({ delegations: [d()] }));
- expect(cmd).toContain('fmode-delegate grant');
- expect(cmd).toContain('@peer:fmode.cn');
- expect(cmd).toContain(`--group "${GROUP}"`);
- expect(cmd).toContain('--scope read,execute');
- expect(cmd).toContain('--days 30');
- });
- it('没有授权时不生成命令', () => {
- expect(buildGrantCommands(perm())).toEqual([]);
- });
- it('天数至少为 1(过期时间算出来是 0 或负数时)', () => {
- const soon = d({ expiresAt: new Date(Date.now() + 1000).toISOString() });
- const [cmd] = buildGrantCommands(perm({ delegations: [soon] }));
- expect(cmd).toContain('--days 1');
- });
- });
- describe('validatePermission', () => {
- it('规范配置无问题', () => {
- expect(validatePermission(perm({ delegations: [d()] }))).toEqual([]);
- });
- it('开启「群内任何人」会报警', () => {
- const issues = validatePermission(perm({ allowAnyoneInGroups: true }));
- expect(issues.some((i) => i.includes('任何进群的成员'))).toBeTrue();
- });
- it('管理员权限被标记为强烈不建议', () => {
- const issues = validatePermission(perm({ delegations: [d({ scope: ['read', 'admin'] })] }));
- expect(issues.some((i) => i.includes('强烈不建议'))).toBeTrue();
- });
- it('未指定群会报警', () => {
- const issues = validatePermission(perm({ delegations: [d({ groupId: undefined })] }));
- expect(issues.some((i) => i.includes('未指定群'))).toBeTrue();
- });
- it('没有权限范围会报警', () => {
- const issues = validatePermission(perm({ delegations: [d({ scope: [] })] }));
- expect(issues.some((i) => i.includes('没有选择任何权限'))).toBeTrue();
- });
- it('未设过期时间会报警', () => {
- const issues = validatePermission(perm({ delegations: [d({ expiresAt: undefined })] }));
- expect(issues.some((i) => i.includes('永久有效'))).toBeTrue();
- });
- it('过期时间已过会报警', () => {
- const past = d({ expiresAt: new Date(Date.now() - 86400000).toISOString() });
- expect(validatePermission(perm({ delegations: [past] })).some((i) => i.includes('已过'))).toBeTrue();
- });
- it('重复授权会报警', () => {
- const issues = validatePermission(perm({ delegations: [d(), d()] }));
- expect(issues.some((i) => i.includes('重复授权'))).toBeTrue();
- });
- it('缺主人身份时提示授权无人可用', () => {
- const issues = validatePermission(perm({ ownerMxId: undefined, delegations: [d()] }));
- expect(issues.some((i) => i.includes('缺少容器主人'))).toBeTrue();
- });
- });
- describe('canCommand(与容器逻辑对齐的预演)', () => {
- it('主人永远可以', () => {
- expect(canCommand(perm(), OWNER, GROUP).allowed).toBeTrue();
- expect(canCommand(perm(), OWNER, GROUP).reason).toBe('容器主人');
- });
- it('已授权的人在指定群可以', () => {
- const r = canCommand(perm({ delegations: [d()] }), '@peer:fmode.cn', GROUP);
- expect(r.allowed).toBeTrue();
- expect(r.reason).toContain('已授权');
- });
- // 群限制是授权的核心保护之一
- it('🔴 出了指定群就不行', () => {
- const r = canCommand(perm({ delegations: [d()] }), '@peer:fmode.cn', '!other:fmode.cn');
- expect(r.allowed).toBeFalse();
- });
- it('过期后不行', () => {
- const expired = d({ expiresAt: new Date(Date.now() - 1000).toISOString() });
- const r = canCommand(perm({ delegations: [expired] }), '@peer:fmode.cn', GROUP);
- expect(r.allowed).toBeFalse();
- expect(r.reason).toBe('授权已过期');
- });
- it('未授权的人不行', () => {
- expect(canCommand(perm(), '@stranger:fmode.cn', GROUP).allowed).toBeFalse();
- });
- it('开启「群内任何人」后任何人都可以在群里指挥', () => {
- const p = perm({ allowAnyoneInGroups: true });
- expect(canCommand(p, '@stranger:fmode.cn', GROUP).allowed).toBeTrue();
- // 但不在群里(无 groupId)时依然不行
- expect(canCommand(p, '@stranger:fmode.cn', undefined).allowed).toBeFalse();
- });
- it('scope 为空的授权不生效', () => {
- const r = canCommand(perm({ delegations: [d({ scope: [] })] }), '@peer:fmode.cn', GROUP);
- expect(r.allowed).toBeFalse();
- });
- });
|