Implement open knowledge access scope

This commit is contained in:
2026-07-07 18:32:01 +08:00
parent 8d5d36c5eb
commit 03b1810a90
13 changed files with 587 additions and 382 deletions

View File

@@ -69,6 +69,7 @@ def delete_knowledge(
current_admin: Admin = Depends(get_current_admin),
) -> dict:
knowledge = _get_knowledge(db, knowledge_id)
# 清理早期按用户授权口径留下的历史关联,避免外键阻止知识库删除。
permissions = db.scalars(
select(UserKnowledgePermission).where(UserKnowledgePermission.knowledge_id == knowledge.id)
).all()

View File

@@ -1,7 +1,5 @@
from __future__ import annotations
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy import select
from sqlalchemy.orm import Session
@@ -10,9 +8,8 @@ from app.core.database import get_db
from app.core.dependencies import get_current_admin
from app.core.responses import api_success
from app.models.admin import Admin
from app.models.knowledge import Knowledge, UserKnowledgePermission
from app.models.user import User
from app.schemas.admin import AdminUserKnowledgePermissionSaveRequest, AdminUserUpdateRequest
from app.schemas.admin import AdminUserUpdateRequest
from app.services.admin_service import OperationLogService
router = APIRouter()
@@ -63,72 +60,6 @@ def update_user(
return api_success(_user_dict(user))
@router.get("/user/{user_id}/knowledge-permissions")
def user_knowledge_permissions(
user_id: int,
db: Session = Depends(get_db),
current_admin: Admin = Depends(get_current_admin),
) -> dict:
user = _get_user(db, user_id)
permissions = db.scalars(
select(UserKnowledgePermission)
.where(UserKnowledgePermission.user_id == user.id)
.order_by(UserKnowledgePermission.knowledge_id.asc())
).all()
return api_success(
{
"user": _user_dict(user),
"permissions": [_permission_dict(permission) for permission in permissions],
}
)
@router.put("/user/{user_id}/knowledge-permissions")
def save_user_knowledge_permissions(
user_id: int,
payload: AdminUserKnowledgePermissionSaveRequest,
db: Session = Depends(get_db),
current_admin: Admin = Depends(get_current_admin),
) -> dict:
user = _get_user(db, user_id)
normalized = {item.knowledgeId: item for item in payload.permissions}
if normalized:
existing_ids = set(db.scalars(select(Knowledge.id).where(Knowledge.id.in_(normalized.keys()))).all())
missing_ids = sorted(set(normalized.keys()) - existing_ids)
if missing_ids:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"知识库不存在: {','.join(str(item) for item in missing_ids)}",
)
old_permissions = db.scalars(
select(UserKnowledgePermission).where(UserKnowledgePermission.user_id == user.id)
).all()
for permission in old_permissions:
db.delete(permission)
db.flush()
for item in normalized.values():
db.add(
UserKnowledgePermission(
user_id=user.id,
knowledge_id=item.knowledgeId,
effective_at=_without_timezone(item.effectiveAt),
expired_at=_without_timezone(item.expiredAt),
created_by=current_admin.id,
)
)
OperationLogService.write(
db,
admin_id=current_admin.id,
module="user",
action="knowledge_permission",
target_id=user.id,
)
db.commit()
return user_knowledge_permissions(user.id, db, current_admin)
@router.delete("/user/{user_id}")
def delete_user(
user_id: int,
@@ -165,17 +96,3 @@ def _user_dict(user: User) -> dict:
"lastLoginAt": user.last_login_at,
"createdAt": user.created_at,
}
def _permission_dict(permission: UserKnowledgePermission) -> dict:
return {
"knowledgeId": permission.knowledge_id,
"effectiveAt": permission.effective_at,
"expiredAt": permission.expired_at,
}
def _without_timezone(value: datetime | None) -> datetime | None:
if value is None:
return None
return value.replace(tzinfo=None)