diff --git a/packages/service/support/permission/controller.ts b/packages/service/support/permission/controller.ts index 92f2e7545..c6e5b9fa6 100644 --- a/packages/service/support/permission/controller.ts +++ b/packages/service/support/permission/controller.ts @@ -22,6 +22,7 @@ import { MemberGroupSchemaType } from '@fastgpt/global/support/permission/member import { TeamMemberSchema } from '@fastgpt/global/support/user/team/type'; import { UserModelSchema } from '@fastgpt/global/support/user/type'; import { OrgSchemaType } from '@fastgpt/global/support/user/team/org/type'; +import { getOrgsWithParentByTmbId } from './org/controllers'; /** get resource permission for a team member * If there is no permission for the team member, it will return undefined @@ -40,15 +41,15 @@ export const getResourcePermission = async ({ teamId: string; tmbId: string; } & ( - | { + | { resourceType: 'team'; resourceId?: undefined; } - | { + | { resourceType: Omit; resourceId: string; } -)): Promise => { + )): Promise => { // Personal permission has the highest priority const tmbPer = ( await MongoResourcePermission.findOne( @@ -68,20 +69,45 @@ export const getResourcePermission = async ({ } // If there is no personal permission, get the group permission - const groupIdList = (await getGroupsByTmbId({ tmbId, teamId })).map((item) => item._id); + const groupPer = await (async () => { + const groupIdList = (await getGroupsByTmbId({ tmbId, teamId })).map((item) => item._id); - if (groupIdList.length === 0) { - return undefined; + if (groupIdList.length === 0) { + return undefined; + } + + // get the maximum permission of the group + const pers = ( + await MongoResourcePermission.find( + { + teamId, + resourceType, + groupId: { + $in: groupIdList + }, + resourceId + }, + 'permission' + ).lean() + ).map((item) => item.permission); + + return getGroupPer(pers); + })(); + + const orgIds = await getOrgsWithParentByTmbId({ tmbId, teamId }).then((item) => Array.from(item)); + + if (orgIds.length === 0) { + return groupPer; } - // get the maximum permission of the group - const pers = ( + // get the maximum permission of the org + const orgPers = ( await MongoResourcePermission.find( { teamId, resourceType, - groupId: { - $in: groupIdList + orgId: { + $in: Array.from(orgIds) }, resourceId }, @@ -89,9 +115,15 @@ export const getResourcePermission = async ({ ).lean() ).map((item) => item.permission); - const groupPer = getGroupPer(pers); + const orgPer = getGroupPer(orgPers); - return groupPer; + if (groupPer === undefined) { + return orgPer; + } else if (orgPer === undefined) { + return groupPer; + } + + return new Permission().addPer(groupPer, orgPer).value; }; /* 仅取 members 不取 groups */ @@ -104,15 +136,15 @@ export async function getResourceAllClbs({ teamId: string; session?: ClientSession; } & ( - | { + | { resourceType: 'team'; resourceId?: undefined; } - | { + | { resourceType: Omit; resourceId?: string | null; } -)): Promise { + )): Promise { return MongoResourcePermission.find( { resourceType: resourceType, diff --git a/packages/service/support/permission/org/controllers.ts b/packages/service/support/permission/org/controllers.ts index 4c8263ac0..d46e83cf3 100644 --- a/packages/service/support/permission/org/controllers.ts +++ b/packages/service/support/permission/org/controllers.ts @@ -36,6 +36,19 @@ import { MongoOrgMemberModel } from './orgMemberSchema'; export const getOrgsByTmbId = async ({ teamId, tmbId }: { teamId: string; tmbId: string }) => MongoOrgMemberModel.find({ teamId, tmbId }, 'orgId').lean(); +export const getOrgsWithParentByTmbId = async ({ teamId, tmbId }: { teamId: string; tmbId: string }) => + MongoOrgMemberModel.find({ teamId, tmbId }, 'orgId').lean().then((orgs) => { + const orgIds = new Set(); + for (const org of orgs) { + const orgId = String(org.orgId); + const parentIds = orgId.split('/').filter((id) => id); + for (const parentId of parentIds) { + orgIds.add(parentId); + } + } + return orgIds; + }); + export const getChildrenByOrg = async ({ org, teamId, diff --git a/projects/app/src/components/support/permission/MemberManager/AddMemberModal.tsx b/projects/app/src/components/support/permission/MemberManager/AddMemberModal.tsx index 24611a644..18fddf866 100644 --- a/projects/app/src/components/support/permission/MemberManager/AddMemberModal.tsx +++ b/projects/app/src/components/support/permission/MemberManager/AddMemberModal.tsx @@ -75,7 +75,7 @@ function AddMemberModal({ onClose, mode = 'member' }: AddModalPropsType) { if (mode !== 'all') return []; return orgs.filter((item) => { if (item.path === '') return false; // exclude root org - if (!permission.isOwner && myOrgs.find((i) => String(i._id) !== String(item._id))) + if (!permission.isOwner && !myOrgs.find((i) => String(i._id) === String(item._id))) return false; if (!searchText) return true; return item.name.includes(searchText); diff --git a/projects/app/src/pages/api/core/app/list.ts b/projects/app/src/pages/api/core/app/list.ts index eaee894bf..294939082 100644 --- a/projects/app/src/pages/api/core/app/list.ts +++ b/projects/app/src/pages/api/core/app/list.ts @@ -17,6 +17,7 @@ import { authUserPer } from '@fastgpt/service/support/permission/user/auth'; import { replaceRegChars } from '@fastgpt/global/common/string/tools'; import { getGroupPer } from '@fastgpt/service/support/permission/controller'; import { getGroupsByTmbId } from '@fastgpt/service/support/permission/memberGroup/controllers'; +import { getOrgsWithParentByTmbId } from '@fastgpt/service/support/permission/org/controllers'; export type ListAppBody = { parentId?: ParentIdType; @@ -25,7 +26,7 @@ export type ListAppBody = { searchKey?: string; }; -/* +/* 获取 APP 列表权限 1. 校验 folder 权限和获取 team 权限(owner 单独处理) 2. 获取 team 下所有 app 权限。获取我的所有组。并计算出我所有的app权限。 @@ -48,19 +49,19 @@ async function handler(req: ApiRequestProps): Promise): Promise String(item.tmbId) === String(tmbId) || myGroupMap.has(String(item.groupId)) + (item) => String(item.tmbId) === String(tmbId) || myGroupMap.has(String(item.groupId)) || myOrgSet.has(String(item.orgId)) ); const findAppsQuery = (() => { @@ -99,17 +104,17 @@ async function handler(req: ApiRequestProps): Promise): Promise String(item.resourceId) === appId && !!item.groupId) + .filter((item) => String(item.resourceId) === appId && (!!item.groupId || !!item.orgId)) .map((item) => item.permission) ); diff --git a/projects/app/src/pages/api/core/dataset/list.ts b/projects/app/src/pages/api/core/dataset/list.ts index 32c1bd82f..0daf6caf5 100644 --- a/projects/app/src/pages/api/core/dataset/list.ts +++ b/projects/app/src/pages/api/core/dataset/list.ts @@ -18,6 +18,7 @@ import { authDataset } from '@fastgpt/service/support/permission/dataset/auth'; import { replaceRegChars } from '@fastgpt/global/common/string/tools'; import { getGroupsByTmbId } from '@fastgpt/service/support/permission/memberGroup/controllers'; import { getGroupPer } from '@fastgpt/service/support/permission/controller'; +import { getOrgsWithParentByTmbId } from '@fastgpt/service/support/permission/org/controllers'; export type GetDatasetListBody = { parentId: ParentIdType; @@ -38,19 +39,19 @@ async function handler(req: ApiRequestProps) { }), ...(parentId ? [ - authDataset({ - req, - authToken: true, - authApiKey: true, - per: ReadPermissionVal, - datasetId: parentId - }) - ] + authDataset({ + req, + authToken: true, + authApiKey: true, + per: ReadPermissionVal, + datasetId: parentId + }) + ] : []) ]); // Get team all app permissions - const [perList, myGroupMap] = await Promise.all([ + const [perList, myGroupMap, myOrgSet] = await Promise.all([ MongoResourcePermission.find({ resourceType: PerResourceTypeEnum.dataset, teamId, @@ -67,10 +68,14 @@ async function handler(req: ApiRequestProps) { map.set(String(item._id), 1); }); return map; + }), + getOrgsWithParentByTmbId({ + teamId, + tmbId }) ]); const myPerList = perList.filter( - (item) => String(item.tmbId) === String(tmbId) || myGroupMap.has(String(item.groupId)) + (item) => String(item.tmbId) === String(tmbId) || myGroupMap.has(String(item.groupId)) || myOrgSet.has(String(item.orgId)) ); const findDatasetQuery = (() => { @@ -80,17 +85,17 @@ async function handler(req: ApiRequestProps) { ? {} : parentId ? { - $or: [idList, parseParentIdInMongo(parentId)] - } + $or: [idList, parseParentIdInMongo(parentId)] + } : { $or: [idList, { parentId: null }] }; const searchMatch = searchKey ? { - $or: [ - { name: { $regex: new RegExp(`${replaceRegChars(searchKey)}`, 'i') } }, - { intro: { $regex: new RegExp(`${replaceRegChars(searchKey)}`, 'i') } } - ] - } + $or: [ + { name: { $regex: new RegExp(`${replaceRegChars(searchKey)}`, 'i') } }, + { intro: { $regex: new RegExp(`${replaceRegChars(searchKey)}`, 'i') } } + ] + } : {}; if (searchKey) { @@ -124,7 +129,7 @@ async function handler(req: ApiRequestProps) { )?.permission; const groupPer = getGroupPer( myPerList - .filter((item) => String(item.resourceId) === datasetId && !!item.groupId) + .filter((item) => String(item.resourceId) === datasetId && (!!item.groupId || !!item.orgId)) .map((item) => item.permission) ); return new DatasetPermission({