perf(auth): make verify_password non-blocking with asyncio.to_thread

This commit is contained in:
silentoplayz 2026-06-07 16:29:27 -04:00
parent b1d40f3409
commit 627e8aaa42
3 changed files with 24 additions and 14 deletions

View file

@ -148,7 +148,7 @@ class AuthsTable:
credential = await session.get(Auth, resolved.id)
if not credential or not credential.active:
return
if not verify_password(credential.password):
if not await verify_password(credential.password):
return
return resolved

View file

@ -290,9 +290,12 @@ async def update_password(
if WEBUI_AUTH_TRUSTED_EMAIL_HEADER:
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.ACTION_PROHIBITED)
if session_user:
async def _verify(pw):
return await verify_password(form_data.password, pw)
user = await Auths.authenticate_user(
session_user.email,
lambda pw: verify_password(form_data.password, pw),
_verify,
db=db,
)
@ -621,10 +624,13 @@ async def signin(
admin_email = 'admin@localhost'
admin_password = 'admin'
async def _verify_admin(pw):
return await verify_password(admin_password, pw)
if await Users.get_user_by_email(admin_email.lower(), db=db):
user = await Auths.authenticate_user(
admin_email.lower(),
lambda pw: verify_password(admin_password, pw),
_verify_admin,
db=db,
)
else:
@ -641,7 +647,7 @@ async def signin(
user = await Auths.authenticate_user(
admin_email.lower(),
lambda pw: verify_password(admin_password, pw),
_verify_admin,
db=db,
)
else:
@ -660,9 +666,12 @@ async def signin(
# decode safely — ignore incomplete UTF-8 sequences
form_data.password = password_bytes.decode('utf-8', errors='ignore')
async def _verify_signin(pw):
return await verify_password(form_data.password, pw)
user = await Auths.authenticate_user(
form_data.email.lower(),
lambda pw: verify_password(form_data.password, pw),
_verify_signin,
db=db,
)

View file

@ -176,15 +176,16 @@ def validate_password(password: str) -> bool:
return True
def verify_password(plain_password: str, hashed_password: str) -> bool:
"""Verify a password against its hash"""
return (
bcrypt.checkpw(
plain_password.encode('utf-8'),
hashed_password.encode('utf-8'),
)
if hashed_password
else None
async def verify_password(plain_password: str, hashed_password: str) -> bool:
"""Verify a password against its hash in a thread pool (non-blocking)."""
import asyncio
if not hashed_password:
return None
return await asyncio.to_thread(
bcrypt.checkpw,
plain_password.encode('utf-8'),
hashed_password.encode('utf-8'),
)