perf(auth): make password hashing non-blocking and batch CSV user import (#25804)
Co-authored-by: Tim Baek <tim@openwebui.com>
This commit is contained in:
1 parent
18e6a10778
commit
6fdf9b4340
5 files changed
+33
-17
No files matched your search
@@ -379,7 +379,7 @@ async def update_password(
|
||||
validate_password(form_data.new_password)
|
||||
except Exception as e:
|
||||
raise HTTPException(400, detail=str(e))
|
||||
hashed = get_password_hash(form_data.new_password)
|
||||
hashed = await get_password_hash(form_data.new_password)
|
||||
success = await Auths.update_user_password_by_id(user.id, hashed, db=db)
|
||||
if success:
|
||||
await publish_event(
|
||||
@@ -786,7 +786,7 @@ async def signup_handler(
|
||||
# Insert with default role first to avoid TOCTOU race on first signup.
|
||||
# If has_users() is checked before insert, concurrent requests during
|
||||
# first-user registration can all see an empty table and each get admin.
|
||||
hashed = get_password_hash(password)
|
||||
hashed = await get_password_hash(password)
|
||||
|
||||
user = await Auths.insert_new_auth(
|
||||
email=email.lower(),
|
||||
@@ -1040,7 +1040,7 @@ async def add_user(
|
||||
except Exception as e:
|
||||
raise HTTPException(400, detail=str(e))
|
||||
|
||||
hashed = get_password_hash(form_data.password)
|
||||
hashed = await get_password_hash(form_data.password)
|
||||
user = await Auths.insert_new_auth(
|
||||
form_data.email.lower(),
|
||||
hashed,
|
||||
|
||||
@@ -642,7 +642,7 @@ async def update_user_by_id(
|
||||
except Exception as e:
|
||||
raise HTTPException(400, detail=str(e))
|
||||
|
||||
hashed = get_password_hash(form_data.password)
|
||||
hashed = await get_password_hash(form_data.password)
|
||||
await Auths.update_user_password_by_id(user_id, hashed, db=db)
|
||||
|
||||
# Build update dict from only the provided fields
|
||||
|
||||
@@ -158,9 +158,11 @@ def get_license_data(app, key):
|
||||
bearer_security = HTTPBearer(auto_error=False)
|
||||
|
||||
|
||||
def get_password_hash(password: str) -> str:
|
||||
"""Hash a password using bcrypt"""
|
||||
return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
|
||||
async def get_password_hash(password: str) -> str:
|
||||
"""Hash a password using bcrypt in a thread pool (non-blocking)."""
|
||||
import asyncio
|
||||
|
||||
return (await asyncio.to_thread(bcrypt.hashpw, password.encode('utf-8'), bcrypt.gensalt())).decode('utf-8')
|
||||
|
||||
|
||||
def validate_password(password: str) -> bool:
|
||||
@@ -486,7 +488,7 @@ async def create_admin_user(email: str, password: str, name: str = 'Admin'):
|
||||
|
||||
log.info(f'Creating admin account from environment variables: {email}')
|
||||
try:
|
||||
hashed = get_password_hash(password)
|
||||
hashed = await get_password_hash(password)
|
||||
user = await Auths.insert_new_auth(
|
||||
email=email.lower(),
|
||||
password=hashed,
|
||||
|
||||
@@ -1871,7 +1871,7 @@ class OAuthManager:
|
||||
|
||||
user = await Auths.insert_new_auth(
|
||||
email=email,
|
||||
password=get_password_hash(str(uuid.uuid4())), # Random password, not used
|
||||
password=await get_password_hash(str(uuid.uuid4())), # Random password, not used
|
||||
name=name,
|
||||
profile_image_url=picture_url,
|
||||
role=await self.get_user_role(None, user_data),
|
||||
|
||||
Reference in new issue
Block a user