permission.test.ts 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import { describe, it, expect } from 'vitest';
  2. import { db } from '../../src/db';
  3. import { checkPermission } from '../../src/lib/auth/permission';
  4. import { eq } from 'drizzle-orm';
  5. import { users, groups, roles, permissions, userGroups, groupRoles, rolePermissions, userRoles, resources, aclRules } from '../../src/db/schema/auth';
  6. import { resources as resourceSchema, aclRules as aclRulesSchema } from '../../src/db/schema/resource';
  7. describe('Permission Engine Integration Tests', () => {
  8. // 注意:这些测试依赖于 Seed 脚本注入的数据
  9. // 管理员: admin@ekb.com
  10. // 测试用户: tester@ekb.com (已被禁止访问 /projects/secret)
  11. const ADMIN_EMAIL = 'admin@ekb.com';
  12. const TESTER_EMAIL = 'tester@ekb.com';
  13. it('should allow admin to access any resource via RBAC', async () => {
  14. // 获取管理员 ID
  15. const [admin] = await db.select().from(users).where(eq(users.email, ADMIN_EMAIL));
  16. // 模拟管理员上下文 (假设他属于一个拥有 editor 角色的组)
  17. // 在 Seed 中,admin 被赋予了 editor 角色
  18. const [engGroup] = await db.select().from(groups).where(eq(groups.name, 'Engineering Department'));
  19. const result = await checkPermission(
  20. { userId: admin.id, groupIds: [engGroup.id] },
  21. '/any/path',
  22. 'read',
  23. 'document'
  24. );
  25. expect(result.granted).toBe(true);
  26. });
  27. it('should deny tester access to secret folder due to explicit ACL deny rule', async () => {
  28. // 获取测试用户 ID
  29. const [tester] = await db.select().from(users).where(eq(users.email, TESTER_EMAIL));
  30. const result = await checkPermission(
  31. { userId: tester.id, groupIds: [] },
  32. '/projects/secret',
  33. 'read',
  34. 'document'
  35. );
  36. expect(result.granted).toBe(false);
  37. expect(result.reason).toBe('Explicitly denied by ACL rule');
  38. });
  39. it('should allow tester access to public folder (no deny rule)', async () => {
  40. const [tester] = await db.select().from(users).where(eq(users.email, TESTER_EMAIL));
  41. const result = await checkPermission(
  42. { userId: tester.id, groupIds: [] },
  43. '/public',
  44. 'read',
  45. 'document'
  46. );
  47. // 注意:由于 tester 本身没有 RBAC 权限,这里应该返回 false (Default Deny)
  48. expect(result.granted).toBe(false);
  49. });
  50. it('should respect path inheritance for ACL rules', async () => {
  51. const [tester] = await db.select().from(users).where(eq(users.email, TESTER_EMAIL));
  52. // 测试访问子路径 /projects/secret/sub-file,应该同样被拒绝
  53. const result = await checkPermission(
  54. { userId: tester.id, groupIds: [] },
  55. '/projects/secret/sub-file',
  56. 'read',
  57. 'document'
  58. );
  59. expect(result.granted).toBe(false);
  60. expect(result.reason).toBe('Explicitly denied by ACL rule');
  61. });
  62. });