diff --git a/backend/open_webui/retrieval/web/external.py b/backend/open_webui/retrieval/web/external.py index a5c8003e47..e6b17c6cc7 100644 --- a/backend/open_webui/retrieval/web/external.py +++ b/backend/open_webui/retrieval/web/external.py @@ -3,6 +3,7 @@ from typing import Optional, List import requests from open_webui.retrieval.web.main import SearchResult, get_filtered_results +from open_webui.utils.user_context import inject_user_headers from open_webui.env import SRC_LOG_LEVELS log = logging.getLogger(__name__) @@ -19,10 +20,12 @@ def search_external( try: response = requests.post( external_url, - headers={ - "User-Agent": "Open WebUI (https://github.com/open-webui/open-webui) RAG Bot", - "Authorization": f"Bearer {external_api_key}", - }, + headers=inject_user_headers( + { + "User-Agent": "Open WebUI (https://github.com/open-webui/open-webui) RAG Bot - Web Search", + "Authorization": f"Bearer {external_api_key}", + } + ), json={ "query": query, "count": count, diff --git a/backend/open_webui/utils/user_context.py b/backend/open_webui/utils/user_context.py new file mode 100644 index 0000000000..a0edd0eb67 --- /dev/null +++ b/backend/open_webui/utils/user_context.py @@ -0,0 +1,76 @@ +from contextvars import ContextVar +import os +from fastapi import Request +from open_webui.utils.auth import get_current_user, get_http_authorization_cred + +current_user_context = ContextVar("current_user_context", default=None) + + +def _get_user_from_request() -> dict: + """Try to get user from current request context""" + try: + # This is a creative approach - we'll try to get the request from the call stack + import inspect + + # Look through the call stack for a request object + for frame_info in inspect.stack(): + frame = frame_info.frame + local_vars = frame.f_locals + + # Check if there's a 'request' variable in the current frame + if "request" in local_vars and hasattr(local_vars["request"], "headers"): + request = local_vars["request"] + try: + # Try to get the user using the same method as the audit middleware + auth_header = request.headers.get("Authorization") + if auth_header: + user = get_current_user( + request, + None, + None, + get_http_authorization_cred(auth_header), + ) + if user: + return { + "id": user.id, + "email": user.email, + "name": user.name, + "role": user.role, + } + except Exception: + continue + + return None + except Exception: + return None + + +def inject_user_headers(headers: dict, user: dict = None) -> dict: + """Inject user headers if enabled and context exists""" + headers.update( + { + "X-OpenWebUI-is-enabled": "true", + } + ) + if os.getenv("ENABLE_FORWARD_USER_INFO_HEADERS", "").lower() == "true": + headers.update( + { + "X-OpenWebUI-is-forwarded": "true", + } + ) + # Try multiple ways to get user information + if user is None: + user = current_user_context.get() + if user is None: + user = _get_user_from_request() + + if user: + headers.update( + { + "X-OpenWebUI-User-Id": user.get("id", ""), + "X-OpenWebUI-User-Email": user.get("email", ""), + "X-OpenWebUI-User-Name": user.get("name", ""), + "X-OpenWebUI-User-Role": user.get("role", ""), + } + ) + return headers