dataset inheritance permission (#2151)
* refactor: dataset create and update api * chore: defaultpermission & resume fe * refactor: database auth * fix(ts): add inheritPermission into default data types * chore: adjust the code * fix: list api type filter * fix: query condition
This commit is contained in:
@@ -8,8 +8,8 @@ export enum DatasetErrEnum {
|
||||
unAuthDatasetCollection = 'unAuthDatasetCollection',
|
||||
unAuthDatasetData = 'unAuthDatasetData',
|
||||
unAuthDatasetFile = 'unAuthDatasetFile',
|
||||
|
||||
unLinkCollection = 'unLinkCollection'
|
||||
unLinkCollection = 'unLinkCollection',
|
||||
invalidVectorModelOrQAModel = 'invalidVectorModelOrQAModel'
|
||||
}
|
||||
const datasetErr = [
|
||||
{
|
||||
@@ -39,6 +39,10 @@ const datasetErr = [
|
||||
{
|
||||
statusText: DatasetErrEnum.unLinkCollection,
|
||||
message: 'core.dataset.error.unLinkCollection'
|
||||
},
|
||||
{
|
||||
statusText: DatasetErrEnum.invalidVectorModelOrQAModel,
|
||||
message: 'core.dataset.error.invalidVectorModelOrQAModel'
|
||||
}
|
||||
];
|
||||
export default datasetErr.reduce((acc, cur, index) => {
|
||||
|
||||
1
packages/global/core/dataset/api.d.ts
vendored
1
packages/global/core/dataset/api.d.ts
vendored
@@ -10,7 +10,6 @@ export type DatasetUpdateBody = {
|
||||
name?: string;
|
||||
avatar?: string;
|
||||
intro?: string;
|
||||
permission?: DatasetSchemaType['permission']; // TODO: Should be deleted.
|
||||
agentModel?: LLMModelItemType;
|
||||
status?: DatasetSchemaType['status'];
|
||||
|
||||
|
||||
21
packages/global/core/dataset/type.d.ts
vendored
21
packages/global/core/dataset/type.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import { PermissionValueType } from 'support/permission/type';
|
||||
import { PermissionSchemaType } from '../../support/permission/type';
|
||||
import type { LLMModelItemType, VectorModelItemType } from '../../core/ai/model.d';
|
||||
import { PermissionTypeEnum } from '../../support/permission/constant';
|
||||
import { PushDatasetDataChunkProps } from './api';
|
||||
@@ -12,31 +12,28 @@ import {
|
||||
import { DatasetPermission } from '../../support/permission/dataset/controller';
|
||||
import { Permission } from '../../support/permission/controller';
|
||||
|
||||
/* schema */
|
||||
export type DatasetSchemaType = {
|
||||
_id: string;
|
||||
parentId: string;
|
||||
parentId?: string;
|
||||
userId: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
updateTime: Date;
|
||||
|
||||
avatar: string;
|
||||
name: string;
|
||||
vectorModel: string;
|
||||
agentModel: string;
|
||||
intro: string;
|
||||
type: DatasetTypeEnum;
|
||||
type: `${DatasetTypeEnum}`;
|
||||
status: `${DatasetStatusEnum}`;
|
||||
// permission: DatasetPermission;
|
||||
|
||||
// metadata
|
||||
websiteConfig?: {
|
||||
url: string;
|
||||
selector: string;
|
||||
};
|
||||
externalReadUrl?: string;
|
||||
defaultPermission: PermissionValueType;
|
||||
};
|
||||
} & PermissionSchemaType;
|
||||
// } & PermissionSchemaType;
|
||||
|
||||
export type DatasetCollectionSchemaType = {
|
||||
_id: string;
|
||||
@@ -133,15 +130,13 @@ export type DatasetSimpleItemType = {
|
||||
};
|
||||
export type DatasetListItemType = {
|
||||
_id: string;
|
||||
parentId: string;
|
||||
avatar: string;
|
||||
name: string;
|
||||
intro: string;
|
||||
type: DatasetTypeEnum;
|
||||
type: `${DatasetTypeEnum}`;
|
||||
permission: DatasetPermission;
|
||||
vectorModel: VectorModelItemType;
|
||||
defaultPermission: PermissionValueType;
|
||||
};
|
||||
} & PermissionSchemaType;
|
||||
|
||||
export type DatasetItemType = Omit<DatasetSchemaType, 'vectorModel' | 'agentModel'> & {
|
||||
vectorModel: VectorModelItemType;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { connectionMongo, getMongoModel, type Model } from '../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import { DatasetSchemaType } from '@fastgpt/global/core/dataset/type.d';
|
||||
import { getMongoModel, Schema } from '../../common/mongo';
|
||||
import {
|
||||
DatasetStatusEnum,
|
||||
DatasetStatusMap,
|
||||
@@ -12,6 +10,8 @@ import {
|
||||
TeamMemberCollectionName
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
import { DatasetDefaultPermissionVal } from '@fastgpt/global/support/permission/dataset/constant';
|
||||
import { getPermissionSchema } from '@fastgpt/global/support/permission/utils';
|
||||
import type { DatasetSchemaType } from '@fastgpt/global/core/dataset/type.d';
|
||||
|
||||
export const DatasetCollectionName = 'datasets';
|
||||
|
||||
@@ -85,11 +85,10 @@ const DatasetSchema = new Schema({
|
||||
}
|
||||
}
|
||||
},
|
||||
externalReadUrl: String,
|
||||
defaultPermission: {
|
||||
type: Number,
|
||||
default: DatasetDefaultPermissionVal
|
||||
}
|
||||
externalReadUrl: {
|
||||
type: String
|
||||
},
|
||||
...getPermissionSchema(DatasetDefaultPermissionVal)
|
||||
});
|
||||
|
||||
try {
|
||||
|
||||
@@ -17,10 +17,11 @@ import { getFileById } from '../../../common/file/gridfs/controller';
|
||||
import { BucketNameEnum } from '@fastgpt/global/common/file/constants';
|
||||
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
||||
import { MongoDatasetData } from '../../../core/dataset/data/schema';
|
||||
import { DatasetDefaultPermissionVal } from '@fastgpt/global/support/permission/dataset/constant';
|
||||
import { AuthModeType, AuthResponseType } from '../type';
|
||||
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||
import { ParentIdType } from '@fastgpt/global/common/parentFolder/type';
|
||||
|
||||
export async function authDatasetByTmbId({
|
||||
export const authDatasetByTmbId = async ({
|
||||
tmbId,
|
||||
datasetId,
|
||||
per
|
||||
@@ -28,30 +29,64 @@ export async function authDatasetByTmbId({
|
||||
tmbId: string;
|
||||
datasetId: string;
|
||||
per: PermissionValueType;
|
||||
}) {
|
||||
const { teamId, permission: tmbPer } = await getTmbInfoByTmbId({ tmbId });
|
||||
|
||||
}): Promise<{
|
||||
dataset: DatasetSchemaType & {
|
||||
permission: DatasetPermission;
|
||||
};
|
||||
}> => {
|
||||
const dataset = await (async () => {
|
||||
// get app and per
|
||||
const [dataset, rp] = await Promise.all([
|
||||
MongoDataset.findOne({ _id: datasetId, teamId }).lean(),
|
||||
getResourcePermission({
|
||||
teamId,
|
||||
tmbId,
|
||||
resourceId: datasetId,
|
||||
resourceType: PerResourceTypeEnum.dataset
|
||||
}) // this could be null
|
||||
const [{ teamId, permission: tmbPer }, dataset] = await Promise.all([
|
||||
getTmbInfoByTmbId({ tmbId }),
|
||||
MongoDataset.findOne({ _id: datasetId }).lean()
|
||||
]);
|
||||
|
||||
if (!dataset) {
|
||||
return Promise.reject(DatasetErrEnum.unExist);
|
||||
}
|
||||
|
||||
const isOwner = tmbPer.isOwner || String(dataset.tmbId) === String(tmbId);
|
||||
const Per = new DatasetPermission({
|
||||
per: rp?.permission ?? dataset.defaultPermission,
|
||||
isOwner
|
||||
});
|
||||
|
||||
// get dataset permission or inherit permission from parent folder.
|
||||
const { Per, defaultPermission } = await (async () => {
|
||||
if (
|
||||
dataset.type === DatasetTypeEnum.folder ||
|
||||
dataset.inheritPermission === false ||
|
||||
!dataset.parentId
|
||||
) {
|
||||
// 1. is a folder. (Folders have compeletely permission)
|
||||
// 2. inheritPermission is false.
|
||||
// 3. is root folder/dataset.
|
||||
const rp = await getResourcePermission({
|
||||
teamId,
|
||||
tmbId,
|
||||
resourceId: datasetId,
|
||||
resourceType: PerResourceTypeEnum.dataset
|
||||
});
|
||||
const Per = new DatasetPermission({
|
||||
per: rp?.permission ?? dataset.defaultPermission,
|
||||
isOwner
|
||||
});
|
||||
return {
|
||||
Per,
|
||||
defaultPermission: dataset.defaultPermission
|
||||
};
|
||||
} else {
|
||||
// is not folder and inheritPermission is true and is not root folder.
|
||||
const { dataset: parent } = await authDatasetByTmbId({
|
||||
tmbId,
|
||||
datasetId: dataset.parentId,
|
||||
per
|
||||
});
|
||||
|
||||
const Per = new DatasetPermission({
|
||||
per: parent.permission.value,
|
||||
isOwner
|
||||
});
|
||||
return {
|
||||
Per,
|
||||
defaultPermission: parent.defaultPermission
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
if (!Per.checkPer(per)) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDataset);
|
||||
@@ -59,27 +94,34 @@ export async function authDatasetByTmbId({
|
||||
|
||||
return {
|
||||
...dataset,
|
||||
defaultPermission: dataset.defaultPermission ?? DatasetDefaultPermissionVal,
|
||||
defaultPermission,
|
||||
permission: Per
|
||||
};
|
||||
})();
|
||||
|
||||
return { dataset };
|
||||
}
|
||||
};
|
||||
|
||||
// Auth Dataset
|
||||
export async function authDataset({
|
||||
export const authDataset = async ({
|
||||
datasetId,
|
||||
per = NullPermission,
|
||||
per,
|
||||
...props
|
||||
}: AuthModeType & {
|
||||
datasetId: string;
|
||||
datasetId: ParentIdType;
|
||||
per: PermissionValueType;
|
||||
}): Promise<
|
||||
AuthResponseType<DatasetPermission> & {
|
||||
dataset: DatasetSchemaType;
|
||||
AuthResponseType & {
|
||||
dataset: DatasetSchemaType & {
|
||||
permission: DatasetPermission;
|
||||
};
|
||||
}
|
||||
> => {
|
||||
const result = await parseHeaderCert(props);
|
||||
const { tmbId } = result;
|
||||
|
||||
if (!datasetId) {
|
||||
return Promise.reject(DatasetErrEnum.unExist);
|
||||
}
|
||||
> {
|
||||
const { teamId, tmbId } = await parseHeaderCert(props);
|
||||
|
||||
const { dataset } = await authDatasetByTmbId({
|
||||
tmbId,
|
||||
@@ -88,13 +130,11 @@ export async function authDataset({
|
||||
});
|
||||
|
||||
return {
|
||||
teamId,
|
||||
tmbId,
|
||||
dataset,
|
||||
permission: dataset.permission
|
||||
...result,
|
||||
permission: dataset.permission,
|
||||
dataset
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
// the temporary solution for authDatasetCollection is getting the
|
||||
export async function authDatasetCollection({
|
||||
collectionId,
|
||||
|
||||
@@ -511,7 +511,8 @@
|
||||
"unAuthDatasetData": "Unauthorized to operate this data",
|
||||
"unAuthDatasetFile": "Unauthorized to operate this file",
|
||||
"unCreateCollection": "Unauthorized to operate this data",
|
||||
"unLinkCollection": "Not a network link collection"
|
||||
"unLinkCollection": "Not a network link collection",
|
||||
"invalidVectorModelOrQAModel": "Invalid vector model or QA model"
|
||||
},
|
||||
"externalFile": "external file repository",
|
||||
"file": "File",
|
||||
|
||||
@@ -511,7 +511,8 @@
|
||||
"unAuthDatasetData": "无权操作该数据",
|
||||
"unAuthDatasetFile": "无权操作该文件",
|
||||
"unCreateCollection": "无权操作该数据",
|
||||
"unLinkCollection": "不是网络链接集合"
|
||||
"unLinkCollection": "不是网络链接集合",
|
||||
"invalidVectorModelOrQAModel": "VectorModel 或 QA 模型错误"
|
||||
},
|
||||
"externalFile": "外部文件库",
|
||||
"file": "文件",
|
||||
|
||||
Reference in New Issue
Block a user