处理孙子部门权限问题

This commit is contained in:
silk 2026-06-02 13:33:12 +08:00
parent 8f21add2d4
commit 2014daee67
3 changed files with 22 additions and 13 deletions

View File

@ -333,7 +333,7 @@ async def upload_file(
kb = await _check_kb_access(conn, kb_id, current_user)
# 检查上传权限allow_kb_upload 开关)
if not can_upload_to_kb(current_user, kb):
if not await can_upload_to_kb(conn, current_user, kb):
raise BadRequestError("您的上传权限已被关闭,请联系部门领导或管理员")
# 检查文件类型
@ -489,7 +489,7 @@ async def upload_url(
):
"""上传 URL 到知识库并进行向量化处理"""
kb = await _check_kb_access(conn, kb_id, current_user)
if not can_upload_to_kb(current_user, kb):
if not await can_upload_to_kb(conn, current_user, kb):
raise BadRequestError("您的上传权限已被关闭,请联系部门领导或管理员")
url = request.url.strip()

View File

@ -87,13 +87,15 @@ async def is_subordinate(
# 知识库级权限(同步,无需数据库)
# ──────────────────────────────────────────────
def can_view_kb(user: User, kb: KnowledgeBase) -> bool:
"""判断用户是否可查看该知识库。"""
async def can_view_kb(conn: asyncpg.Connection, user: User, kb: KnowledgeBase) -> bool:
"""判断用户是否可查看该知识库。leader 权限覆盖本部门及所有子孙部门。"""
if user.role == "admin":
return True
if kb.creator_id is not None and user.id == kb.creator_id:
return True
if user.role == "leader" and user.department_id is not None and kb.department_id == user.department_id:
if user.role == "leader" and user.department_id is not None and kb.department_id is not None:
managed = await get_managed_dept_ids(conn, user)
if kb.department_id in managed:
return True
vis = kb.visibility or "private"
if vis == "private":
@ -144,14 +146,14 @@ async def can_delete_file(
return False
def can_upload_to_kb(user: User, kb: KnowledgeBase) -> bool:
async def can_upload_to_kb(conn: asyncpg.Connection, user: User, kb: KnowledgeBase) -> bool:
"""
判断用户是否可向知识库上传文件
- 必须能 view KB
- allow_kb_upload 未被关闭
- leader admin 也受 allow_kb_upload 约束管理员初始化时均为 True
"""
if not can_view_kb(user, kb):
if not await can_view_kb(conn, user, kb):
return False
return bool(user.allow_kb_upload)

View File

@ -4,7 +4,7 @@
from typing import Any, Dict, List, Optional, Tuple
import asyncpg
from core.permissions import can_manage_kb, can_view_kb
from core.permissions import can_manage_kb, can_view_kb, get_managed_dept_ids
from models.knowledge_base import KnowledgeBase, KnowledgeBaseCreate, KnowledgeBaseUpdate
from models.user import User
from logger.logging import get_logger
@ -185,7 +185,7 @@ class KnowledgeBaseService:
kb = await KnowledgeBaseService.fetch_knowledge_base_by_id(conn, kb_id)
if kb is None:
return None
if not can_view_kb(user, kb):
if not await can_view_kb(conn, user, kb):
return None
return kb
@ -206,14 +206,19 @@ class KnowledgeBaseService:
dept_id = user.department_id
uid = user.id
# leader 需要获取本部门及所有子孙部门 ID用于列表过滤
managed_dept_ids: List[int] = []
if role == "leader" and dept_id is not None:
managed_dept_ids = await get_managed_dept_ids(conn, user)
where_sql = """
kb.is_deleted = FALSE
AND kb.enterprise_id = $1
AND (
$2::text = 'admin'
OR kb.creator_id = $3
OR ($2::text = 'leader' AND kb.department_id IS NOT NULL AND kb.department_id = $4)
OR (kb.visibility = 'department' AND kb.department_id IS NOT NULL AND kb.department_id = $4)
OR ($2::text = 'leader' AND kb.department_id IS NOT NULL AND kb.department_id = ANY($4::int[]))
OR (kb.visibility = 'department' AND kb.department_id IS NOT NULL AND kb.department_id = $5)
OR (kb.visibility = 'enterprise')
)
"""
@ -226,6 +231,7 @@ class KnowledgeBaseService:
enterprise_id,
role,
uid,
managed_dept_ids,
dept_id,
)
@ -241,11 +247,12 @@ class KnowledgeBaseService:
LEFT JOIN department d ON d.id = kb.department_id
WHERE {where_sql}
ORDER BY kb.created_at DESC
LIMIT $5 OFFSET $6
LIMIT $6 OFFSET $7
""",
enterprise_id,
role,
uid,
managed_dept_ids,
dept_id,
page_size,
offset,