fix: avoid double bcrypt on login by using create_session_trusted (#3236)

* fix: avoid double bcrypt on login by adding create_session_trusted

* fix: update test to expect create_session_trusted instead of create_session
This commit is contained in:
Ashvin
2026-06-07 18:40:53 +05:30
committed by GitHub
parent 83b0ab7cd3
commit cbbb41dfb1
3 changed files with 11 additions and 7 deletions
+6
View File
@@ -447,6 +447,12 @@ class AuthManager:
username = username.strip().lower()
if not self.verify_password(username, password):
return None
return self.create_session_trusted(username)
def create_session_trusted(self, username: str) -> str:
"""Issue a session token for an already-verified user.
Call only after verify_password (and TOTP if enabled) have passed."""
username = username.strip().lower()
token = secrets.token_hex(32)
with self._sessions_lock:
self._sessions[token] = {
+2 -4
View File
@@ -131,10 +131,8 @@ def setup_auth_routes(auth_manager: AuthManager) -> APIRouter:
return {"ok": False, "requires_totp": True, "username": username}
if not auth_manager.totp_verify(username, body.totp_code):
raise HTTPException(401, "Invalid 2FA code")
# All checks passed — create session
token = await asyncio.to_thread(auth_manager.create_session, username, body.password)
if not token:
raise HTTPException(401, "Invalid credentials")
# All checks passed — create session (password already verified above)
token = await asyncio.to_thread(auth_manager.create_session_trusted, username)
cookie_kwargs = dict(
key=SESSION_COOKIE,
value=token,
+3 -3
View File
@@ -95,7 +95,7 @@ def test_login_offloads_bcrypt_bearing_calls(monkeypatch):
monkeypatch.setattr("routes.auth_routes.asyncio.to_thread", fake_to_thread)
auth.verify_password.return_value = True
auth.totp_enabled.return_value = False
auth.create_session.return_value = "tok-123"
auth.create_session_trusted.return_value = "tok-123"
login = _login_endpoint(auth)
@@ -107,7 +107,7 @@ def test_login_offloads_bcrypt_bearing_calls(monkeypatch):
assert result["ok"] is True
auth.verify_password.assert_called_once()
auth.create_session.assert_called_once()
auth.create_session_trusted.assert_called_once()
# The whole point: the expensive bcrypt-bearing calls go through
# asyncio.to_thread rather than running inline in the request coroutine.
assert calls == [auth.verify_password, auth.create_session]
assert calls == [auth.verify_password, auth.create_session_trusted]