mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-11 08:38:24 +00:00
fix(key/info): return 400 instead of 500 when no key is provided (#43577)
* fix(key/info): return 400 instead of 500 when no key is provided
When GET /key/info is called without a ?key= query parameter and the
authenticated principal has no virtual key (e.g. an admin-UI session
token whose UserAPIKeyAuth.api_key is None), info_key_fn passed
hashed_key=None to Prisma find_unique(where={"token": None}), which
raised MissingRequiredValueError and surfaced as an unhandled 500.
Add an explicit None/empty guard that raises a clean 400 ProxyException
before the DB lookup, and add a regression test asserting that prisma
find_unique is never called with token=None.
Fixes #43571
Signed-off-by: apex-mochen <2756823972@qq.com>
* test: remove redundant assertion comment
* fix(key/info): remove redundant None check to satisfy basedpyright delta gate
After if not key: raise, key is narrowed to str. The subsequent
if key is not None: guard is always true and triggers basedpyright
reportUnnecessaryComparison, which fails the delta gate.
Collapse to a single hash_token_if_needed(token=key) call.
Signed-off-by: apex-mochen <2756823972@qq.com>
---------
Signed-off-by: apex-mochen <2756823972@qq.com>
Co-authored-by: ryan-crabbe-berri <ryan@berri.ai>
This commit is contained in:
parent
82e43cd55a
commit
c61ec51108
2 changed files with 24 additions and 3 deletions
|
|
@ -5104,9 +5104,14 @@ async def info_key_fn(
|
|||
|
||||
# default to using Auth token if no key is passed in
|
||||
key = key or user_api_key_dict.api_key
|
||||
hashed_key: str | None = key
|
||||
if key is not None:
|
||||
hashed_key = hash_token_if_needed(token=key) # rebind-ok: pre-existing rebinding on a rename-only line
|
||||
if not key:
|
||||
raise ProxyException(
|
||||
message="No key passed in. Pass ?key= or authenticate with a virtual key.",
|
||||
type=ProxyErrorTypes.bad_request_error,
|
||||
param="key",
|
||||
code=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
hashed_key: str | None = hash_token_if_needed(token=key)
|
||||
live_key_info: Final = await _prisma_table(VerificationTokenRepository(prisma_client)).find_unique(
|
||||
where={"token": hashed_key},
|
||||
include={"litellm_budget_table": True},
|
||||
|
|
|
|||
|
|
@ -6980,6 +6980,22 @@ async def test_info_key_fn_unknown_key_still_404s(monkeypatch):
|
|||
assert exc_info.value.code == "404"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_info_key_fn_no_key_returns_400_not_500(monkeypatch):
|
||||
"""#43571: when both ?key= and auth api_key are None, return a clean 400
|
||||
instead of letting Prisma raise MissingRequiredValueError as a 500."""
|
||||
from litellm.proxy.management_endpoints.key_management_endpoints import info_key_fn
|
||||
|
||||
mock_prisma_client = AsyncMock()
|
||||
monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", mock_prisma_client)
|
||||
|
||||
auth = UserAPIKeyAuth(user_role=LitellmUserRoles.PROXY_ADMIN, api_key=None)
|
||||
with pytest.raises(ProxyException) as exc_info:
|
||||
await info_key_fn(key=None, user_api_key_dict=auth)
|
||||
assert exc_info.value.code == "400"
|
||||
mock_prisma_client.db.litellm_verificationtoken.find_unique.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
("blocked", "expires", "expected_status"),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue