mirror of
https://github.com/open-webui/open-webui.git
synced 2026-11-14 09:21:22 +00:00
refac
This commit is contained in:
parent
99f4541e3b
commit
69189cbaad
4 changed files with 28 additions and 25 deletions
|
|
@ -89,7 +89,6 @@ class AuthSessionsTable:
|
|||
return [
|
||||
{
|
||||
**{key: getattr(row, key) for key in ('id', 'created_at', 'updated_at', 'expires_at')},
|
||||
'connection_id': row.data.get('connection_id'),
|
||||
'name': row.data['name'],
|
||||
}
|
||||
for row in rows
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ PROOF_KEYS = ('auth_time', 'auth_method', 'session_stamp', 'mfa_verified')
|
|||
|
||||
class SessionForm(BaseModel):
|
||||
model_config = ConfigDict(extra='forbid', str_strip_whitespace=True)
|
||||
connection_id: UUID | None = None
|
||||
name: str = Field(min_length=1, max_length=100)
|
||||
|
||||
|
||||
|
|
@ -147,7 +146,7 @@ async def create_session(form: SessionForm, request: Request, user=Depends(get_h
|
|||
proof = await verify_proof(request.state.claims, request)
|
||||
row = await AuthSessions.create(
|
||||
user_id=user.id,
|
||||
data=form.model_dump(mode='json', exclude_none=True),
|
||||
data={'name': form.name},
|
||||
expires_at=await idle_expiry(),
|
||||
refresh_token_id=str(uuid4()),
|
||||
)
|
||||
|
|
@ -159,7 +158,7 @@ async def authorization_request(form: AuthorizationRequest, request: Request):
|
|||
await throttle(request)
|
||||
row = await AuthSessions.create(
|
||||
data={
|
||||
**form.model_dump(mode='json', include={'connection_id', 'name'}, exclude_none=True),
|
||||
'name': form.name,
|
||||
'authorization': {
|
||||
'redirect_uri': form.redirect_uri,
|
||||
'state': form.state,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import asyncio
|
|||
import json
|
||||
from contextlib import suppress
|
||||
from types import SimpleNamespace
|
||||
from uuid import uuid4
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
from fastapi import APIRouter, WebSocket
|
||||
from open_webui.models.auth_sessions import AuthSessions
|
||||
|
|
@ -31,9 +31,10 @@ async def connect(ws: WebSocket):
|
|||
row = await AuthSessions.get(claims['sid'])
|
||||
if not row or row.user_id != user.id or row.refresh_token_id is None:
|
||||
raise ValueError('Invalid session')
|
||||
connection_id = row.data.get('connection_id')
|
||||
if not connection_id:
|
||||
raise ValueError('A Tether connection ID is required')
|
||||
connection_id = str(UUID(hello['connection_id']))
|
||||
name = hello.get('name')
|
||||
if not isinstance(name, str) or not 1 <= len(name.strip()) <= 100:
|
||||
raise ValueError('A connection name of 1–100 characters is required')
|
||||
await hub.start()
|
||||
presence = {
|
||||
'connection': str(uuid4()),
|
||||
|
|
@ -41,6 +42,7 @@ async def connect(ws: WebSocket):
|
|||
'session': row.id,
|
||||
'user': user.id,
|
||||
'connection_id': connection_id,
|
||||
'name': name.strip(),
|
||||
}
|
||||
connection = SimpleNamespace(ws=ws, presence=presence, routes={}, lock=asyncio.Lock())
|
||||
|
||||
|
|
|
|||
|
|
@ -209,18 +209,25 @@ class Hub:
|
|||
None,
|
||||
)
|
||||
|
||||
async def presences(self, user_id):
|
||||
await self.start()
|
||||
if self.redis:
|
||||
records = []
|
||||
async for key in self.redis.scan_iter(match=self.key(user_id, '*'), count=100):
|
||||
raw = await self.redis.get(key)
|
||||
if raw:
|
||||
records.append(json.loads(raw))
|
||||
else:
|
||||
records = [connection.presence for connection in self.connections.values()]
|
||||
# SCAN may return a key more than once while connections are changing.
|
||||
return list({record['connection_id']: record for record in records if record['user'] == user_id}.values())
|
||||
|
||||
async def open(self, user_id, connection_id):
|
||||
presence = await self.presence(user_id, connection_id)
|
||||
if not presence:
|
||||
if not presence or presence['user'] != user_id or presence['connection_id'] != connection_id:
|
||||
raise HTTPException(503, 'Tether is offline.')
|
||||
row = await AuthSessions.get(presence['session'])
|
||||
if (
|
||||
not row
|
||||
or row.user_id != user_id
|
||||
or row.refresh_token_id is None
|
||||
or row.expires_at <= time.time()
|
||||
or row.data.get('connection_id') != connection_id
|
||||
):
|
||||
if not row or row.user_id != user_id or row.refresh_token_id is None or row.expires_at <= time.time():
|
||||
raise HTTPException(403, 'Tether session is no longer available.')
|
||||
if sum(s.presence['connection'] == presence['connection'] for s in self.streams.values()) >= 16:
|
||||
raise HTTPException(429, 'Tether has too many active operations.')
|
||||
|
|
@ -269,19 +276,15 @@ async def get_terminal_connections(user):
|
|||
"""Resolve personal targets alongside existing configured servers."""
|
||||
user_id = user['id'] if isinstance(user, dict) else user.id
|
||||
connections = list(await Config.get('terminal_server.connections', []) or [])
|
||||
seen = set()
|
||||
for row in await AuthSessions.list(user_id):
|
||||
connection_id = row['connection_id']
|
||||
if not connection_id or connection_id in seen:
|
||||
continue
|
||||
seen.add(connection_id)
|
||||
presence = await hub.presence(user_id, connection_id)
|
||||
if not presence:
|
||||
for presence in await hub.presences(user_id):
|
||||
row = await AuthSessions.get(presence['session'])
|
||||
if not row or row.user_id != user_id or row.refresh_token_id is None or row.expires_at <= time.time():
|
||||
continue
|
||||
connection_id = presence['connection_id']
|
||||
connections.append(
|
||||
{
|
||||
'id': 'tether:' + connection_id,
|
||||
'name': row['name'],
|
||||
'name': presence['name'],
|
||||
'url': 'tether://' + connection_id,
|
||||
'auth_type': 'none',
|
||||
'enabled': True,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue