refactor: 移除dify:dataset:manage权限映射
数据库已经删除了统一的dify:dataset:manage权限(id:103), 保留了细分的CRUD权限: - dify:bind:list (查看) - dify:bind:create (创建) - dify:bind:update (更新) - dify:bind:delete (删除) 修改内容: 1. 从permission-mapper.ts中移除所有权限键映射 2. 现在前端直接显示数据库权限键,不再进行任何转换 3. 权限检查直接使用数据库中的细分权限 优势: - 更灵活的角色权限配置 - 不同角色可以拥有不同的操作组合 - 符合最小权限原则
This commit is contained in:
@@ -1,46 +1,36 @@
|
|||||||
/**
|
/**
|
||||||
* 权限键映射工具
|
* 权限键映射工具
|
||||||
* 用于将数据库中的权限键映射为前端显示的权限键
|
* 用于处理数据库权限键与路由装饰器检查权限键不一致的情况
|
||||||
*
|
|
||||||
* 问题背景:
|
|
||||||
* 数据库中的权限键(dify:bind:*)与路由实际检查的权限键(dify:dataset:*, dify:file:*)不一致
|
|
||||||
* 导致前端取消勾选后,后端仍然检查实际权限,权限控制失效
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限键映射表
|
* 权限键映射表
|
||||||
* key: 数据库中的权限键
|
* key: 数据库中的权限键
|
||||||
* value: 前端显示和实际生效的权限键
|
* value: 前端显示和实际生效的权限键
|
||||||
|
*
|
||||||
|
* 当前配置:不做映射,直接显示数据库权限键
|
||||||
|
* 因为权限已经细分为CRUD操作,不需要合并显示
|
||||||
*/
|
*/
|
||||||
const PERMISSION_KEY_MAP: Record<string, string> = {
|
const PERMISSION_KEY_MAP: Record<string, string> = {
|
||||||
// 知识库绑定相关 - 映射到数据集管理权限
|
// 知识库绑定相关 - 直接显示数据库权限键,不映射
|
||||||
'dify:bind:list': 'dify:dataset:manage',
|
// 'dify:bind:list': 'dify:bind:list',
|
||||||
'dify:bind:create': 'dify:dataset:manage',
|
// 'dify:bind:create': 'dify:bind:create',
|
||||||
'dify:bind:update': 'dify:dataset:manage',
|
// 'dify:bind:update': 'dify:bind:update',
|
||||||
'dify:bind:delete': 'dify:dataset:manage',
|
// 'dify:bind:delete': 'dify:bind:delete',
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反向映射表:实际权限键 -> 数据库权限键列表
|
* 反向映射表:实际权限键 -> 数据库权限键列表
|
||||||
* 用于检查某个权限是否被正确配置
|
* 当前配置:不进行反向映射
|
||||||
*/
|
*/
|
||||||
const REVERSE_PERMISSION_MAP: Record<string, string[]> = {
|
const REVERSE_PERMISSION_MAP: Record<string, string[]> = {
|
||||||
'dify:dataset:manage': [
|
// 'dify:bind:list': ['dify:bind:list'],
|
||||||
'dify:bind:list',
|
|
||||||
'dify:bind:create',
|
|
||||||
'dify:bind:update',
|
|
||||||
'dify:bind:delete',
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将数据库权限键转换为显示权限键
|
* 将数据库权限键转换为显示权限键
|
||||||
* @param permissionKey 数据库中的权限键
|
* @param permissionKey 数据库中的权限键
|
||||||
* @returns 前端显示的权限键
|
* @returns 前端显示的权限键(无映射时返回原值)
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* mapPermissionKey('dify:bind:list') // 返回 'dify:dataset:manage'
|
|
||||||
* mapPermissionKey('dify:file:read') // 返回 'dify:file:read'(无映射)
|
|
||||||
*/
|
*/
|
||||||
export function mapPermissionKey(permissionKey: string): string {
|
export function mapPermissionKey(permissionKey: string): string {
|
||||||
return PERMISSION_KEY_MAP[permissionKey] || permissionKey;
|
return PERMISSION_KEY_MAP[permissionKey] || permissionKey;
|
||||||
@@ -57,22 +47,23 @@ export function mapPermissionKeys(permissionKeys: string[]): string[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反向查找:根据实际权限键找到对应的数据库权限键列表
|
* 反向查找:根据显示权限键找到对应的数据库权限键
|
||||||
* @param effectivePermissionKey 实际生效的权限键(如 'dify:dataset:manage')
|
* @param effectivePermissionKey 显示权限键
|
||||||
* @returns 对应的数据库权限键列表
|
* @returns 对应的数据库权限键列表(无映射时返回原值)
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* findDbPermissionKeys('dify:dataset:manage')
|
|
||||||
* // 返回 ['dify:bind:list', 'dify:bind:create', 'dify:bind:update', 'dify:bind:delete']
|
|
||||||
*/
|
*/
|
||||||
export function findDbPermissionKeys(effectivePermissionKey: string): string[] {
|
export function reverseMapPermissionKey(permissionKey: string): string[] {
|
||||||
return REVERSE_PERMISSION_MAP[effectivePermissionKey] || [effectivePermissionKey];
|
// 查找所有映射到该权限键的原始权限键
|
||||||
|
const originalKeys: string[] = [];
|
||||||
|
for (const [key, mappedKey] of Object.entries(PERMISSION_KEY_MAP)) {
|
||||||
|
if (mappedKey === permissionKey) {
|
||||||
|
originalKeys.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return originalKeys.length > 0 ? originalKeys : [permissionKey];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换权限对象:将数据库权限对象转换为显示权限对象
|
* 转换权限对象:将数据库权限对象转换为显示权限对象
|
||||||
* @param permission 权限对象(来自数据库)
|
|
||||||
* @returns 转换后的权限对象
|
|
||||||
*/
|
*/
|
||||||
export interface Permission {
|
export interface Permission {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -86,13 +77,10 @@ export interface Permission {
|
|||||||
export function mapPermission(permission: Permission): Permission {
|
export function mapPermission(permission: Permission): Permission {
|
||||||
const mappedKey = mapPermissionKey(permission.permission_key);
|
const mappedKey = mapPermissionKey(permission.permission_key);
|
||||||
|
|
||||||
// 如果权限键被映射,更新显示名称(可选)
|
// 如果权限键被映射,更新显示名称(可根据业务逻辑调整)
|
||||||
let displayName = permission.display_name;
|
let displayName = permission.display_name;
|
||||||
if (mappedKey !== permission.permission_key) {
|
if (mappedKey !== permission.permission_key) {
|
||||||
// 根据映射后的权限键更新显示名称
|
// 这里可以添加自定义的显示名称映射逻辑
|
||||||
if (mappedKey === 'dify:dataset:manage') {
|
|
||||||
displayName = '知识库管理(查看、创建、编辑、删除)';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -113,7 +101,7 @@ export function mapPermissions(permissions: Permission[]): Permission[] {
|
|||||||
permissions.forEach(permission => {
|
permissions.forEach(permission => {
|
||||||
const mapped = mapPermission(permission);
|
const mapped = mapPermission(permission);
|
||||||
|
|
||||||
// 如果映射后的权限键已存在,合并(保留第一个或根据业务逻辑)
|
// 如果映射后的权限键已存在,合并(保留第一个)
|
||||||
if (!mappedMap.has(mapped.permission_key)) {
|
if (!mappedMap.has(mapped.permission_key)) {
|
||||||
mappedMap.set(mapped.permission_key, mapped);
|
mappedMap.set(mapped.permission_key, mapped);
|
||||||
}
|
}
|
||||||
@@ -122,51 +110,19 @@ export function mapPermissions(permissions: Permission[]): Permission[] {
|
|||||||
return Array.from(mappedMap.values());
|
return Array.from(mappedMap.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 反向转换:将显示权限键转换为数据库权限键列表(用于保存权限)
|
|
||||||
* @param permissionKey 显示权限键(如 'dify:dataset:manage')
|
|
||||||
* @returns 对应的数据库权限键列表
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* reverseMapPermissionKey('dify:dataset:manage')
|
|
||||||
* // 返回 ['dify:bind:list', 'dify:bind:create', 'dify:bind:update', 'dify:bind:delete']
|
|
||||||
*
|
|
||||||
* reverseMapPermissionKey('dify:file:read')
|
|
||||||
* // 返回 ['dify:file:read'](无映射)
|
|
||||||
*/
|
|
||||||
export function reverseMapPermissionKey(permissionKey: string): string[] {
|
|
||||||
// 查找所有映射到该权限键的原始权限键
|
|
||||||
const originalKeys: string[] = [];
|
|
||||||
for (const [key, mappedKey] of Object.entries(PERMISSION_KEY_MAP)) {
|
|
||||||
if (mappedKey === permissionKey) {
|
|
||||||
originalKeys.push(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return originalKeys.length > 0 ? originalKeys : [permissionKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据显示的权限ID查找对应的数据库权限ID(用于保存)
|
* 根据显示的权限ID查找对应的数据库权限ID(用于保存)
|
||||||
* 这是一个复杂操作,因为前端显示的权限ID是经过映射的
|
|
||||||
*
|
|
||||||
* @param displayPermissionId 前端显示的权限ID(映射后的)
|
|
||||||
* @param allMappedPermissions 所有映射后的权限列表(从路由获取的)
|
|
||||||
* @param originalPermissions 原始的权限列表(未映射的)
|
|
||||||
* @returns 对应的数据库权限ID列表
|
|
||||||
*/
|
*/
|
||||||
export function findDbPermissionIds(
|
export function findDbPermissionIds(
|
||||||
displayPermissionId: number,
|
displayPermissionId: number,
|
||||||
allMappedPermissions: Permission[],
|
allMappedPermissions: Permission[],
|
||||||
originalPermissions: Permission[]
|
originalPermissions: Permission[]
|
||||||
): number[] {
|
): number[] {
|
||||||
// 查找显示权限对应的显示权限对象
|
|
||||||
const displayPerm = allMappedPermissions.find(p => p.id === displayPermissionId);
|
const displayPerm = allMappedPermissions.find(p => p.id === displayPermissionId);
|
||||||
if (!displayPerm) return [];
|
if (!displayPerm) return [];
|
||||||
|
|
||||||
// 将显示权限键反向映射为数据库权限键列表
|
|
||||||
const dbKeys = reverseMapPermissionKey(displayPerm.permission_key);
|
const dbKeys = reverseMapPermissionKey(displayPerm.permission_key);
|
||||||
|
|
||||||
// 在原始权限列表中查找这些数据库权限键对应的ID
|
|
||||||
const dbIds: number[] = [];
|
const dbIds: number[] = [];
|
||||||
for (const key of dbKeys) {
|
for (const key of dbKeys) {
|
||||||
const originalPerm = originalPermissions.find(p => p.permission_key === key);
|
const originalPerm = originalPermissions.find(p => p.permission_key === key);
|
||||||
@@ -180,8 +136,6 @@ export function findDbPermissionIds(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查权限是否受映射影响
|
* 检查权限是否受映射影响
|
||||||
* @param permissionKey 权限键
|
|
||||||
* @returns 是否有映射关系
|
|
||||||
*/
|
*/
|
||||||
export function hasPermissionMapping(permissionKey: string): boolean {
|
export function hasPermissionMapping(permissionKey: string): boolean {
|
||||||
return PERMISSION_KEY_MAP[permissionKey] !== undefined;
|
return PERMISSION_KEY_MAP[permissionKey] !== undefined;
|
||||||
@@ -189,10 +143,8 @@ export function hasPermissionMapping(permissionKey: string): boolean {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取权限映射的说明信息
|
* 获取权限映射的说明信息
|
||||||
* @returns 映射关系的说明文本
|
|
||||||
*/
|
*/
|
||||||
export function getPermissionMappingInfo(): string {
|
export function getPermissionMappingInfo(): string {
|
||||||
return `权限映射说明:\n` +
|
return `权限映射说明:\n` +
|
||||||
`- dify:bind:list/create/update/delete → dify:dataset:manage(知识库管理)\n` +
|
`当前未启用权限键映射,直接使用数据库权限键`;
|
||||||
`取消勾选后,对应接口将返回403权限不足错误`;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user