Skip to content

Commit ae05586

Browse files
committed
refac: oauth session management
1 parent f5e5632 commit ae05586

3 files changed

Lines changed: 24 additions & 4 deletions

File tree

backend/open_webui/env.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,12 @@ def parse_section(section):
557557
"OAUTH_SESSION_TOKEN_ENCRYPTION_KEY", WEBUI_SECRET_KEY
558558
)
559559

560+
# Maximum number of concurrent OAuth sessions per user per provider
561+
# This prevents unbounded session growth while allowing multi-device usage
562+
OAUTH_MAX_SESSIONS_PER_USER = int(
563+
os.environ.get("OAUTH_MAX_SESSIONS_PER_USER", "10")
564+
)
565+
560566
# Token Exchange Configuration
561567
# Allows external apps to exchange OAuth tokens for OpenWebUI tokens
562568
ENABLE_OAUTH_TOKEN_EXCHANGE = (

backend/open_webui/models/oauth_sessions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ def get_session_by_provider_and_user_id(
188188
session = (
189189
db.query(OAuthSession)
190190
.filter_by(provider=provider, user_id=user_id)
191+
.order_by(OAuthSession.created_at.desc())
191192
.first()
192193
)
193194
if session:

backend/open_webui/utils/oauth.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
ENABLE_OAUTH_ID_TOKEN_COOKIE,
7070
ENABLE_OAUTH_EMAIL_FALLBACK,
7171
OAUTH_CLIENT_INFO_ENCRYPTION_KEY,
72+
OAUTH_MAX_SESSIONS_PER_USER,
7273
)
7374
from open_webui.utils.misc import parse_duration
7475
from open_webui.utils.auth import get_password_hash, create_token
@@ -1679,11 +1680,23 @@ async def handle_callback(self, request, provider, response, db=None):
16791680
if "expires_in" in token and "expires_at" not in token:
16801681
token["expires_at"] = datetime.now().timestamp() + token["expires_in"]
16811682

1682-
# Clean up any existing sessions for this user/provider first
1683+
# Enforce max concurrent sessions per user/provider to prevent
1684+
# unbounded growth while allowing multi-device usage
16831685
sessions = OAuthSessions.get_sessions_by_user_id(user.id, db=db)
1684-
for session in sessions:
1685-
if session.provider == provider:
1686-
OAuthSessions.delete_session_by_id(session.id, db=db)
1686+
provider_sessions = sorted(
1687+
[
1688+
for session in sessions
1689+
if session.provider == provider
1690+
],
1691+
key=lambda session: session.created_at,
1692+
reverse=True,
1693+
)
1694+
# Keep the newest sessions up to the limit, prune the rest
1695+
if len(provider_sessions) >= OAUTH_MAX_SESSIONS_PER_USER:
1696+
for old_session in provider_sessions[
1697+
OAUTH_MAX_SESSIONS_PER_USER - 1 :
1698+
]:
1699+
OAuthSessions.delete_session_by_id(old_session.id, db=db)
16871700

16881701
session = OAuthSessions.create_session(
16891702
user_id=user.id,

0 commit comments

Comments
 (0)