This commit is contained in:
Timothy Jaeryang Baek 2026-09-07 12:40:44 -04:00
parent f9f815c862
commit f5fcf4c89f
2 changed files with 37 additions and 0 deletions

View file

@ -1,3 +1,4 @@
import logging
from typing import Any
from open_webui.config import DEFAULT_USER_PERMISSIONS
@ -14,6 +15,8 @@ from open_webui.models.users import UserModel
from open_webui.utils.json_codec import JSONCodec
from sqlalchemy.ext.asyncio import AsyncSession
log = logging.getLogger(__name__)
def fill_missing_permissions(permissions: dict[str, Any], default_permissions: dict[str, Any]) -> dict[str, Any]:
"""
@ -325,6 +328,13 @@ async def has_base_model_access(
seen.add(base_model_id)
base_model_info = await Models.get_model_by_id(base_model_id, db=db)
if base_model_info is None:
if user_role != 'admin':
log.warning(
'Model access denied: user_id=%r model_id=%r base_model_id=%r reason=base_model_unregistered',
user_id,
model_info.id,
base_model_id,
)
return user_role == 'admin'
if not (
user_id == base_model_info.user_id
@ -337,6 +347,12 @@ async def has_base_model_access(
db=db,
)
):
log.warning(
'Model access denied: user_id=%r model_id=%r base_model_id=%r reason=base_model_read_denied',
user_id,
model_info.id,
base_model_id,
)
return False
base_model_id = getattr(base_model_info, 'base_model_id', None)
return True
@ -381,6 +397,11 @@ async def check_model_access(
user_group_ids=user_group_ids,
)
):
log.warning(
'Model access denied: user_id=%r model_id=%r reason=model_read_denied',
user.id,
model_info.id,
)
raise HTTPException(status_code=403, detail='Model not found')
# Enforce access on chained base models
@ -388,4 +409,5 @@ async def check_model_access(
raise HTTPException(status_code=403, detail='Model not found')
else:
if user.role != 'admin':
log.warning('Model access denied: user_id=%r reason=model_unregistered', user.id)
raise HTTPException(status_code=403, detail='Model not found')

View file

@ -468,12 +468,22 @@ async def check_model_access(user, model, model_info=None, db=None):
access_grants=access_grants,
db=db,
):
log.warning(
'Model access denied: user_id=%r model_id=%r reason=arena_read_denied',
user.id,
model.get('id'),
)
raise Exception('Model not found')
else:
# Callers that already fetched the row (chat completion entry) pass it in
if model_info is None or model_info.id != model.get('id'):
model_info = await Models.get_model_by_id(model.get('id'), db=db)
if not model_info:
log.warning(
'Model access denied: user_id=%r model_id=%r reason=model_unregistered',
user.id,
model.get('id'),
)
raise Exception('Model not found')
# One group-membership fetch shared by the direct check and every
@ -493,6 +503,11 @@ async def check_model_access(user, model, model_info=None, db=None):
db=db,
)
):
log.warning(
'Model access denied: user_id=%r model_id=%r reason=model_read_denied',
user.id,
model_info.id,
)
raise Exception('Model not found')
# Enforce access on chained base models