diff --git a/backend/open_webui/models/knowledge.py b/backend/open_webui/models/knowledge.py index 401265a1c6..848232d6f2 100644 --- a/backend/open_webui/models/knowledge.py +++ b/backend/open_webui/models/knowledge.py @@ -467,14 +467,22 @@ class KnowledgeTable: print('search_knowledge_files error:', e) return KnowledgeFileListResponse(items=[], total=0) - async def check_access_by_user_id(self, id, user_id, permission='write', db: Optional[AsyncSession] = None) -> bool: + async def check_access_by_user_id( + self, + id, + user_id, + permission='write', + db: Optional[AsyncSession] = None, + user_group_ids: set[str] | None = None, + ) -> bool: knowledge = await self.get_knowledge_by_id(id, db=db) if not knowledge: return False if knowledge.user_id == user_id: return True - user_groups = await Groups.get_groups_by_member_id(user_id, db=db) - user_group_ids = {group.id for group in user_groups} + if user_group_ids is None: + user_groups = await Groups.get_groups_by_member_id(user_id, db=db) + user_group_ids = {group.id for group in user_groups} return await AccessGrants.has_access( user_id=user_id, resource_type='knowledge', diff --git a/backend/open_webui/routers/folders.py b/backend/open_webui/routers/folders.py index c4ed8d0d4d..9a6ff1c4df 100644 --- a/backend/open_webui/routers/folders.py +++ b/backend/open_webui/routers/folders.py @@ -99,6 +99,10 @@ async def get_folders( folders = await Folders.get_folders_by_user_id(user.id, db=db) folder_ids = {folder.id for folder in folders} + user_group_ids = None + if user.role != 'admin' and any(folder.data and 'files' in folder.data for folder in folders): + user_group_ids = {group.id for group in await Groups.get_groups_by_member_id(user.id, db=db)} + # Verify folder data integrity folder_list = [] for folder in folders: @@ -106,7 +110,9 @@ async def get_folders( folder = await Folders.update_folder_parent_id_by_id_and_user_id(folder.id, user.id, None, db=db) if folder.data and 'files' in folder.data: - accessible_files = await get_accessible_folder_files(folder.data['files'], user, db=db) + accessible_files = await get_accessible_folder_files( + folder.data['files'], user, db=db, user_group_ids=user_group_ids + ) if len(accessible_files) != len(folder.data.get('files', [])): folder.data['files'] = accessible_files await Folders.update_folder_by_id_and_user_id( diff --git a/backend/open_webui/utils/access_control/files.py b/backend/open_webui/utils/access_control/files.py index 5d192db603..efc8b11222 100644 --- a/backend/open_webui/utils/access_control/files.py +++ b/backend/open_webui/utils/access_control/files.py @@ -128,6 +128,7 @@ async def get_accessible_folder_files( entries: list[dict] | None, user: UserModel, db: AsyncSession | None = None, + user_group_ids: set[str] | None = None, ) -> list[dict]: """Filter folder.data['files'] entries to those the caller can read. @@ -144,8 +145,8 @@ async def get_accessible_folder_files( if user.role == 'admin': return entries - # One group-membership fetch for the whole folder listing - user_group_ids = {group.id for group in await Groups.get_groups_by_member_id(user.id, db=db)} + if user_group_ids is None: + user_group_ids = {group.id for group in await Groups.get_groups_by_member_id(user.id, db=db)} accessible: list[dict] = [] for entry in entries: @@ -155,7 +156,9 @@ async def get_accessible_folder_files( if await has_access_to_file(entry_id, 'read', user, db=db, user_group_ids=user_group_ids): accessible.append(entry) elif entry_type == 'collection': - if await Knowledges.check_access_by_user_id(entry_id, user.id, 'read', db=db): + if await Knowledges.check_access_by_user_id( + entry_id, user.id, 'read', db=db, user_group_ids=user_group_ids + ): accessible.append(entry) elif entry_type == 'note': # Owner has no self-grant (notes are private by default), so check ownership too. @@ -169,6 +172,7 @@ async def get_accessible_folder_files( resource_type='note', resource_id=entry_id, permission='read', + user_group_ids=user_group_ids, db=db, ) ):