Files
ai-agent-admin/backend-fastapi/online_dev/form_data_manager/dependencies.py
T

243 lines
7.0 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
表单数据权限校验依赖
"""
import logging
from typing import Dict, Any, List, Optional
from fastapi import Depends, HTTPException, Request
from sqlalchemy import exists, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
logger = logging.getLogger(__name__)
async def get_user_info(request: Request) -> Dict[str, Any]:
"""从请求中获取用户信息"""
return {
"user_id": getattr(request.state, 'user_id', None),
"dept_id": getattr(request.state, 'dept_id', None),
"role_ids": getattr(request.state, 'role_ids', []),
"is_superuser": getattr(request.state, 'is_superuser', False),
}
async def check_form_permission(
form_code: str,
action: str,
request: Request,
db: AsyncSession
) -> bool:
"""
检查用户是否有表单操作权限
:param form_code: 表单编码
:param action: 操作类型 (view/add/edit/delete/export/import)
:param request: 请求对象
:param db: 数据库会话
:return: True 表示有权限
:raises HTTPException: 无权限时抛出 403 异常
"""
user_id = getattr(request.state, 'user_id', None)
is_superuser = getattr(request.state, 'is_superuser', False)
# 超级管理员跳过权限检查
if is_superuser:
return True
if not user_id:
raise HTTPException(status_code=401, detail="未登录")
# 权限编码
perm_code = f"form:{form_code}:{action}"
# 查询用户角色的权限
from core.user.model import User
from core.role.model import Role, role_permission
from core.permission.model import Permission
# 获取用户的角色ID列表
role_ids = getattr(request.state, 'role_ids', [])
if not role_ids:
# 如果 request.state 中没有角色信息,从数据库查询
user_stmt = select(User).where(User.id == user_id)
user_result = await db.execute(user_stmt)
user = user_result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=401, detail="用户不存在")
role_ids = [role.id for role in user.roles] if hasattr(user, 'roles') else []
if not role_ids:
raise HTTPException(status_code=403, detail=f"没有{action}权限")
# 多个角色可能同时拥有同一权限,用 EXISTS 判断即可
has_perm_stmt = select(
exists(
select(Permission.id)
.join(
role_permission,
Permission.id == role_permission.c.permission_id,
)
.where(
role_permission.c.role_id.in_(role_ids),
Permission.code == perm_code,
Permission.is_active == True,
Permission.is_deleted == False,
)
)
)
has_permission = await db.scalar(has_perm_stmt)
if has_permission:
return True
# 操作名称映射
action_names = {
"view": "查看",
"add": "新增",
"edit": "编辑",
"delete": "删除",
"export": "导出",
"import": "导入",
}
action_name = action_names.get(action, action)
raise HTTPException(status_code=403, detail=f"没有{action_name}权限")
async def get_user_form_permissions(
form_code: str,
request: Request,
db: AsyncSession
) -> Dict[str, bool]:
"""
获取用户对表单的所有操作权限
:param form_code: 表单编码
:param request: 请求对象
:param db: 数据库会话
:return: 权限字典
"""
user_id = getattr(request.state, 'user_id', None)
is_superuser = getattr(request.state, 'is_superuser', False)
# 默认权限
permissions = {
"view": False,
"add": False,
"edit": False,
"delete": False,
"export": False,
"import": False,
}
# 超级管理员拥有所有权限
if is_superuser:
return {k: True for k in permissions.keys()}
if not user_id:
return permissions
# 获取用户角色ID列表
role_ids = getattr(request.state, 'role_ids', [])
if not role_ids:
from core.user.model import User
user_stmt = select(User).where(User.id == user_id)
user_result = await db.execute(user_stmt)
user = user_result.scalar_one_or_none()
if user and hasattr(user, 'roles'):
role_ids = [role.id for role in user.roles]
if not role_ids:
return permissions
# 查询用户拥有的表单权限
from core.role.model import role_permission
from core.permission.model import Permission
perm_stmt = select(Permission.code).join(
role_permission,
Permission.id == role_permission.c.permission_id
).where(
role_permission.c.role_id.in_(role_ids),
Permission.code.like(f"form:{form_code}:%"),
Permission.is_active == True,
Permission.is_deleted == False
)
perm_result = await db.execute(perm_stmt)
perm_codes = [row[0] for row in perm_result.fetchall()]
# 解析权限
for perm_code in perm_codes:
# 格式: form:{form_code}:{action}
parts = perm_code.split(":")
if len(parts) == 3 and parts[2] in permissions:
permissions[parts[2]] = True
return permissions
async def get_data_scope_filter(
form_code: str,
request: Request,
db: AsyncSession
) -> Dict[str, Any]:
"""
获取数据权限过滤条件
:param form_code: 表单编码
:param request: 请求对象
:param db: 数据库会话
:return: 数据权限过滤配置
"""
user_id = getattr(request.state, 'user_id', None)
dept_id = getattr(request.state, 'dept_id', None)
role_ids = getattr(request.state, 'role_ids', [])
is_superuser = getattr(request.state, 'is_superuser', False)
# 超级管理员:全部数据
if is_superuser:
return {
'filter_type': 'all',
'scope': 0,
'user_id': None,
'dept_id': None,
'dept_ids': None
}
# 资源类型
resource_type = f"form:{form_code}"
# 查询数据权限配置
from core.resource_scope.scope_permission.service import ResourceDataScopeConfigService
config = await ResourceDataScopeConfigService.get_resource_data_scope(
db=db,
role_ids=role_ids,
resource_type=resource_type,
is_superuser=False
)
# 填充用户信息
if config['filter_type'] == 'self':
config['user_id'] = user_id
elif config['filter_type'] == 'dept':
config['dept_id'] = dept_id
elif config['filter_type'] == 'dept_and_children':
if dept_id:
from core.dept.service import DeptService
descendants = await DeptService.get_descendants(db, dept_id)
config['dept_ids'] = [dept_id] + [d.id for d in descendants]
else:
config['dept_ids'] = []
return config