feat(authz): 重写权限模板分配与班级授权边界
拆分能力、分配范围和业务关系,固定管理员能力并收紧组织级写入口。 补齐内容、课表、设备会话和实时通道授权,兼容旧库分配及历史快照。 重写权限分配预览,按实际可操作范围展示维护入口,合并学生入口并独立学年升级页。 增加授权攻击矩阵及静态门禁,更新隔离回归与开发契约。 验证:授权矩阵 23 段通过,Node 24 下 Web 63/63,类型检查、lint 与文档严格构建通过。
This commit is contained in:
1 parent
682818dd4a
commit
66be3a63b1
115 files changed
+4463
-2747
No files matched your search
@@ -1563,28 +1563,18 @@ async function main() {
|
||||
`含 homework:write=${teacher2ResetPermissions.includes('homework:write')}`,
|
||||
);
|
||||
|
||||
// 管理员可以分配权限组,但始终保留两个管理入口
|
||||
const assignAdmin = await api(`/permissions/users/${adminMember?.id}/groups`, {
|
||||
method: 'PUT',
|
||||
token: adminToken,
|
||||
body: { groupIds: permissionGroupId ? [permissionGroupId] : [] },
|
||||
body: { assignments: [] },
|
||||
});
|
||||
const fixedAdmin = await api('/permissions/me', { token: adminToken });
|
||||
record(
|
||||
'管理员可以分配权限组(PUT /users/:id/groups → 200)',
|
||||
Boolean(adminMember) &&
|
||||
assignAdmin.status === 200 &&
|
||||
Array.isArray(assignAdmin.payload?.data?.permissions) &&
|
||||
assignAdmin.payload.data.permissions.includes('permission:manage') &&
|
||||
assignAdmin.payload.data.permissions.includes('system:manage'),
|
||||
`status=${assignAdmin.status} 响应=${assignAdmin.payload?.message ?? ''}`,
|
||||
'管理员固定全集并拒绝分配模板',
|
||||
assignAdmin.status === 400 && fixedAdmin.payload?.data?.permissions.includes('teacher:manage'),
|
||||
`status=${assignAdmin.status}`,
|
||||
);
|
||||
|
||||
await api(`/permissions/users/${adminMember?.id}/groups`, {
|
||||
method: 'PUT',
|
||||
token: adminToken,
|
||||
body: { groupIds: [] },
|
||||
});
|
||||
|
||||
// 内置权限组不可删除:先找一个 builtin 的(**演示库当前没有内置组**,此时只报事实、不算失败)
|
||||
const groupsList = await api('/permissions/groups', { token: adminToken });
|
||||
const builtinGroup = (groupsList.payload?.data ?? []).find((item) => item.builtin === true) ?? null;
|
||||
|
||||
Reference in new issue
Block a user