统一http客户端,自动 session cookie
This commit is contained in:
parent
496efd8d31
commit
829174439f
@ -2,30 +2,30 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
"""
|
"""
|
||||||
API v2 路由 - 转发到 SaaS 端
|
API v2 routes - Forward to SaaS using unified HTTP client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter, Request
|
from fastapi import APIRouter, Request
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
import requests
|
|
||||||
import logging
|
import logging
|
||||||
from jingrow.config import Config
|
import time
|
||||||
from jingrow.utils.auth import get_request_session_cookie
|
from jingrow.utils.auth import saas_get
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
router = APIRouter(prefix="/api/v2")
|
router = APIRouter(prefix="/api/v2")
|
||||||
|
|
||||||
|
|
||||||
def _forward_to_saas(endpoint: str, params: dict = None) -> dict:
|
def _forward_to_saas(endpoint: str, params: dict = None) -> dict:
|
||||||
"""通用转发函数"""
|
"""Forward request to SaaS using unified HTTP client"""
|
||||||
url = f"{Config.jingrow_server_url}/api/v2{endpoint}"
|
start_time = time.time()
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
print(f"[v2] Forwarding to: {endpoint}")
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
resp = saas_get(f"/api/v2{endpoint}", params=params)
|
||||||
|
|
||||||
|
req_time = time.time() - start_time
|
||||||
|
print(f"[v2] Response: status={resp.status_code}, time={req_time:.3f}s, endpoint={endpoint}")
|
||||||
|
|
||||||
resp = requests.get(url, headers=headers, params=params, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json()
|
return resp.json()
|
||||||
logger.error(f"[v2] SaaS error {endpoint}: {resp.status_code}")
|
logger.error(f"[v2] SaaS error {endpoint}: {resp.status_code}")
|
||||||
@ -34,14 +34,14 @@ def _forward_to_saas(endpoint: str, params: dict = None) -> dict:
|
|||||||
|
|
||||||
@router.get("/pagetype/{pagetype}/meta")
|
@router.get("/pagetype/{pagetype}/meta")
|
||||||
async def get_meta(pagetype: str):
|
async def get_meta(pagetype: str):
|
||||||
"""获取 PageType 元数据 - 转发到 SaaS 端"""
|
"""Get PageType metadata - Forward to SaaS"""
|
||||||
result = _forward_to_saas(f"/pagetype/{pagetype}/meta")
|
result = _forward_to_saas(f"/pagetype/{pagetype}/meta")
|
||||||
return JSONResponse(content=result)
|
return JSONResponse(content=result)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/pagetype/{pagetype}/count")
|
@router.get("/pagetype/{pagetype}/count")
|
||||||
async def get_count(pagetype: str, request: Request):
|
async def get_count(pagetype: str, request: Request):
|
||||||
"""获取 PageType 计数 - 转发到 SaaS 端"""
|
"""Get PageType count - Forward to SaaS"""
|
||||||
params = dict(request.query_params)
|
params = dict(request.query_params)
|
||||||
result = _forward_to_saas(f"/pagetype/{pagetype}/count", params)
|
result = _forward_to_saas(f"/pagetype/{pagetype}/count", params)
|
||||||
return JSONResponse(content=result)
|
return JSONResponse(content=result)
|
||||||
|
|||||||
@ -2,29 +2,20 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Client 相关白名单函数 - 转发到 SaaS 端
|
Client whitelist functions - Forward to SaaS using unified HTTP client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import jingrow
|
import jingrow
|
||||||
import requests
|
|
||||||
import logging
|
import logging
|
||||||
from jingrow.config import Config
|
from jingrow.utils.auth import saas_get, saas_post
|
||||||
from jingrow.utils.auth import get_request_session_cookie
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def get_list(**kwargs):
|
def get_list(**kwargs):
|
||||||
"""获取列表 - 转发到 SaaS 端"""
|
"""Get list - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.client.get_list"
|
resp = saas_post('/api/action/jingrow.client.get_list', json=kwargs)
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.post(url, headers=headers, json=kwargs, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message", [])
|
return resp.json().get("message", [])
|
||||||
logger.error(f"[get_list] SaaS error: {resp.status_code} - {resp.text[:200]}")
|
logger.error(f"[get_list] SaaS error: {resp.status_code} - {resp.text[:200]}")
|
||||||
@ -33,15 +24,8 @@ def get_list(**kwargs):
|
|||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def get_value(**kwargs):
|
def get_value(**kwargs):
|
||||||
"""获取值 - 转发到 SaaS 端"""
|
"""Get value - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.client.get_value"
|
resp = saas_post('/api/action/jingrow.client.get_value', json=kwargs)
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.post(url, headers=headers, json=kwargs, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message")
|
return resp.json().get("message")
|
||||||
logger.error(f"[get_value] SaaS error: {resp.status_code} - {resp.text[:200]}")
|
logger.error(f"[get_value] SaaS error: {resp.status_code} - {resp.text[:200]}")
|
||||||
@ -50,15 +34,8 @@ def get_value(**kwargs):
|
|||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def get_count(**kwargs):
|
def get_count(**kwargs):
|
||||||
"""获取计数 - 转发到 SaaS 端"""
|
"""Get count - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.client.get_count"
|
resp = saas_get('/api/action/jingrow.client.get_count', params=kwargs)
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.get(url, headers=headers, params=kwargs, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message", 0)
|
return resp.json().get("message", 0)
|
||||||
logger.error(f"[get_count] SaaS error: {resp.status_code} - {resp.text[:200]}")
|
logger.error(f"[get_count] SaaS error: {resp.status_code} - {resp.text[:200]}")
|
||||||
|
|||||||
@ -2,29 +2,20 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
"""
|
"""
|
||||||
User 相关白名单函数 - 转发到 SaaS 端
|
User whitelist functions - Forward to SaaS using unified HTTP client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import jingrow
|
import jingrow
|
||||||
import requests
|
|
||||||
import logging
|
import logging
|
||||||
from jingrow.config import Config
|
from jingrow.utils.auth import saas_post
|
||||||
from jingrow.utils.auth import get_request_session_cookie
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def get_all_roles(**kwargs):
|
def get_all_roles(**kwargs):
|
||||||
"""获取所有角色 - 转发到 SaaS 端"""
|
"""Get all roles - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.core.pagetype.user.user.get_all_roles"
|
resp = saas_post('/api/action/jingrow.core.pagetype.user.user.get_all_roles', json=kwargs)
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.post(url, headers=headers, json=kwargs, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message", [])
|
return resp.json().get("message", [])
|
||||||
logger.error(f"[user.get_all_roles] SaaS error: {resp.status_code}")
|
logger.error(f"[user.get_all_roles] SaaS error: {resp.status_code}")
|
||||||
|
|||||||
@ -2,29 +2,20 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Desktop 相关白名单函数 - 转发到 SaaS 端
|
Desktop whitelist functions - Forward to SaaS using unified HTTP client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import jingrow
|
import jingrow
|
||||||
import requests
|
|
||||||
import logging
|
import logging
|
||||||
from jingrow.config import Config
|
from jingrow.utils.auth import saas_post
|
||||||
from jingrow.utils.auth import get_request_session_cookie
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def get_workspace_sidebar_items(**kwargs):
|
def get_workspace_sidebar_items(**kwargs):
|
||||||
"""获取工作区侧边栏项目 - 转发到 SaaS 端"""
|
"""Get workspace sidebar items - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.desk.desktop.get_workspace_sidebar_items"
|
resp = saas_post('/api/action/jingrow.desk.desktop.get_workspace_sidebar_items', json=kwargs)
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.post(url, headers=headers, json=kwargs, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message", {})
|
return resp.json().get("message", {})
|
||||||
logger.error(f"[get_workspace_sidebar_items] SaaS error: {resp.status_code}")
|
logger.error(f"[get_workspace_sidebar_items] SaaS error: {resp.status_code}")
|
||||||
@ -33,15 +24,8 @@ def get_workspace_sidebar_items(**kwargs):
|
|||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def get_desktop_page(**kwargs):
|
def get_desktop_page(**kwargs):
|
||||||
"""获取桌面页面 - 转发到 SaaS 端"""
|
"""Get desktop page - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.desk.desktop.get_desktop_page"
|
resp = saas_post('/api/action/jingrow.desk.desktop.get_desktop_page', json=kwargs)
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.post(url, headers=headers, json=kwargs, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message", {})
|
return resp.json().get("message", {})
|
||||||
logger.error(f"[get_desktop_page] SaaS error: {resp.status_code}")
|
logger.error(f"[get_desktop_page] SaaS error: {resp.status_code}")
|
||||||
|
|||||||
@ -2,32 +2,33 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Form load 相关白名单函数 - 转发到 SaaS 端
|
Form load whitelist functions - Forward to SaaS using unified HTTP client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import jingrow
|
import jingrow
|
||||||
import requests
|
|
||||||
import logging
|
import logging
|
||||||
from jingrow.config import Config
|
import time
|
||||||
from jingrow.utils.auth import get_request_session_cookie
|
from jingrow.utils.auth import saas_post
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def getdoc(**kwargs):
|
def getdoc(**kwargs):
|
||||||
"""获取文档 - 转发到 SaaS 端"""
|
"""Get document - Forward to SaaS using unified HTTP client"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.desk.form.load.getdoc"
|
start_time = time.time()
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
print(f"[getdoc] Requesting: pagetype={kwargs.get('pagetype')}, name={kwargs.get('name')}")
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
resp = saas_post('/api/action/jingrow.desk.form.load.getdoc', json=kwargs)
|
||||||
|
|
||||||
|
req_time = time.time() - start_time
|
||||||
|
print(f"[getdoc] SaaS response: status={resp.status_code}, time={req_time:.3f}s")
|
||||||
|
|
||||||
resp = requests.post(url, headers=headers, json=kwargs, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
# SaaS getdoc 直接返回 {docs: [...], docinfo: {...}} 格式
|
result = resp.json()
|
||||||
# 不包装在 message 里
|
resp_size = len(resp.content) / 1024 # KB
|
||||||
return resp.json()
|
print(f"[getdoc] Total time: {time.time() - start_time:.3f}s, response size: {resp_size:.1f}KB")
|
||||||
logger.error(f"[getdoc] SaaS error: {resp.status_code} - {resp.text[:200]}")
|
return result
|
||||||
|
print(f"[getdoc] SaaS error: {resp.status_code} - {resp.text[:200]}")
|
||||||
return {}
|
return {}
|
||||||
|
|||||||
@ -2,29 +2,20 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dashboard Chart 相关白名单函数 - 转发到 SaaS 端
|
Dashboard Chart whitelist functions - Forward to SaaS using unified HTTP client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import jingrow
|
import jingrow
|
||||||
import requests
|
|
||||||
import logging
|
import logging
|
||||||
from jingrow.config import Config
|
from jingrow.utils.auth import saas_post
|
||||||
from jingrow.utils.auth import get_request_session_cookie
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def get(**kwargs):
|
def get(**kwargs):
|
||||||
"""获取 Dashboard Chart - 转发到 SaaS 端"""
|
"""Get Dashboard Chart - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.desk.pagetype.dashboard_chart.dashboard_chart.get"
|
resp = saas_post('/api/action/jingrow.desk.pagetype.dashboard_chart.dashboard_chart.get', json=kwargs)
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.post(url, headers=headers, json=kwargs, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message", {})
|
return resp.json().get("message", {})
|
||||||
logger.error(f"[dashboard_chart.get] SaaS error: {resp.status_code}")
|
logger.error(f"[dashboard_chart.get] SaaS error: {resp.status_code}")
|
||||||
|
|||||||
@ -2,29 +2,20 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dashboard Chart Source 相关白名单函数 - 转发到 SaaS 端
|
Dashboard Chart Source whitelist functions - Forward to SaaS using unified HTTP client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import jingrow
|
import jingrow
|
||||||
import requests
|
|
||||||
import logging
|
import logging
|
||||||
from jingrow.config import Config
|
from jingrow.utils.auth import saas_post
|
||||||
from jingrow.utils.auth import get_request_session_cookie
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def get_config(**kwargs):
|
def get_config(**kwargs):
|
||||||
"""获取 Chart Source 配置 - 转发到 SaaS 端"""
|
"""Get Chart Source config - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.desk.pagetype.dashboard_chart_source.dashboard_chart_source.get_config"
|
resp = saas_post('/api/action/jingrow.desk.pagetype.dashboard_chart_source.dashboard_chart_source.get_config', json=kwargs)
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.post(url, headers=headers, json=kwargs, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message", {})
|
return resp.json().get("message", {})
|
||||||
logger.error(f"[dashboard_chart_source.get_config] SaaS error: {resp.status_code}")
|
logger.error(f"[dashboard_chart_source.get_config] SaaS error: {resp.status_code}")
|
||||||
|
|||||||
@ -2,29 +2,20 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Query Report 相关白名单函数 - 转发到 SaaS 端
|
Query Report whitelist functions - Forward to SaaS using unified HTTP client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import jingrow
|
import jingrow
|
||||||
import requests
|
|
||||||
import logging
|
import logging
|
||||||
from jingrow.config import Config
|
from jingrow.utils.auth import saas_post
|
||||||
from jingrow.utils.auth import get_request_session_cookie
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def run(**kwargs):
|
def run(**kwargs):
|
||||||
"""运行查询报表 - 转发到 SaaS 端"""
|
"""Run query report - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.desk.query_report.run"
|
resp = saas_post('/api/action/jingrow.desk.query_report.run', json=kwargs)
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.post(url, headers=headers, json=kwargs, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message", {})
|
return resp.json().get("message", {})
|
||||||
logger.error(f"[query_report.run] SaaS error: {resp.status_code}")
|
logger.error(f"[query_report.run] SaaS error: {resp.status_code}")
|
||||||
@ -33,15 +24,8 @@ def run(**kwargs):
|
|||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def get_script(**kwargs):
|
def get_script(**kwargs):
|
||||||
"""获取报表脚本 - 转发到 SaaS 端"""
|
"""Get report script - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.desk.query_report.get_script"
|
resp = saas_post('/api/action/jingrow.desk.query_report.get_script', json=kwargs)
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.post(url, headers=headers, json=kwargs, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message", {})
|
return resp.json().get("message", {})
|
||||||
logger.error(f"[query_report.get_script] SaaS error: {resp.status_code}")
|
logger.error(f"[query_report.get_script] SaaS error: {resp.status_code}")
|
||||||
|
|||||||
@ -2,29 +2,20 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Search 相关白名单函数 - 转发到 SaaS 端
|
Search whitelist functions - Forward to SaaS using unified HTTP client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import jingrow
|
import jingrow
|
||||||
import requests
|
|
||||||
import logging
|
import logging
|
||||||
from jingrow.config import Config
|
from jingrow.utils.auth import saas_post
|
||||||
from jingrow.utils.auth import get_request_session_cookie
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def search_link(**kwargs):
|
def search_link(**kwargs):
|
||||||
"""搜索链接 - 转发到 SaaS 端"""
|
"""Search link - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.desk.search.search_link"
|
resp = saas_post('/api/action/jingrow.desk.search.search_link', json=kwargs)
|
||||||
headers = {"Accept": "application/json", "Content-Type": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.post(url, headers=headers, json=kwargs, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message", [])
|
return resp.json().get("message", [])
|
||||||
logger.error(f"[search_link] SaaS error: {resp.status_code}")
|
logger.error(f"[search_link] SaaS error: {resp.status_code}")
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Jingrow 白名单路由服务
|
Jingrow whitelist routing service
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter, Request, HTTPException
|
from fastapi import APIRouter, Request, HTTPException
|
||||||
@ -11,7 +11,7 @@ import importlib
|
|||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
import logging
|
import logging
|
||||||
from jingrow import get_whitelisted_function
|
from jingrow import get_whitelisted_function
|
||||||
from jingrow.utils.auth import get_jingrow_api_headers
|
from jingrow.utils.auth import get_jingrow_api_headers, set_request_session_cookie
|
||||||
from jingrow.utils.jingrow_api import get_logged_user
|
from jingrow.utils.jingrow_api import get_logged_user
|
||||||
from jingrow.utils.app_manager import ensure_apps_on_sys_path
|
from jingrow.utils.app_manager import ensure_apps_on_sys_path
|
||||||
|
|
||||||
@ -20,41 +20,41 @@ router = APIRouter(prefix="/api/action")
|
|||||||
|
|
||||||
async def authenticate_request(request: Request, allow_guest: bool) -> bool:
|
async def authenticate_request(request: Request, allow_guest: bool) -> bool:
|
||||||
"""
|
"""
|
||||||
认证请求,支持两种认证方式:
|
Authenticate request. Supports:
|
||||||
1. Session Cookie 认证
|
1. Session Cookie authentication
|
||||||
2. API Key 认证
|
2. API Key authentication
|
||||||
"""
|
"""
|
||||||
if allow_guest:
|
if allow_guest:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# 方式1: 检查 Session Cookie 认证
|
# Method 1: Check Session Cookie authentication
|
||||||
session_cookie = request.cookies.get('sid')
|
session_cookie = request.cookies.get('sid')
|
||||||
if session_cookie:
|
if session_cookie:
|
||||||
try:
|
try:
|
||||||
user = get_logged_user(session_cookie)
|
user = get_logged_user(session_cookie)
|
||||||
if user:
|
if user:
|
||||||
logger.info(f"Session认证成功: {user}")
|
# Store session cookie in ContextVar for downstream use
|
||||||
|
set_request_session_cookie(session_cookie)
|
||||||
|
logger.info(f"Session authenticated: {user}")
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Session认证失败: {e}")
|
logger.warning(f"Session authentication failed: {e}")
|
||||||
|
|
||||||
# 方式2: 检查 API Key 认证
|
# Method 2: Check API Key authentication
|
||||||
auth_header = request.headers.get('Authorization')
|
auth_header = request.headers.get('Authorization')
|
||||||
if auth_header and auth_header.startswith('token '):
|
if auth_header and auth_header.startswith('token '):
|
||||||
try:
|
try:
|
||||||
# 验证API Key格式: token key:secret
|
token_part = auth_header[6:]
|
||||||
token_part = auth_header[6:] # 移除 "token " 前缀
|
|
||||||
if ':' in token_part:
|
if ':' in token_part:
|
||||||
api_key, api_secret = token_part.split(':', 1)
|
api_key, api_secret = token_part.split(':', 1)
|
||||||
# 验证API Key是否有效
|
|
||||||
expected_headers = get_jingrow_api_headers()
|
expected_headers = get_jingrow_api_headers()
|
||||||
if expected_headers and expected_headers.get('Authorization') == auth_header:
|
if expected_headers and expected_headers.get('Authorization') == auth_header:
|
||||||
logger.info("API Key认证成功")
|
logger.info("API Key authenticated")
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"API Key认证失败: {e}")
|
logger.warning(f"API Key authentication failed: {e}")
|
||||||
|
|
||||||
logger.warning("认证失败: 未提供有效的认证信息")
|
logger.warning("Authentication failed: no valid credentials")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def _process_whitelist_call(request: Request, full_module_path: str):
|
async def _process_whitelist_call(request: Request, full_module_path: str):
|
||||||
|
|||||||
@ -2,26 +2,17 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
"""
|
"""
|
||||||
会话相关白名单函数 - 转发到 SaaS 端
|
Session whitelist functions - Forward to SaaS using unified HTTP client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import jingrow
|
import jingrow
|
||||||
import requests
|
from jingrow.utils.auth import saas_get
|
||||||
from jingrow.config import Config
|
|
||||||
from jingrow.utils.auth import get_request_session_cookie
|
|
||||||
|
|
||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def get_boot_info():
|
def get_boot_info():
|
||||||
"""获取启动信息 - 转发到 SaaS 端"""
|
"""Get boot info - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.sessions.get_boot_info"
|
resp = saas_get('/api/action/jingrow.sessions.get_boot_info')
|
||||||
headers = {"Accept": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.get(url, headers=headers, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message", {})
|
return resp.json().get("message", {})
|
||||||
return {}
|
return {}
|
||||||
@ -29,15 +20,8 @@ def get_boot_info():
|
|||||||
|
|
||||||
@jingrow.whitelist()
|
@jingrow.whitelist()
|
||||||
def get_translations():
|
def get_translations():
|
||||||
"""获取翻译 - 转发到 SaaS 端"""
|
"""Get translations - Forward to SaaS"""
|
||||||
url = f"{Config.jingrow_server_url}/api/action/jingrow.sessions.get_translations"
|
resp = saas_get('/api/action/jingrow.sessions.get_translations')
|
||||||
headers = {"Accept": "application/json"}
|
|
||||||
|
|
||||||
session_cookie = get_request_session_cookie()
|
|
||||||
if session_cookie:
|
|
||||||
headers["Cookie"] = f"sid={session_cookie}"
|
|
||||||
|
|
||||||
resp = requests.get(url, headers=headers, timeout=30)
|
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
return resp.json().get("message", {})
|
return resp.json().get("message", {})
|
||||||
return {}
|
return {}
|
||||||
|
|||||||
@ -2,10 +2,10 @@ import threading
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import requests
|
import requests
|
||||||
from typing import Optional
|
from typing import Optional, Dict, Any
|
||||||
from contextvars import ContextVar
|
from contextvars import ContextVar
|
||||||
|
|
||||||
# 导入配置
|
# Import config
|
||||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))))
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))))
|
||||||
from jingrow.config import Config
|
from jingrow.config import Config
|
||||||
|
|
||||||
@ -14,20 +14,79 @@ _thread_local = threading.local()
|
|||||||
# ContextVar for async-safe session cookie storage
|
# ContextVar for async-safe session cookie storage
|
||||||
_request_session_cookie: ContextVar[Optional[str]] = ContextVar('request_session_cookie', default=None)
|
_request_session_cookie: ContextVar[Optional[str]] = ContextVar('request_session_cookie', default=None)
|
||||||
|
|
||||||
|
# Global HTTP session with connection pooling
|
||||||
|
_http_session: Optional[requests.Session] = None
|
||||||
|
|
||||||
|
def _get_http_session() -> requests.Session:
|
||||||
|
"""Get or create global HTTP session with connection pooling"""
|
||||||
|
global _http_session
|
||||||
|
if _http_session is None:
|
||||||
|
_http_session = requests.Session()
|
||||||
|
adapter = requests.adapters.HTTPAdapter(
|
||||||
|
pool_connections=10,
|
||||||
|
pool_maxsize=20,
|
||||||
|
max_retries=2
|
||||||
|
)
|
||||||
|
_http_session.mount('http://', adapter)
|
||||||
|
_http_session.mount('https://', adapter)
|
||||||
|
return _http_session
|
||||||
|
|
||||||
|
def saas_request(method: str, endpoint: str, **kwargs) -> requests.Response:
|
||||||
|
"""
|
||||||
|
Unified HTTP client for SaaS requests with connection pooling and auto session cookie.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
method: HTTP method (GET, POST, etc.)
|
||||||
|
endpoint: API endpoint (e.g., '/api/action/jingrow.xxx' or '/api/v2/pagetype/User/meta')
|
||||||
|
**kwargs: Additional arguments for requests (json, params, data, timeout, etc.)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
requests.Response
|
||||||
|
|
||||||
|
Example:
|
||||||
|
# GET request
|
||||||
|
resp = saas_request('GET', '/api/v2/pagetype/User/meta')
|
||||||
|
|
||||||
|
# POST request
|
||||||
|
resp = saas_request('POST', '/api/action/jingrow.desk.form.load.getdoc', json={'pagetype': 'User', 'name': 'Administrator'})
|
||||||
|
"""
|
||||||
|
url = f"{Config.jingrow_server_url}{endpoint}"
|
||||||
|
headers = kwargs.pop('headers', {})
|
||||||
|
headers.setdefault('Accept', 'application/json')
|
||||||
|
headers.setdefault('Content-Type', 'application/json')
|
||||||
|
|
||||||
|
# Auto-add session cookie from ContextVar
|
||||||
|
session_cookie = get_request_session_cookie()
|
||||||
|
if session_cookie:
|
||||||
|
headers['Cookie'] = f"sid={session_cookie}"
|
||||||
|
|
||||||
|
timeout = kwargs.pop('timeout', 30)
|
||||||
|
|
||||||
|
session = _get_http_session()
|
||||||
|
return session.request(method.upper(), url, headers=headers, timeout=timeout, **kwargs)
|
||||||
|
|
||||||
|
def saas_get(endpoint: str, **kwargs) -> requests.Response:
|
||||||
|
"""Convenience method for GET requests to SaaS"""
|
||||||
|
return saas_request('GET', endpoint, **kwargs)
|
||||||
|
|
||||||
|
def saas_post(endpoint: str, **kwargs) -> requests.Response:
|
||||||
|
"""Convenience method for POST requests to SaaS"""
|
||||||
|
return saas_request('POST', endpoint, **kwargs)
|
||||||
|
|
||||||
def set_request_session_cookie(cookie: Optional[str]):
|
def set_request_session_cookie(cookie: Optional[str]):
|
||||||
"""设置当前请求的 session cookie(异步安全)"""
|
"""Set current request's session cookie (async-safe)"""
|
||||||
_request_session_cookie.set(cookie)
|
_request_session_cookie.set(cookie)
|
||||||
|
|
||||||
def get_request_session_cookie() -> Optional[str]:
|
def get_request_session_cookie() -> Optional[str]:
|
||||||
"""获取当前请求的 session cookie(异步安全)"""
|
"""Get current request's session cookie (async-safe)"""
|
||||||
return _request_session_cookie.get()
|
return _request_session_cookie.get()
|
||||||
|
|
||||||
def set_context(context):
|
def set_context(context):
|
||||||
"""设置当前线程的context"""
|
"""Set current thread's context"""
|
||||||
_thread_local.context = context
|
_thread_local.context = context
|
||||||
|
|
||||||
def get_jingrow_api_headers():
|
def get_jingrow_api_headers():
|
||||||
"""获取 Jingrow API 认证头部,用于系统级调用"""
|
"""Get Jingrow API auth headers for system-level calls"""
|
||||||
api_key = Config.jingrow_api_key
|
api_key = Config.jingrow_api_key
|
||||||
api_secret = Config.jingrow_api_secret
|
api_secret = Config.jingrow_api_secret
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user