mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
fix(auth): honour cached CLI session revocations before checking DB availability
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
e57250f5f8
commit
782d1ebb40
2 changed files with 23 additions and 6 deletions
|
|
@ -105,20 +105,24 @@ async def is_cli_session_revoked(
|
|||
interval per replica rather than one per request. That TTL is also the bound on
|
||||
how long a revocation takes to reach a replica that did not serve the revoke.
|
||||
|
||||
A lookup that cannot reach the database follows the proxy-wide
|
||||
A proxy running without a database has no registry, so nothing can have been
|
||||
revoked; those sessions authenticate as they always have. A lookup that cannot
|
||||
reach a configured database follows the proxy-wide
|
||||
``allow_requests_on_db_unavailable`` posture rather than inventing its own: an
|
||||
operator who opted into serving during an outage keeps serving CLI sessions,
|
||||
and one who did not gets the same failure every other DB-backed auth read gives.
|
||||
operator who opted into serving during an outage keeps serving CLI sessions, and
|
||||
one who did not gets the same failure every other DB-backed auth read gives. The
|
||||
cache is consulted first either way, so a revocation this replica already knows
|
||||
about is refused regardless of DB health.
|
||||
"""
|
||||
if prisma_client is None:
|
||||
return False
|
||||
|
||||
session_id: Final = cli_session_id(session_token)
|
||||
cache_key: Final = _revocation_cache_key(session_id)
|
||||
cached: Final = await user_api_key_cache.async_get_cache(key=cache_key)
|
||||
if cached is not None:
|
||||
return bool(cached)
|
||||
|
||||
if prisma_client is None:
|
||||
return False
|
||||
|
||||
try:
|
||||
session: Final = await _get_cli_session(prisma_client=prisma_client, session_id=session_id)
|
||||
except Exception as e: # noqa: BLE001 # handle_db_exception takes any exception and re-raises what it does not recognise
|
||||
|
|
|
|||
|
|
@ -297,12 +297,25 @@ async def test_recorded_session_is_keyed_by_the_hash_not_the_token():
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_no_db_connection_does_not_refuse_the_session():
|
||||
"""A proxy running without a database has no registry, so nothing can have been
|
||||
revoked and the session keeps authenticating."""
|
||||
assert (
|
||||
await is_cli_session_revoked(session_token=SESSION_TOKEN, prisma_client=None, user_api_key_cache=_cache())
|
||||
is False
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_cached_revocation_is_refused_even_without_a_db_client():
|
||||
cache = _cache()
|
||||
await cache.async_set_cache(key=f"cli_session_revoked:{hash_token(SESSION_TOKEN)}", value=True, ttl=60)
|
||||
|
||||
assert (
|
||||
await is_cli_session_revoked(session_token=SESSION_TOKEN, prisma_client=None, user_api_key_cache=cache)
|
||||
is True
|
||||
)
|
||||
|
||||
|
||||
class UnreachableCLISessionTable(FakeCLISessionTable):
|
||||
async def find_unique(self, where):
|
||||
raise EngineConnectionError("Could not connect to the query engine")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue