# app/utils/decorators.py from functools import wraps from flask_jwt_extended import get_jwt, verify_jwt_in_request from flask import jsonify, g import logging def role_required(*roles): """ 自定义装饰器:检查用户角色 使用方法: @role_required('super_admin', 'finance') """ def wrapper(fn): @wraps(fn) def decorator(*args, **kwargs): claims = get_jwt() user_role = claims.get('role') # 如果是超级管理员,拥有上帝视角,直接放行 (可选) if user_role == 'super_admin': return fn(*args, **kwargs) if user_role not in roles: return jsonify(msg='权限不足:您没有访问此资源的权限'), 403 return fn(*args, **kwargs) return decorator return wrapper def login_required(fn): """ 验证 JWT 令牌是否存在且有效 """ @wraps(fn) def decorator(*args, **kwargs): try: verify_jwt_in_request() except Exception as e: logging.warning(f"JWT verification failed: {e}") return jsonify(msg='登录已过期,请重新登录'), 401 return fn(*args, **kwargs) return decorator def permission_required(permission_code): """ 检查当前用户是否拥有指定权限码 使用方法: @permission_required('material:base:read') """ def wrapper(fn): @wraps(fn) def decorator(*args, **kwargs): # 首先验证 JWT try: verify_jwt_in_request() except Exception as e: logging.warning(f"JWT verification failed: {e}") return jsonify(msg='登录已过期,请重新登录'), 401 claims = get_jwt() user_role = claims.get('role') # 超级管理员放行 if user_role == 'super_admin': return fn(*args, **kwargs) # TODO: 根据角色和 permission_code 查询数据库验证权限 # 此处为示例逻辑:假设角色 'admin' 和 'manager' 拥有所有权限 # 实际项目中应替换为真实的权限查询 if user_role in ['admin', 'manager']: return fn(*args, **kwargs) # 其他角色暂时拒绝,并记录日志 logging.warning( f'Permission check not implemented for {permission_code}, user role {user_role}. Access denied.') return jsonify(msg='权限不足:您没有访问此资源的权限'), 403 return decorator return wrapper