feat(auth): 为数据管理和RAG服务增加资源访问控制

- 在DatasetApplicationService中注入ResourceAccessService并添加所有权验证
- 在KnowledgeSetApplicationService中注入ResourceAccessService并添加所有权验证
- 修改DatasetRepository接口和实现类,增加按创建者过滤的方法
- 修改KnowledgeSetRepository接口和实现类,增加按创建者过滤的方法
- 在RAG索引器服务中添加知识库访问权限检查和作用域过滤
- 更新实体元对象处理器以使用请求用户上下文获取当前用户
- 在前端设置页面添加用户权限管理功能和角色权限控制
- 为Python标注服务增加用户上下文和数据集访问权限验证
This commit is contained in:
2026-02-06 14:58:46 +08:00
parent 056cee11cc
commit 6a4c4ae3d7
28 changed files with 1063 additions and 158 deletions

View File

@@ -54,6 +54,10 @@ from app.module.annotation.service.knowledge_sync import KnowledgeSyncService
from app.module.annotation.service.annotation_text_splitter import (
AnnotationTextSplitter,
)
from app.module.annotation.security import (
RequestUserContext,
ensure_dataset_owner_access,
)
from app.module.annotation.service.text_fetcher import (
fetch_text_content_via_download_api,
)
@@ -104,8 +108,9 @@ class AnnotationEditorService:
# 分段阈值:超过此字符数自动分段
SEGMENT_THRESHOLD = 200
def __init__(self, db: AsyncSession):
def __init__(self, db: AsyncSession, user_context: RequestUserContext):
self.db = db
self.user_context = user_context
self.template_service = AnnotationTemplateService()
@staticmethod
@@ -157,14 +162,24 @@ class AnnotationEditorService:
async def _get_project_or_404(self, project_id: str) -> LabelingProject:
result = await self.db.execute(
select(LabelingProject).where(
select(LabelingProject, Dataset.created_by).join(
Dataset,
LabelingProject.dataset_id == Dataset.id,
).where(
LabelingProject.id == project_id,
LabelingProject.deleted_at.is_(None),
)
)
project = result.scalar_one_or_none()
if not project:
row = result.first()
if not row:
raise HTTPException(status_code=404, detail=f"标注项目不存在: {project_id}")
project = row[0]
dataset_owner = row[1]
ensure_dataset_owner_access(
self.user_context,
str(dataset_owner) if dataset_owner is not None else None,
project.dataset_id,
)
return project
async def _get_dataset_type(self, dataset_id: str) -> Optional[str]: