refac
This commit is contained in:
1 parent
18c604baa9
commit
7d4747dfd7
4 files changed
+52
-33
No files matched your search
@@ -19,6 +19,7 @@ from pydantic import BaseModel
|
|||||||
from open_webui.env import (
|
from open_webui.env import (
|
||||||
DATA_DIR,
|
DATA_DIR,
|
||||||
DATABASE_URL,
|
DATABASE_URL,
|
||||||
|
ENABLE_ADMIN_CHAT_ACCESS,
|
||||||
ENABLE_DB_MIGRATIONS,
|
ENABLE_DB_MIGRATIONS,
|
||||||
ENV,
|
ENV,
|
||||||
FRONTEND_BUILD_DIR,
|
FRONTEND_BUILD_DIR,
|
||||||
@@ -2085,8 +2086,6 @@ BYPASS_ADMIN_ACCESS_CONTROL = (
|
|||||||
== 'true'
|
== 'true'
|
||||||
)
|
)
|
||||||
|
|
||||||
ENABLE_ADMIN_CHAT_ACCESS = os.getenv('ENABLE_ADMIN_CHAT_ACCESS', 'True').lower() == 'true'
|
|
||||||
|
|
||||||
ENABLE_ADMIN_ANALYTICS = os.getenv('ENABLE_ADMIN_ANALYTICS', 'True').lower() == 'true'
|
ENABLE_ADMIN_ANALYTICS = os.getenv('ENABLE_ADMIN_ANALYTICS', 'True').lower() == 'true'
|
||||||
|
|
||||||
ENABLE_COMMUNITY_SHARING = os.getenv('ENABLE_COMMUNITY_SHARING', 'True').lower() == 'true'
|
ENABLE_COMMUNITY_SHARING = os.getenv('ENABLE_COMMUNITY_SHARING', 'True').lower() == 'true'
|
||||||
|
|||||||
@@ -365,6 +365,7 @@ ENABLE_PUBLIC_ACTIVE_USERS_COUNT = os.getenv('ENABLE_PUBLIC_ACTIVE_USERS_COUNT',
|
|||||||
RESET_CONFIG_ON_START = os.getenv('RESET_CONFIG_ON_START', 'False').lower() == 'true'
|
RESET_CONFIG_ON_START = os.getenv('RESET_CONFIG_ON_START', 'False').lower() == 'true'
|
||||||
ENABLE_REALTIME_CHAT_SAVE = os.getenv('ENABLE_REALTIME_CHAT_SAVE', 'False').lower() == 'true'
|
ENABLE_REALTIME_CHAT_SAVE = os.getenv('ENABLE_REALTIME_CHAT_SAVE', 'False').lower() == 'true'
|
||||||
ENABLE_QUERIES_CACHE = os.getenv('ENABLE_QUERIES_CACHE', 'False').lower() == 'true'
|
ENABLE_QUERIES_CACHE = os.getenv('ENABLE_QUERIES_CACHE', 'False').lower() == 'true'
|
||||||
|
ENABLE_ADMIN_CHAT_ACCESS = os.getenv('ENABLE_ADMIN_CHAT_ACCESS', 'True').lower() == 'true'
|
||||||
RAG_SYSTEM_CONTEXT = os.getenv('RAG_SYSTEM_CONTEXT', 'False').lower() == 'true'
|
RAG_SYSTEM_CONTEXT = os.getenv('RAG_SYSTEM_CONTEXT', 'False').lower() == 'true'
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ import time
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
|
from open_webui.env import ENABLE_ADMIN_CHAT_ACCESS
|
||||||
from open_webui.internal.db import Base, JSONField, get_async_db_context
|
from open_webui.internal.db import Base, JSONField, get_async_db_context
|
||||||
|
from open_webui.models.access_grants import AccessGrants
|
||||||
from open_webui.models.automations import AutomationRun
|
from open_webui.models.automations import AutomationRun
|
||||||
from open_webui.models.chat_messages import ChatMessage, ChatMessages
|
from open_webui.models.chat_messages import ChatMessage, ChatMessages
|
||||||
from open_webui.models.folders import Folders
|
from open_webui.models.folders import Folders
|
||||||
@@ -1634,6 +1636,41 @@ class ChatTable:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
async def get_chat_by_id_for_user(
|
||||||
|
self,
|
||||||
|
id: str,
|
||||||
|
user,
|
||||||
|
db: AsyncSession | None = None,
|
||||||
|
) -> ChatModel | None:
|
||||||
|
chat = await self.get_chat_by_id_and_user_id(id, user.id, db=db)
|
||||||
|
if chat:
|
||||||
|
return chat
|
||||||
|
|
||||||
|
chat = await self.get_chat_by_id(id, db=db)
|
||||||
|
if not chat:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if user.role == 'admin' and (ENABLE_ADMIN_CHAT_ACCESS or is_internal_chat(chat.meta)):
|
||||||
|
return chat
|
||||||
|
|
||||||
|
if await AccessGrants.has_access(
|
||||||
|
user_id=user.id,
|
||||||
|
resource_type='shared_chat',
|
||||||
|
resource_id=id,
|
||||||
|
permission='read',
|
||||||
|
db=db,
|
||||||
|
):
|
||||||
|
return chat
|
||||||
|
|
||||||
|
if chat.folder_id:
|
||||||
|
from open_webui.utils.access_control.folders import has_folder_access
|
||||||
|
|
||||||
|
folder = await Folders.get_folder_by_id(chat.folder_id, db=db)
|
||||||
|
if folder and await has_folder_access(user.id, folder, 'read', db):
|
||||||
|
return chat
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
async def is_chat_owner(self, id: str, user_id: str, db: AsyncSession | None = None) -> bool:
|
async def is_chat_owner(self, id: str, user_id: str, db: AsyncSession | None = None) -> bool:
|
||||||
"""
|
"""
|
||||||
Lightweight ownership check — uses EXISTS subquery instead of loading
|
Lightweight ownership check — uses EXISTS subquery instead of loading
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ from open_webui.models.chats import (
|
|||||||
MessageStats,
|
MessageStats,
|
||||||
chat_search_content_query,
|
chat_search_content_query,
|
||||||
chat_search_terms,
|
chat_search_terms,
|
||||||
is_internal_chat,
|
|
||||||
)
|
)
|
||||||
from open_webui.models.config import Config
|
from open_webui.models.config import Config
|
||||||
from open_webui.models.folders import Folders
|
from open_webui.models.folders import Folders
|
||||||
@@ -36,7 +35,7 @@ from open_webui.models.tags import TagModel, Tags
|
|||||||
from open_webui.socket.main import get_event_emitter
|
from open_webui.socket.main import get_event_emitter
|
||||||
from open_webui.tasks import get_response_streams_by_chat_id, has_active_tasks, stop_item_tasks
|
from open_webui.tasks import get_response_streams_by_chat_id, has_active_tasks, stop_item_tasks
|
||||||
from open_webui.utils.access_control import filter_allowed_access_grants, has_permission
|
from open_webui.utils.access_control import filter_allowed_access_grants, has_permission
|
||||||
from open_webui.utils.access_control.folders import has_folder_access, has_folder_write_access
|
from open_webui.utils.access_control.folders import has_folder_write_access
|
||||||
from open_webui.utils.auth import bearer_security, get_admin_user, get_current_user, get_verified_user
|
from open_webui.utils.auth import bearer_security, get_admin_user, get_current_user, get_verified_user
|
||||||
from open_webui.utils.chat_fork import build_fork_history
|
from open_webui.utils.chat_fork import build_fork_history
|
||||||
from open_webui.utils.context_compaction import compact_chat_branch, get_chat_context_usage
|
from open_webui.utils.context_compaction import compact_chat_branch, get_chat_context_usage
|
||||||
@@ -1329,33 +1328,11 @@ async def get_chat_by_id(
|
|||||||
user=Depends(get_verified_user),
|
user=Depends(get_verified_user),
|
||||||
db: AsyncSession = Depends(get_async_session),
|
db: AsyncSession = Depends(get_async_session),
|
||||||
):
|
):
|
||||||
chat = await Chats.get_chat_by_id_and_user_id(id, user.id, db=db)
|
chat = await Chats.get_chat_by_id_for_user(
|
||||||
|
id,
|
||||||
if not chat and user.role == 'admin':
|
user,
|
||||||
candidate = await Chats.get_chat_by_id(id, db=db)
|
db=db,
|
||||||
if ENABLE_ADMIN_CHAT_ACCESS or (candidate and is_internal_chat(candidate.meta)):
|
)
|
||||||
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:
|
if chat:
|
||||||
data = ChatResponse.model_validate(chat, from_attributes=True).model_dump()
|
data = ChatResponse.model_validate(chat, from_attributes=True).model_dump()
|
||||||
@@ -2177,10 +2154,15 @@ async def update_chat_folder_id_by_id(
|
|||||||
|
|
||||||
@router.get('/{id}/tags', response_model=list[TagModel])
|
@router.get('/{id}/tags', response_model=list[TagModel])
|
||||||
async def get_chat_tags_by_id(id: str, user=Depends(get_verified_user), db: AsyncSession = Depends(get_async_session)):
|
async def get_chat_tags_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)
|
chat = await Chats.get_chat_by_id_for_user(
|
||||||
|
id,
|
||||||
|
user,
|
||||||
|
db=db,
|
||||||
|
)
|
||||||
|
|
||||||
if chat:
|
if chat:
|
||||||
tags = chat.meta.get('tags', [])
|
tags = chat.meta.get('tags', [])
|
||||||
return await Tags.get_tags_by_ids_and_user_id(tags, user.id, db=db)
|
return await Tags.get_tags_by_ids_and_user_id(tags, chat.user_id, db=db)
|
||||||
else:
|
else:
|
||||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND)
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND)
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user