From a35b37adcd2cc21c41c9f98c6f7dc26f2551e022 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Fri, 24 Jul 2026 07:02:12 +0200 Subject: [PATCH] fix: keep chats shared with an admin readable when ENABLE_ADMIN_CHAT_ACCESS is off (#27127) get_chat_by_id sent admins down a branch that returned the chat only when ENABLE_ADMIN_CHAT_ACCESS was on, or the chat was internal, and never fell through to the access-grant and shared-folder checks. With the setting off, an admin was therefore denied a chat that had been deliberately shared with them, either directly or through a shared folder, while any non-admin holding the same grant could open it. The admin role removed access the user had been given rather than only closing the admin-only path. Try the admin path first, then let everyone fall through to the grant and folder checks. ENABLE_ADMIN_CHAT_ACCESS=false still closes the admin-only route to other users' chats, and internal chats stay reachable. --- backend/open_webui/routers/chats.py | 47 +++++++++++++++-------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/backend/open_webui/routers/chats.py b/backend/open_webui/routers/chats.py index 0f1a32251d..a136d3679d 100644 --- a/backend/open_webui/routers/chats.py +++ b/backend/open_webui/routers/chats.py @@ -1203,30 +1203,31 @@ async def compact_chat_by_id( async def get_chat_by_id(id: str, user=Depends(get_verified_user), db: AsyncSession = Depends(get_async_session)): chat = await Chats.get_chat_by_id_and_user_id(id, user.id, db=db) - if not chat: - # Check if user has access via access grants (shared_chat grants) - if user.role == 'admin': - candidate = await Chats.get_chat_by_id(id, db=db) - if ENABLE_ADMIN_CHAT_ACCESS or (candidate and is_internal_chat(candidate.meta)): - chat = candidate - else: - has_grant = await AccessGrants.has_access( - user_id=user.id, - resource_type='shared_chat', - resource_id=id, - permission='read', - db=db, - ) - if has_grant: - chat = await Chats.get_chat_by_id(id, db=db) + if not chat and user.role == 'admin': + candidate = await Chats.get_chat_by_id(id, db=db) + if ENABLE_ADMIN_CHAT_ACCESS or (candidate and is_internal_chat(candidate.meta)): + chat = candidate - # Check folder-based access (shared folders) - if not chat: - candidate = await Chats.get_chat_by_id(id, db=db) - if candidate and candidate.folder_id: - folder = await Folders.get_folder_by_id(candidate.folder_id, db=db) - if folder and await has_folder_access(user.id, folder, 'read', db): - chat = candidate + # Access explicitly granted to this user applies to admins too, so an admin + # does not lose a chat shared with them when ENABLE_ADMIN_CHAT_ACCESS is off. + if not chat: + has_grant = await AccessGrants.has_access( + user_id=user.id, + resource_type='shared_chat', + resource_id=id, + permission='read', + db=db, + ) + if has_grant: + chat = await Chats.get_chat_by_id(id, db=db) + + # Check folder-based access (shared folders) + if not chat: + candidate = await Chats.get_chat_by_id(id, db=db) + if candidate and candidate.folder_id: + folder = await Folders.get_folder_by_id(candidate.folder_id, db=db) + if folder and await has_folder_access(user.id, folder, 'read', db): + chat = candidate if chat: data = ChatResponse(**chat.model_dump()).model_dump()