mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-07 03:48:44 +08:00
fix: handle missing SDK authorization headers (#15050)
### What problem does this PR solve? Closes #15048. Several SDK session routes in `api/apps/sdk/session.py` called `.split()` directly on `request.headers.get("Authorization")`. When clients omitted the header, the handlers raised `AttributeError` before returning the existing `Authorization is not valid!` response. This PR centralizes SDK Authorization parsing in a small helper and keeps the existing error response for missing, empty, or malformed headers. ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) ### Tests - `ZHIPU_AI_API_KEY=dummy uv run --python 3.13 --group test pytest test/testcases/test_http_api/test_session_management/test_session_sdk_routes_unit.py::test_sdk_session_routes_missing_authorization_unit -q` - `uv run --python 3.13 --group test ruff check api/apps/sdk/session.py test/testcases/test_http_api/test_session_management/test_session_sdk_routes_unit.py` - `python3 -m py_compile api/apps/sdk/session.py test/testcases/test_http_api/test_session_management/test_session_sdk_routes_unit.py` - `git diff --check`
This commit is contained in:
@@ -53,6 +53,13 @@ from api.utils.reference_metadata_utils import (
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_sdk_authorization_token():
|
||||
token = request.headers.get("Authorization", "").split()
|
||||
if len(token) != 2:
|
||||
return None
|
||||
return token[1]
|
||||
|
||||
|
||||
@token_required
|
||||
async def create_agent_session(tenant_id, agent_id):
|
||||
req = await get_request_json()
|
||||
@@ -148,10 +155,9 @@ async def delete_agent_session(tenant_id, agent_id):
|
||||
async def chatbot_completions(dialog_id):
|
||||
req = await get_request_json()
|
||||
|
||||
token = request.headers.get("Authorization").split()
|
||||
if len(token) != 2:
|
||||
token = _get_sdk_authorization_token()
|
||||
if not token:
|
||||
return get_error_data_result(message='Authorization is not valid!')
|
||||
token = token[1]
|
||||
objs = await thread_pool_exec(APIToken.query, beta=token)
|
||||
if not objs:
|
||||
return get_error_data_result(message='Authentication error: API key is invalid!"')
|
||||
@@ -223,10 +229,9 @@ async def chatbot_completions(dialog_id):
|
||||
|
||||
@manager.route("/chatbots/<dialog_id>/info", methods=["GET"]) # noqa: F821
|
||||
async def chatbots_inputs(dialog_id):
|
||||
token = request.headers.get("Authorization").split()
|
||||
if len(token) != 2:
|
||||
token = _get_sdk_authorization_token()
|
||||
if not token:
|
||||
return get_error_data_result(message='Authorization is not valid!')
|
||||
token = token[1]
|
||||
objs = await thread_pool_exec(APIToken.query, beta=token)
|
||||
if not objs:
|
||||
return get_error_data_result(message='Authentication error: API key is invalid!"')
|
||||
@@ -261,10 +266,9 @@ async def chatbots_inputs(dialog_id):
|
||||
async def agent_bot_completions(agent_id):
|
||||
req = await get_request_json()
|
||||
|
||||
token = request.headers.get("Authorization").split()
|
||||
if len(token) != 2:
|
||||
token = _get_sdk_authorization_token()
|
||||
if not token:
|
||||
return get_error_data_result(message='Authorization is not valid!')
|
||||
token = token[1]
|
||||
objs = await thread_pool_exec(APIToken.query, beta=token)
|
||||
if not objs:
|
||||
return get_error_data_result(message='Authentication error: API key is invalid!"')
|
||||
@@ -347,10 +351,9 @@ async def agent_bot_completions(agent_id):
|
||||
|
||||
@manager.route("/agentbots/<agent_id>/inputs", methods=["GET"]) # noqa: F821
|
||||
async def begin_inputs(agent_id):
|
||||
token = request.headers.get("Authorization").split()
|
||||
if len(token) != 2:
|
||||
token = _get_sdk_authorization_token()
|
||||
if not token:
|
||||
return get_error_data_result(message='Authorization is not valid!')
|
||||
token = token[1]
|
||||
objs = await thread_pool_exec(APIToken.query, beta=token)
|
||||
if not objs:
|
||||
return get_error_data_result(message='Authentication error: API key is invalid!"')
|
||||
@@ -368,10 +371,9 @@ async def begin_inputs(agent_id):
|
||||
@manager.route("/searchbots/ask", methods=["POST"]) # noqa: F821
|
||||
@validate_request("question", "kb_ids")
|
||||
async def ask_about_embedded():
|
||||
token = request.headers.get("Authorization").split()
|
||||
if len(token) != 2:
|
||||
token = _get_sdk_authorization_token()
|
||||
if not token:
|
||||
return get_error_data_result(message='Authorization is not valid!')
|
||||
token = token[1]
|
||||
objs = await thread_pool_exec(APIToken.query, beta=token)
|
||||
if not objs:
|
||||
return get_error_data_result(message='Authentication error: API key is invalid!"')
|
||||
@@ -407,10 +409,9 @@ async def ask_about_embedded():
|
||||
@manager.route("/searchbots/retrieval_test", methods=["POST"]) # noqa: F821
|
||||
@validate_request("kb_id", "question")
|
||||
async def retrieval_test_embedded():
|
||||
token = request.headers.get("Authorization").split()
|
||||
if len(token) != 2:
|
||||
token = _get_sdk_authorization_token()
|
||||
if not token:
|
||||
return get_error_data_result(message='Authorization is not valid!')
|
||||
token = token[1]
|
||||
objs = await thread_pool_exec(APIToken.query, beta=token)
|
||||
if not objs:
|
||||
return get_error_data_result(message='Authentication error: API key is invalid!"')
|
||||
@@ -563,10 +564,9 @@ async def retrieval_test_embedded():
|
||||
@manager.route("/searchbots/related_questions", methods=["POST"]) # noqa: F821
|
||||
@validate_request("question")
|
||||
async def related_questions_embedded():
|
||||
token = request.headers.get("Authorization").split()
|
||||
if len(token) != 2:
|
||||
token = _get_sdk_authorization_token()
|
||||
if not token:
|
||||
return get_error_data_result(message='Authorization is not valid!')
|
||||
token = token[1]
|
||||
objs = await thread_pool_exec(APIToken.query, beta=token)
|
||||
if not objs:
|
||||
return get_error_data_result(message='Authentication error: API key is invalid!"')
|
||||
@@ -611,10 +611,9 @@ Related search terms:
|
||||
|
||||
@manager.route("/searchbots/detail", methods=["GET"]) # noqa: F821
|
||||
async def detail_share_embedded():
|
||||
token = request.headers.get("Authorization").split()
|
||||
if len(token) != 2:
|
||||
token = _get_sdk_authorization_token()
|
||||
if not token:
|
||||
return get_error_data_result(message='Authorization is not valid!')
|
||||
token = token[1]
|
||||
objs = await thread_pool_exec(APIToken.query, beta=token)
|
||||
if not objs:
|
||||
return get_error_data_result(message='Authentication error: API key is invalid!"')
|
||||
@@ -643,10 +642,9 @@ async def detail_share_embedded():
|
||||
@manager.route("/searchbots/mindmap", methods=["POST"]) # noqa: F821
|
||||
@validate_request("question", "kb_ids")
|
||||
async def mindmap():
|
||||
token = request.headers.get("Authorization").split()
|
||||
if len(token) != 2:
|
||||
token = _get_sdk_authorization_token()
|
||||
if not token:
|
||||
return get_error_data_result(message='Authorization is not valid!')
|
||||
token = token[1]
|
||||
objs = await thread_pool_exec(APIToken.query, beta=token)
|
||||
if not objs:
|
||||
return get_error_data_result(message='Authentication error: API key is invalid!"')
|
||||
|
||||
@@ -1405,6 +1405,32 @@ def test_delete_agent_session_error_matrix_unit(monkeypatch):
|
||||
assert res["data"]["errors"] == ["Duplicate session ids: ok"]
|
||||
|
||||
|
||||
@pytest.mark.p2
|
||||
@pytest.mark.parametrize(
|
||||
("handler_name", "args"),
|
||||
[
|
||||
("chatbot_completions", ("dialog-1",)),
|
||||
("chatbots_inputs", ("dialog-1",)),
|
||||
("agent_bot_completions", ("agent-1",)),
|
||||
("begin_inputs", ("agent-1",)),
|
||||
("ask_about_embedded", ()),
|
||||
("retrieval_test_embedded", ()),
|
||||
("related_questions_embedded", ()),
|
||||
("detail_share_embedded", ()),
|
||||
("mindmap", ()),
|
||||
],
|
||||
)
|
||||
def test_sdk_session_routes_missing_authorization_unit(monkeypatch, handler_name, args):
|
||||
module = _load_session_module(monkeypatch)
|
||||
monkeypatch.setattr(module, "request", SimpleNamespace(headers={}, args={"search_id": "search-1"}))
|
||||
monkeypatch.setattr(module, "get_request_json", lambda: _AwaitableValue({}))
|
||||
|
||||
handler = inspect.unwrap(getattr(module, handler_name))
|
||||
res = _run(handler(*args))
|
||||
|
||||
assert res["message"] == "Authorization is not valid!"
|
||||
|
||||
|
||||
@pytest.mark.p2
|
||||
def test_chatbot_routes_auth_stream_nonstream_unit(monkeypatch):
|
||||
module = _load_session_module(monkeypatch)
|
||||
|
||||
Reference in New Issue
Block a user