优化whitelist白名单函数机制,api路径更简短
This commit is contained in:
parent
dab5fa4cda
commit
6895bf380b
@ -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/<app>)
|
||||
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
|
||||
兼容旧路径:直接传入完整点分路径 '<package.module.function>'
|
||||
"""
|
||||
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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user