From 4567cdc0d9cb7b42b6eba7b676c0ced3f4850d31 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 26 Mar 2026 18:17:49 -0500 Subject: [PATCH] refac --- backend/open_webui/routers/configs.py | 41 +++++++++++++++++++ src/lib/apis/configs/index.ts | 27 ++++++------ .../components/AddTerminalServerModal.svelte | 2 +- 3 files changed, 56 insertions(+), 14 deletions(-) diff --git a/backend/open_webui/routers/configs.py b/backend/open_webui/routers/configs.py index e738090a18..041c4ad935 100644 --- a/backend/open_webui/routers/configs.py +++ b/backend/open_webui/routers/configs.py @@ -314,6 +314,47 @@ async def verify_terminal_server_connection( raise HTTPException(status_code=400, detail='Failed to connect to the terminal server') +class TerminalServerPolicyForm(BaseModel): + url: str + key: Optional[str] = '' + auth_type: Optional[str] = 'bearer' + policy_id: str + policy_data: dict + + +@router.post('/terminal_servers/policy') +async def put_terminal_server_policy( + request: Request, form_data: TerminalServerPolicyForm, user=Depends(get_admin_user) +): + """ + Proxy a policy PUT to an orchestrator terminal server. + """ + base_url = (form_data.url or '').rstrip('/') + if not base_url: + raise HTTPException(status_code=400, detail='Terminal server URL is required') + + headers = {'Content-Type': 'application/json'} + if form_data.auth_type == 'bearer' and form_data.key: + headers['Authorization'] = f'Bearer {form_data.key}' + + try: + async with aiohttp.ClientSession( + trust_env=True, + timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT), + ) as session: + policy_url = f'{base_url}/api/v1/policies/{form_data.policy_id}' + async with session.put(policy_url, headers=headers, json=form_data.policy_data) as resp: + if resp.ok: + return await resp.json() + detail = await resp.text() + raise HTTPException(status_code=resp.status, detail=detail) + except HTTPException: + raise + except Exception as e: + log.debug(f'Failed to save policy to terminal server: {e}') + raise HTTPException(status_code=400, detail='Failed to save policy to terminal server') + + @router.post('/tool_servers/verify') async def verify_tool_servers_config(request: Request, form_data: ToolServerConnection, user=Depends(get_admin_user)): """ diff --git a/src/lib/apis/configs/index.ts b/src/lib/apis/configs/index.ts index 2f26d711ea..6b7bf6f47b 100644 --- a/src/lib/apis/configs/index.ts +++ b/src/lib/apis/configs/index.ts @@ -268,9 +268,10 @@ export const detectTerminalServerType = async ( /** * Create or update a policy on the orchestrator. - * PUT {url}/api/v1/policies/{policyId} + * Proxied through the Open WebUI backend to keep API keys server-side. */ export const putOrchestratorPolicy = async ( + token: string, url: string, key: string, policyId: string, @@ -278,18 +279,18 @@ export const putOrchestratorPolicy = async ( ): Promise => { let error = null; - const baseUrl = url.replace(/\/$/, ''); - const headers: Record = { - 'Content-Type': 'application/json' - }; - if (key) { - headers['Authorization'] = `Bearer ${key}`; - } - - const res = await fetch(`${baseUrl}/api/v1/policies/${encodeURIComponent(policyId)}`, { - method: 'PUT', - headers, - body: JSON.stringify(policyData) + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/terminal_servers/policy`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + url: url.replace(/\/$/, ''), + key, + policy_id: policyId, + policy_data: policyData + }) }) .then(async (res) => { if (!res.ok) throw await res.json(); diff --git a/src/lib/components/AddTerminalServerModal.svelte b/src/lib/components/AddTerminalServerModal.svelte index 466884b3ed..f5b1612ee2 100644 --- a/src/lib/components/AddTerminalServerModal.svelte +++ b/src/lib/components/AddTerminalServerModal.svelte @@ -198,7 +198,7 @@ // Save policy to orchestrator if applicable if (serverType === 'orchestrator' && !direct && policyId) { try { - await putOrchestratorPolicy(url, key, policyId, buildPolicyData()); + await putOrchestratorPolicy(localStorage.token, url, key, policyId, buildPolicyData()); } catch (err) { toast.error($i18n.t('Failed to save policy: {{error}}', { error: err })); return;