This commit is contained in:
Timothy Jaeryang Baek
2026-03-26 18:17:49 -05:00
parent a641325707
commit 4567cdc0d9
3 changed files with 56 additions and 14 deletions
+41
View File
@@ -314,6 +314,47 @@ async def verify_terminal_server_connection(
raise HTTPException(status_code=400, detail='Failed to connect to the terminal server') 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') @router.post('/tool_servers/verify')
async def verify_tool_servers_config(request: Request, form_data: ToolServerConnection, user=Depends(get_admin_user)): async def verify_tool_servers_config(request: Request, form_data: ToolServerConnection, user=Depends(get_admin_user)):
""" """
+14 -13
View File
@@ -268,9 +268,10 @@ export const detectTerminalServerType = async (
/** /**
* Create or update a policy on the orchestrator. * 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 ( export const putOrchestratorPolicy = async (
token: string,
url: string, url: string,
key: string, key: string,
policyId: string, policyId: string,
@@ -278,18 +279,18 @@ export const putOrchestratorPolicy = async (
): Promise<object | null> => { ): Promise<object | null> => {
let error = null; let error = null;
const baseUrl = url.replace(/\/$/, ''); const res = await fetch(`${WEBUI_API_BASE_URL}/configs/terminal_servers/policy`, {
const headers: Record<string, string> = { method: 'POST',
'Content-Type': 'application/json' headers: {
}; 'Content-Type': 'application/json',
if (key) { Authorization: `Bearer ${token}`
headers['Authorization'] = `Bearer ${key}`; },
} body: JSON.stringify({
url: url.replace(/\/$/, ''),
const res = await fetch(`${baseUrl}/api/v1/policies/${encodeURIComponent(policyId)}`, { key,
method: 'PUT', policy_id: policyId,
headers, policy_data: policyData
body: JSON.stringify(policyData) })
}) })
.then(async (res) => { .then(async (res) => {
if (!res.ok) throw await res.json(); if (!res.ok) throw await res.json();
@@ -198,7 +198,7 @@
// Save policy to orchestrator if applicable // Save policy to orchestrator if applicable
if (serverType === 'orchestrator' && !direct && policyId) { if (serverType === 'orchestrator' && !direct && policyId) {
try { try {
await putOrchestratorPolicy(url, key, policyId, buildPolicyData()); await putOrchestratorPolicy(localStorage.token, url, key, policyId, buildPolicyData());
} catch (err) { } catch (err) {
toast.error($i18n.t('Failed to save policy: {{error}}', { error: err })); toast.error($i18n.t('Failed to save policy: {{error}}', { error: err }));
return; return;