mirror of
https://github.com/open-webui/open-webui.git
synced 2026-08-25 17:21:00 -05:00
Moving a folder under one of its own subfolders was accepted. A folder in a parent loop is never a root, so it and everything under it silently disappeared from the sidebar, and there was no way to get it back from the UI. The move is now rejected with a 400, folders whose parent chain loops are put back at the root on the next folder list, and the folder tree traversals skip ids they have already visited so existing data in that state stays workable.
35 lines
1.3 KiB
Python
35 lines
1.3 KiB
Python
from open_webui.models.access_grants import AccessGrants
|
|
from open_webui.models.folders import FolderModel, Folders
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
|
|
async def has_folder_access(user_id: str, folder: FolderModel, permission: str, db: AsyncSession | None) -> bool:
|
|
"""Check if user has access to folder directly or via ancestor inheritance."""
|
|
# A corrupt parent loop must not spin forever
|
|
seen_ids = set()
|
|
while folder and folder.id not in seen_ids:
|
|
seen_ids.add(folder.id)
|
|
|
|
if folder.user_id == user_id:
|
|
return True
|
|
|
|
if await AccessGrants.has_access(
|
|
user_id=user_id,
|
|
resource_type='folder',
|
|
resource_id=folder.id,
|
|
permission=permission,
|
|
db=db,
|
|
):
|
|
return True
|
|
|
|
folder = await Folders.get_folder_by_id(folder.parent_id, db=db) if folder.parent_id else None
|
|
return False
|
|
|
|
|
|
async def has_folder_write_access(user_id: str, folder_id: str, db: AsyncSession | None = None) -> bool:
|
|
"""Check write access on the folder with this id; False if no such folder exists."""
|
|
folder = await Folders.get_folder_by_id(folder_id, db=db)
|
|
if not folder:
|
|
return False
|
|
return await has_folder_access(user_id, folder, 'write', db)
|