diff --git a/apps/jingrow/jingrow/services/whitelist.py b/apps/jingrow/jingrow/services/whitelist.py index 6d66fe4..170def3 100644 --- a/apps/jingrow/jingrow/services/whitelist.py +++ b/apps/jingrow/jingrow/services/whitelist.py @@ -19,11 +19,11 @@ from jingrow.utils.jingrow_api import get_logged_user logger = logging.getLogger(__name__) router = APIRouter() -# 确保 apps 目录在 sys.path 中(仅初始化一次) +# 确保各 app 根目录在 sys.path 中(仅初始化一次) _apps_path_initialized = False def _ensure_apps_on_sys_path(): - """确保 apps 目录在 sys.path 中,支持跨 app 导入""" + """确保各 app 根目录在 sys.path 中,支持跨 app 导入""" global _apps_path_initialized if _apps_path_initialized: return @@ -31,8 +31,16 @@ def _ensure_apps_on_sys_path(): try: project_root = Path(__file__).resolve().parents[4] apps_dir = project_root / "apps" - if apps_dir.exists() and str(apps_dir) not in sys.path: - sys.path.insert(0, str(apps_dir)) + + # 读取 apps.txt,添加各 app 的根目录(apps/) + apps_txt = apps_dir / "apps.txt" + if apps_txt.exists(): + for app_name in apps_txt.read_text().splitlines(): + app_name = app_name.strip() + if app_name: + app_root_dir = apps_dir / app_name + if app_root_dir.exists() and str(app_root_dir) not in sys.path: + sys.path.insert(0, str(app_root_dir)) except Exception: pass finally: @@ -92,24 +100,17 @@ async def _process_whitelist_call(request: Request, full_module_path: str): # 确保 apps 目录在 sys.path 中(支持跨 app 导入) _ensure_apps_on_sys_path() - # 先导入模块,确保装饰器执行 - module_info = parse_module_path(full_module_path) - module = import_module(module_info['module_path']) + # 解析路径并导入 + modulename = ".".join(full_module_path.split('.')[:-1]) + methodname = full_module_path.split('.')[-1] + module = import_module(modulename) + func = getattr(module, methodname) - # 使用实际模块路径匹配白名单(装饰器注册时使用 func.__module__) - actual_module_name = module.__name__ - actual_whitelist_path = f"{actual_module_name}.{module_info['function_name']}" - - # 检查白名单:优先使用实际模块路径,也支持原始路径 - whitelist_info = None - for check_path in [actual_whitelist_path, full_module_path]: - if is_whitelisted(check_path): - whitelist_info = get_whitelisted_function(check_path) - break + # 检查白名单(装饰器注册时使用 func.__module__) + actual_whitelist_path = f"{module.__name__}.{methodname}" + whitelist_info = get_whitelisted_function(actual_whitelist_path) if whitelist_info: - func = whitelist_info['function'] - # 检查 HTTP 方法 if request.method not in whitelist_info['methods']: raise HTTPException(status_code=405, detail=f"Method {request.method} not allowed") @@ -118,19 +119,8 @@ async def _process_whitelist_call(request: Request, full_module_path: str): if not whitelist_info['allow_guest']: if not await authenticate_request(request, whitelist_info['allow_guest']): raise HTTPException(status_code=401, detail="Authentication required") - - # 获取请求数据并调用函数 - request_data = await _get_request_data(request) - result = func(**request_data) - - return JSONResponse(content={"success": True, "data": result}) - # 非白名单:按原逻辑调用模块函数 - function_name = module_info['function_name'] - if not hasattr(module, function_name): - raise HTTPException(status_code=404, detail=f"Function {function_name} not found") - - func = getattr(module, function_name) + # 调用函数 request_data = await _get_request_data(request) result = func(**request_data) @@ -146,7 +136,7 @@ async def _process_whitelist_call(request: Request, full_module_path: str): @router.api_route("/{module_path:path}", methods=["GET", "POST", "PUT", "DELETE"]) async def handle_request(request: Request, module_path: str): """ - 动态路由:支持完整点分路径,例如 demo.demo.pagetype.hello_world.hello_world.test_whitelist + 兼容旧路径:直接传入完整点分路径 '' """ return await _process_whitelist_call(request, module_path) @@ -154,7 +144,7 @@ async def handle_request(request: Request, module_path: str): @router.api_route("/{app}/{module_path:path}", methods=["GET", "POST", "PUT", "DELETE"]) async def handle_request_with_app_prefix(request: Request, app: str, module_path: str): """ - 动态路由:支持 app 前缀格式,例如 /demo/demo.pagetype.hello_world.hello_world.test_whitelist + 新路径:支持以 app 作为前缀,例如 app.module.function """ full_module_path = f"{app}.{module_path}" return await _process_whitelist_call(request, full_module_path)