fix(auth): address PR #758 round-7 medium/minor review
- Gate browser session creation on a successful refresh token. When the IdP returns no refresh token, SessionAuthBackend would silently reject every subsequent request and bounce the user back to /oauth/login in a loop. The callback now bails with a 400 + correlation ID + actionable hint about offline_access *before* writing browser_sessions or setting the cookie. Pinned by a new end-to-end unit test. - Evict orphaned browser_sessions rows in SessionAuthBackend when the associated refresh token is gone, instead of letting them accumulate until TTL cleanup. Best-effort; deletion errors stay non-fatal. - Demote identity-bearing logs in the Flow 2 OAuth callback (user_id, scopes, audience, expires_at) from INFO to DEBUG so they don't leak into multi-tenant log aggregation on every provision. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
27fcf05d3a
commit
b875eaf069
@@ -586,7 +586,12 @@ async def test_session_backend_rejects_unknown_session(storage):
|
||||
|
||||
|
||||
async def test_session_backend_rejects_session_without_refresh_token(storage):
|
||||
"""Defense-in-depth: session row exists but user has no refresh token."""
|
||||
"""Defense-in-depth: session row exists but user has no refresh token.
|
||||
|
||||
PR #758 round-7 minor: rejection now also evicts the orphaned
|
||||
``browser_sessions`` row so the table doesn't accumulate dead entries
|
||||
that the auth check will keep rejecting until TTL cleanup.
|
||||
"""
|
||||
await storage.create_browser_session(session_id="sid-B", user_id="bob")
|
||||
# Note: NO refresh token stored for bob
|
||||
|
||||
@@ -594,6 +599,9 @@ async def test_session_backend_rejects_session_without_refresh_token(storage):
|
||||
conn = _build_conn(cookie="sid-B", oauth_context={"storage": storage})
|
||||
assert await backend.authenticate(conn) is None
|
||||
|
||||
# Orphan must be evicted on rejection.
|
||||
assert await storage.get_browser_session_user("sid-B") is None
|
||||
|
||||
|
||||
async def test_session_backend_rejects_when_no_cookie(storage):
|
||||
backend = SessionAuthBackend(oauth_enabled=True)
|
||||
|
||||
Reference in New Issue
Block a user