You've already forked DataMate
fix(auth): harden confidential knowledge access checks and sensitivity filtering
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { Card, Button, Table, Tooltip, Tag, App, Statistic } from "antd";
|
||||
import { DeleteOutlined, EditOutlined } from "@ant-design/icons";
|
||||
import { DeleteOutlined, EditOutlined, LockOutlined } from "@ant-design/icons";
|
||||
import { useNavigate } from "react-router";
|
||||
import CardView from "@/components/CardView";
|
||||
import { SearchControls } from "@/components/SearchControls";
|
||||
@@ -15,8 +15,14 @@ import {
|
||||
knowledgeStatusOptions,
|
||||
mapKnowledgeSet,
|
||||
KnowledgeSetView,
|
||||
sensitivityMap,
|
||||
sensitivityOptions,
|
||||
} from "../knowledge-management.const";
|
||||
import { KnowledgeManagementStatistics, KnowledgeSet } from "../knowledge-management.model";
|
||||
import {
|
||||
KnowledgeManagementStatistics,
|
||||
KnowledgeSensitivityType,
|
||||
KnowledgeSet,
|
||||
} from "../knowledge-management.model";
|
||||
import CreateKnowledgeSet from "../components/CreateKnowledgeSet";
|
||||
import {
|
||||
createDatasetTagUsingPost,
|
||||
@@ -76,6 +82,11 @@ export default function KnowledgeManagementPage() {
|
||||
label: "状态",
|
||||
options: knowledgeStatusOptions,
|
||||
},
|
||||
{
|
||||
key: "sensitivity",
|
||||
label: "敏感级别",
|
||||
options: sensitivityOptions,
|
||||
},
|
||||
{
|
||||
key: "tags",
|
||||
label: "标签",
|
||||
@@ -101,7 +112,16 @@ export default function KnowledgeManagementPage() {
|
||||
30000,
|
||||
false,
|
||||
[],
|
||||
0
|
||||
0,
|
||||
(filters) => {
|
||||
const sensitivity = Array.isArray(filters?.sensitivity)
|
||||
? (filters.sensitivity[0] as string | undefined)
|
||||
: undefined;
|
||||
if (!sensitivity || sensitivity === "all") {
|
||||
return {};
|
||||
}
|
||||
return { sensitivity: sensitivity.toUpperCase() };
|
||||
}
|
||||
);
|
||||
|
||||
const fetchStatistics = useCallback(async () => {
|
||||
@@ -204,6 +224,25 @@ export default function KnowledgeManagementPage() {
|
||||
<Tag color={status?.color}>{status?.label}</Tag>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "敏感级别",
|
||||
dataIndex: "sensitivity",
|
||||
key: "sensitivity",
|
||||
width: 100,
|
||||
render: (sensitivity: string) => {
|
||||
const normalized = sensitivity ? sensitivity.toUpperCase() : "";
|
||||
const meta = normalized ? sensitivityMap[normalized] : null;
|
||||
if (!meta) return "-";
|
||||
return (
|
||||
<Tag
|
||||
color={meta.color}
|
||||
icon={normalized === KnowledgeSensitivityType.CONFIDENTIAL ? <LockOutlined /> : undefined}
|
||||
>
|
||||
{meta.label}
|
||||
</Tag>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "领域",
|
||||
dataIndex: "domain",
|
||||
|
||||
@@ -9,10 +9,11 @@ import {
|
||||
import {
|
||||
knowledgeSourceTypeOptions,
|
||||
knowledgeStatusOptions,
|
||||
// sensitivityOptions,
|
||||
sensitivityOptions,
|
||||
} from "../knowledge-management.const";
|
||||
import {
|
||||
KnowledgeSet,
|
||||
KnowledgeSensitivityType,
|
||||
KnowledgeStatusType,
|
||||
} from "../knowledge-management.model";
|
||||
import { queryDatasetTagsUsingGet } from "@/pages/DataManagement/dataset.api";
|
||||
@@ -65,7 +66,7 @@ export default function CreateKnowledgeSet({
|
||||
validFrom: data.validFrom ? dayjs(data.validFrom) : null,
|
||||
validTo: data.validTo ? dayjs(data.validTo) : null,
|
||||
sourceType: data.sourceType,
|
||||
sensitivity: data.sensitivity,
|
||||
sensitivity: data.sensitivity?.toUpperCase() || undefined,
|
||||
tags: data.tags?.map((tag) => tag.name) || [],
|
||||
metadata: data.metadata,
|
||||
});
|
||||
@@ -85,6 +86,9 @@ export default function CreateKnowledgeSet({
|
||||
|
||||
const payload = {
|
||||
...values,
|
||||
sensitivity: values.sensitivity
|
||||
? String(values.sensitivity).toUpperCase()
|
||||
: undefined,
|
||||
validFrom,
|
||||
validTo,
|
||||
tags: values.tags || [],
|
||||
@@ -124,7 +128,11 @@ export default function CreateKnowledgeSet({
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => {
|
||||
form.resetFields();
|
||||
form.setFieldsValue({ status: KnowledgeStatusType.DRAFT, tags: [] });
|
||||
form.setFieldsValue({
|
||||
status: KnowledgeStatusType.DRAFT,
|
||||
sensitivity: KnowledgeSensitivityType.INTERNAL,
|
||||
tags: [],
|
||||
});
|
||||
setOpen(true);
|
||||
}}
|
||||
>
|
||||
@@ -170,9 +178,9 @@ export default function CreateKnowledgeSet({
|
||||
<Form.Item label="负责人" name="owner">
|
||||
<Input placeholder="请输入负责人" />
|
||||
</Form.Item>
|
||||
{/* <Form.Item label="敏感级别" name="sensitivity">
|
||||
<Select options={sensitivityOptions} placeholder="请选择敏感级别" />
|
||||
</Form.Item> */}
|
||||
<Form.Item label="敏感级别" name="sensitivity">
|
||||
<Select options={sensitivityOptions} placeholder="请选择敏感级别" allowClear />
|
||||
</Form.Item>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<Form.Item label="有效期开始" name="validFrom">
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
KnowledgeContentType,
|
||||
KnowledgeItem,
|
||||
KnowledgeSet,
|
||||
KnowledgeSensitivityType,
|
||||
KnowledgeSourceType,
|
||||
KnowledgeStatusType,
|
||||
} from "./knowledge-management.model";
|
||||
@@ -66,10 +67,22 @@ export const knowledgeSourceTypeOptions = [
|
||||
{ label: "文件上传", value: KnowledgeSourceType.FILE_UPLOAD },
|
||||
];
|
||||
|
||||
// export const sensitivityOptions = [
|
||||
// { label: "敏感", value: "敏感" },
|
||||
// { label: "不敏感", value: "不敏感" },
|
||||
// ];
|
||||
export const sensitivityOptions = [
|
||||
{ label: "公开", value: KnowledgeSensitivityType.PUBLIC },
|
||||
{ label: "内部", value: KnowledgeSensitivityType.INTERNAL },
|
||||
{ label: "保密", value: KnowledgeSensitivityType.CONFIDENTIAL },
|
||||
];
|
||||
|
||||
export type SensitivityMeta = {
|
||||
label: string;
|
||||
color: string;
|
||||
};
|
||||
|
||||
export const sensitivityMap: Record<string, SensitivityMeta> = {
|
||||
[KnowledgeSensitivityType.PUBLIC]: { label: "公开", color: "#52c41a" },
|
||||
[KnowledgeSensitivityType.INTERNAL]: { label: "内部", color: "#1677ff" },
|
||||
[KnowledgeSensitivityType.CONFIDENTIAL]: { label: "保密", color: "#f5222d" },
|
||||
};
|
||||
|
||||
export type KnowledgeSetView = {
|
||||
id: string;
|
||||
@@ -118,6 +131,7 @@ export type KnowledgeItemView = {
|
||||
};
|
||||
|
||||
export function mapKnowledgeSet(data: KnowledgeSet): KnowledgeSetView {
|
||||
const normalizedSensitivity = data.sensitivity?.toUpperCase();
|
||||
return {
|
||||
id: data.id,
|
||||
name: data.name,
|
||||
@@ -131,7 +145,7 @@ export function mapKnowledgeSet(data: KnowledgeSet): KnowledgeSetView {
|
||||
validFrom: data.validFrom,
|
||||
validTo: data.validTo,
|
||||
sourceType: data.sourceType,
|
||||
sensitivity: data.sensitivity,
|
||||
sensitivity: normalizedSensitivity,
|
||||
metadata: data.metadata,
|
||||
createdAt: data.createdAt ? formatDateTime(data.createdAt) : "",
|
||||
updatedAt: data.updatedAt ? formatDateTime(data.updatedAt) : "",
|
||||
@@ -142,6 +156,7 @@ export function mapKnowledgeSet(data: KnowledgeSet): KnowledgeSetView {
|
||||
}
|
||||
|
||||
export function mapKnowledgeItem(data: KnowledgeItem): KnowledgeItemView {
|
||||
const normalizedSensitivity = data.sensitivity?.toUpperCase();
|
||||
return {
|
||||
id: data.id,
|
||||
setId: data.setId,
|
||||
@@ -156,7 +171,7 @@ export function mapKnowledgeItem(data: KnowledgeItem): KnowledgeItemView {
|
||||
validFrom: data.validFrom,
|
||||
validTo: data.validTo,
|
||||
sourceType: data.sourceType,
|
||||
sensitivity: data.sensitivity,
|
||||
sensitivity: normalizedSensitivity,
|
||||
sourceDatasetId: data.sourceDatasetId,
|
||||
sourceFileId: data.sourceFileId,
|
||||
relativePath: data.relativePath,
|
||||
|
||||
@@ -17,6 +17,12 @@ export enum KnowledgeSourceType {
|
||||
FILE_UPLOAD = "FILE_UPLOAD",
|
||||
}
|
||||
|
||||
export enum KnowledgeSensitivityType {
|
||||
PUBLIC = "PUBLIC",
|
||||
INTERNAL = "INTERNAL",
|
||||
CONFIDENTIAL = "CONFIDENTIAL",
|
||||
}
|
||||
|
||||
export interface KnowledgeTag {
|
||||
id: string;
|
||||
name: string;
|
||||
|
||||
Reference in New Issue
Block a user